Skip to content

Commit

Permalink
Add methods for tapping err and out simultaneously
Browse files Browse the repository at this point in the history
The output of command-line applications is usually the output to the
standard output stream and the error output stream intermixed. The new
methods allow capturing the intermixed output.

    @test
    void application_writes_text_to_System_err_and_out(
    ) throws Exception {
      String text = tapSystemErrAndOut(() -> {
        System.err.print("text from err");
        System.out.print("text from out");
      });
      assertEquals("text from errtext from out", text);
    }

    @test
    void application_writes_mutliple_lines_to_System_err_and_out(
    ) throws Exception {
      String text = tapSystemErrAndOutNormalized(() -> {
        System.err.println("text from err");
        System.out.println("text from out");
      });
      assertEquals("text from err\ntext from out\n", text);
    }
  • Loading branch information
stefanbirkner committed Aug 14, 2021
1 parent 8903a1d commit a203454
Show file tree
Hide file tree
Showing 5 changed files with 253 additions and 6 deletions.
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ System Lambda is available from
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-lambda</artifactId>
<version>1.1.1</version>
<version>1.2.0</version>
</dependency>
```

Expand Down Expand Up @@ -113,8 +113,9 @@ void execute_code_that_manipulates_system_properties(

Command-line applications usually write to the console. If you write such
applications you need to test the output of these applications. The methods
`tapSystemErr`, `tapSystemErrNormalized`, `tapSystemOut` and
`tapSystemOutNormalized` allow you to tap the text that is written to
`tapSystemErr`, `tapSystemErrNormalized`, `tapSystemOut`,
`tapSystemOutNormalized`, `tapSystemErrAndOut` and
`tapSystemErrAndOutNormalized` allow you to tap the text that is written to
`System.err`/`System.out`. The methods with the suffix `Normalized` normalize
line breaks to `\n` so that you can run tests with the same assertions on
different operating systems.
Expand Down Expand Up @@ -157,6 +158,26 @@ void application_writes_mutliple_lines_to_System_out(
});
assertEquals("first line\nsecond line\n", text);
}

@Test
void application_writes_text_to_System_err_and_out(
) throws Exception {
String text = tapSystemErrAndOut(() -> {
System.err.print("text from err");
System.out.print("text from out");
});
assertEquals("text from errtext from out", text);
}

@Test
void application_writes_mutliple_lines_to_System_err_and_out(
) throws Exception {
String text = tapSystemErrAndOutNormalized(() -> {
System.err.println("text from err");
System.out.println("text from out");
});
assertEquals("text from err\ntext from out\n", text);
}
```

You can assert that nothing is written to `System.err`/`System.out` by wrapping
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</parent>

<artifactId>system-lambda</artifactId>
<version>1.2.0-SNAPSHOT</version>
<version>1.2.0</version>
<packaging>jar</packaging>

<name>System Lambda</name>
Expand Down
109 changes: 107 additions & 2 deletions src/main/java/com/github/stefanbirkner/systemlambda/SystemLambda.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,11 @@
* applications you need to test the output of these applications. The methods
* {@link #tapSystemErr(Statement) tapSystemErr},
* {@link #tapSystemErrNormalized(Statement) tapSystemErrNormalized},
* {@link #tapSystemOut(Statement) tapSystemOut} and
* {@link #tapSystemOutNormalized(Statement) tapSystemOutNormalized} allow you
* {@link #tapSystemOut(Statement) tapSystemOut},
* {@link #tapSystemOutNormalized(Statement) tapSystemOutNormalized},
* {@link #tapSystemErrAndOut(Statement) tapSystemErrAndOut} and
* {@link #tapSystemErrAndOutNormalized(Statement) tapSystemErrAndOutNormalized}
* allow you
* to tap the text that is written to {@code System.err}/{@code System.out}. The
* methods with the suffix {@code Normalized} normalize line breaks to
* {@code \n} so that you can run tests with the same assertions on different
Expand Down Expand Up @@ -131,6 +134,26 @@
* System.out.println("second line");
* });
* assertEquals(text, "first line\nsecond line\n");
* }
*
* &#064;Test
* void application_writes_text_to_System_err_and_out(
* ) throws Exception {
* String text = tapSystemErrAndOut((){@literal ->} {
* System.err.print("text from err");
* System.out.print("text from out");
* });
* assertEquals("text from errtext from out", text);
* }
*
* &#064;Test
* void application_writes_mutliple_lines_to_System_err_and_out(
* ) throws Exception {
* String text = tapSystemErrAndOutNormalized((){@literal ->} {
* System.err.println("text from err");
* System.out.println("text from out");
* });
* assertEquals("text from err\ntext from out\n", text);
* }</pre>
*
* <p>You can assert that nothing is written to
Expand Down Expand Up @@ -509,6 +532,8 @@ public static void restoreSystemProperties(
* @return text that is written to {@code System.err} by the statement.
* @throws Exception any exception thrown by the statement.
* @see #tapSystemOut(Statement)
* @see #tapSystemErrAndOut(Statement)
* @see #tapSystemErrAndOutNormalized(Statement)
* @since 1.0.0
*/
public static String tapSystemErr(
Expand Down Expand Up @@ -541,6 +566,8 @@ public static String tapSystemErr(
* @return text that is written to {@code System.err} by the statement.
* @throws Exception any exception thrown by the statement.
* @see #tapSystemOut(Statement)
* @see #tapSystemErrAndOut(Statement)
* @see #tapSystemErrAndOutNormalized(Statement)
* @since 1.0.0
*/
public static String tapSystemErrNormalized(
Expand All @@ -550,6 +577,80 @@ public static String tapSystemErrNormalized(
.replace(lineSeparator(), "\n");
}

/**
* Executes the statement and returns the text that was written to
* {@code System.err} and {@code System.out} by the statement.
* <pre>
* &#064;Test
* void application_writes_text_to_System_err_and_out(
* ) throws Exception {
* String text = tapSystemErrAndOut((){@literal ->} {
* System.err.print("text from err");
* System.out.print("text from out");
* });
* assertEquals("text from errtext from out", text);
* }
* </pre>
*
* @param statement an arbitrary piece of code.
* @return text that is written to {@code System.err} and {@code System.out}
* by the statement.
* @throws Exception any exception thrown by the statement.
* @see #tapSystemErrAndOutNormalized(Statement)
* @see #tapSystemErr(Statement)
* @see #tapSystemErrNormalized(Statement)
* @see #tapSystemOut(Statement)
* @see #tapSystemOutNormalized(Statement)
* @since 1.2.0
*/
public static String tapSystemErrAndOut(
Statement statement
) throws Exception {
TapStream tapStream = new TapStream();
executeWithSystemErrReplacement(
tapStream,
() -> executeWithSystemOutReplacement(
tapStream,
statement
)
);
return tapStream.textThatWasWritten();
}

/**
* Executes the statement and returns the text that was written to
* {@code System.err} and {@code System.out} by the statement. New line
* characters are replaced with a single {@code \n}.
* <pre>
* &#064;Test
* void application_writes_mutliple_lines_to_System_err_and_out(
* ) throws Exception {
* String text = tapSystemErrAndOutNormalized((){@literal ->} {
* System.err.println("text from err");
* System.out.println("text from out");
* });
* assertEquals("text from err\ntext from out\n", text);
* }
* </pre>
*
* @param statement an arbitrary piece of code.
* @return text that is written to {@code System.err} and {@code System.out}
* by the statement.
* @throws Exception any exception thrown by the statement.
* @see #tapSystemErrAndOut(Statement)
* @see #tapSystemErr(Statement)
* @see #tapSystemErrNormalized(Statement)
* @see #tapSystemOut(Statement)
* @see #tapSystemOutNormalized(Statement)
* @since 1.2.0
*/
public static String tapSystemErrAndOutNormalized(
Statement statement
) throws Exception {
return tapSystemErrAndOut(statement)
.replace(lineSeparator(), "\n");
}

/**
* Executes the statement and returns the text that was written to
* {@code System.out} by the statement.
Expand All @@ -568,6 +669,8 @@ public static String tapSystemErrNormalized(
* @return text that is written to {@code System.out} by the statement.
* @throws Exception any exception thrown by the statement.
* @see #tapSystemErr(Statement)
* @see #tapSystemErrAndOut(Statement)
* @see #tapSystemErrAndOutNormalized(Statement)
* @since 1.0.0
*/
public static String tapSystemOut(
Expand Down Expand Up @@ -600,6 +703,8 @@ public static String tapSystemOut(
* @return text that is written to {@code System.out} by the statement.
* @throws Exception any exception thrown by the statement.
* @see #tapSystemErr(Statement)
* @see #tapSystemErrAndOut(Statement)
* @see #tapSystemErrAndOutNormalized(Statement)
* @since 1.0.0
*/
public static String tapSystemOutNormalized(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.github.stefanbirkner.systemlambda;

import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static com.github.stefanbirkner.systemlambda.SystemLambda.*;
import static java.lang.System.err;
import static java.lang.System.out;
import static org.assertj.core.api.Assertions.assertThat;

@DisplayNameGeneration(ReplaceUnderscores.class)
class TapSystemErrAndOutNormalizedTest {

@Test
void taps_text_that_is_written_to_System_err_and_out_by_statement_has_only_slash_n_for_new_line(
) throws Exception {
String textWrittenToSystemErr = tapSystemErrAndOutNormalized(
() -> {
err.println("line 1");
out.println("line 2");
err.println("line 3");
out.println("line 4");
}
);

assertThat(textWrittenToSystemErr)
.isEqualTo("line 1\nline 2\nline 3\nline 4\n");
}

@Test
void tapped_text_is_empty_when_statement_does_not_write_to_System_err_nor_out(
) throws Exception {
String textWrittenToSystemErr = tapSystemErrAndOutNormalized(
() -> {}
);

assertThat(textWrittenToSystemErr)
.isEqualTo("");
}

@Nested
class System_err_is_same_as_before
extends RestoreSystemErrChecks
{
System_err_is_same_as_before() {
super(SystemLambda::tapSystemErrAndOutNormalized);
}
}

@Nested
class System_out_is_same_as_before
extends RestoreSystemOutChecks
{
System_out_is_same_as_before() {
super(SystemLambda::tapSystemErrAndOutNormalized);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.github.stefanbirkner.systemlambda;

import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemErr;
import static com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemErrAndOut;
import static java.lang.System.err;
import static java.lang.System.out;
import static org.assertj.core.api.Assertions.assertThat;

@DisplayNameGeneration(ReplaceUnderscores.class)
class TapSystemErrAndOutTest {

@Test
void taps_text_that_is_written_to_System_err_and_out_by_statement(
) throws Exception {
String textWrittenToSystemErrAndOut = tapSystemErrAndOut(
() -> {
err.print("word1 ");
out.print("word2 ");
err.print("word3 ");
out.print("word4 ");
}
);

assertThat(textWrittenToSystemErrAndOut)
.isEqualTo("word1 word2 word3 word4 ");
}

@Test
void tapped_text_is_empty_when_statement_does_not_write_to_System_err_nor_out(
) throws Exception {
String textWrittenToSystemErrAndOut = tapSystemErrAndOut(
() -> {}
);

assertThat(textWrittenToSystemErrAndOut)
.isEqualTo("");
}

@Nested
class System_err_is_same_as_before
extends RestoreSystemErrChecks
{
System_err_is_same_as_before() {
super(SystemLambda::tapSystemErrAndOut);
}
}

@Nested
class System_out_is_same_as_before
extends RestoreSystemOutChecks
{
System_out_is_same_as_before() {
super(SystemLambda::tapSystemErrAndOut);
}
}
}

0 comments on commit a203454

Please sign in to comment.