From 9460fa4544fad50881cb8d18bac234698568e523 Mon Sep 17 00:00:00 2001 From: Daniel Hodder Date: Wed, 28 May 2014 16:53:55 +1200 Subject: [PATCH 1/2] Changed the default output appender to be a PrintStream Previously the default output was an OutputStreamWriter. Since this is buffered it resulted in test output being buffered making watching the test output in real time impossible. Now we use a PrintStream which is the type that the System.out stream is anyway, while still retaining the fix intoduced to make the Appender's close() method a no-op. --- .../java/cucumber/runtime/formatter/FormatterFactory.java | 6 +++--- .../cucumber/runtime/formatter/FormatterFactoryTest.java | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/cucumber/runtime/formatter/FormatterFactory.java b/core/src/main/java/cucumber/runtime/formatter/FormatterFactory.java index 650a283905..561617f7d3 100644 --- a/core/src/main/java/cucumber/runtime/formatter/FormatterFactory.java +++ b/core/src/main/java/cucumber/runtime/formatter/FormatterFactory.java @@ -8,7 +8,7 @@ import java.io.File; import java.io.IOException; -import java.io.OutputStreamWriter; +import java.io.PrintStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.net.URI; @@ -51,9 +51,9 @@ public class FormatterFactory { put("rerun", RerunFormatter.class); }}; private static final Pattern FORMATTER_WITH_FILE_PATTERN = Pattern.compile("([^:]+):(.*)"); - private Appendable defaultOut = new OutputStreamWriter(System.out) { + private Appendable defaultOut = new PrintStream(System.out) { @Override - public void close() throws IOException { + public void close() { // We have no intention to close System.out } }; diff --git a/core/src/test/java/cucumber/runtime/formatter/FormatterFactoryTest.java b/core/src/test/java/cucumber/runtime/formatter/FormatterFactoryTest.java index b1ec0e6dbd..8b69b7ef86 100644 --- a/core/src/test/java/cucumber/runtime/formatter/FormatterFactoryTest.java +++ b/core/src/test/java/cucumber/runtime/formatter/FormatterFactoryTest.java @@ -4,13 +4,14 @@ import cucumber.runtime.Utils; import cucumber.runtime.io.UTF8OutputStreamWriter; import gherkin.formatter.Formatter; + import org.junit.Test; import java.io.File; import java.io.IOException; -import java.io.OutputStreamWriter; import java.net.URI; import java.net.URISyntaxException; +import java.io.PrintStream; import java.net.URL; import static org.hamcrest.CoreMatchers.instanceOf; @@ -77,7 +78,7 @@ public void instantiates_usage_formatter_with_file_arg() throws IOException { @Test public void instantiates_single_custom_appendable_formatter_with_stdout() { WantsAppendable formatter = (WantsAppendable) fc.create("cucumber.runtime.formatter.FormatterFactoryTest$WantsAppendable"); - assertThat(formatter.out, is(instanceOf(OutputStreamWriter.class))); + assertThat(formatter.out, is(instanceOf(PrintStream.class))); try { fc.create("cucumber.runtime.formatter.FormatterFactoryTest$WantsAppendable"); fail(); @@ -89,7 +90,7 @@ public void instantiates_single_custom_appendable_formatter_with_stdout() { @Test public void instantiates_custom_appendable_formatter_with_stdout_and_file() throws IOException { WantsAppendable formatter = (WantsAppendable) fc.create("cucumber.runtime.formatter.FormatterFactoryTest$WantsAppendable"); - assertThat(formatter.out, is(instanceOf(OutputStreamWriter.class))); + assertThat(formatter.out, is(instanceOf(PrintStream.class))); WantsAppendable formatter2 = (WantsAppendable) fc.create("cucumber.runtime.formatter.FormatterFactoryTest$WantsAppendable:" + TempDir.createTempFile().getAbsolutePath()); assertEquals(UTF8OutputStreamWriter.class, formatter2.out.getClass()); From 68faa4b045ae0d674667f229009aeba3084bf694 Mon Sep 17 00:00:00 2001 From: Daniel Hodder Date: Thu, 29 May 2014 10:07:42 +1200 Subject: [PATCH 2/2] Added test that ensures that output to System.out is not buffered --- .../formatter/FormatterFactoryTest.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/core/src/test/java/cucumber/runtime/formatter/FormatterFactoryTest.java b/core/src/test/java/cucumber/runtime/formatter/FormatterFactoryTest.java index 8b69b7ef86..077e77a476 100644 --- a/core/src/test/java/cucumber/runtime/formatter/FormatterFactoryTest.java +++ b/core/src/test/java/cucumber/runtime/formatter/FormatterFactoryTest.java @@ -4,17 +4,21 @@ import cucumber.runtime.Utils; import cucumber.runtime.io.UTF8OutputStreamWriter; import gherkin.formatter.Formatter; +import gherkin.formatter.model.Result; import org.junit.Test; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.io.OutputStream; import java.io.PrintStream; import java.net.URL; import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; @@ -74,6 +78,27 @@ public void instantiates_usage_formatter_with_file_arg() throws IOException { Formatter formatter = fc.create("usage:" + TempDir.createTempFile().getAbsolutePath()); assertEquals(UsageFormatter.class, formatter.getClass()); } + + @Test + public void formatter_does_not_buffer_its_output() throws IOException { + PrintStream previousSystemOut = System.out; + OutputStream mockSystemOut = new ByteArrayOutputStream(); + + try { + System.setOut(new PrintStream(mockSystemOut)); + + // Need to create a new formatter factory here since we need it to pick up the new value of System.out + fc = new FormatterFactory(); + + ProgressFormatter formatter = (ProgressFormatter) fc.create("progress"); + + formatter.result(new Result("passed", null, null)); + + assertThat(mockSystemOut.toString(), is(not(""))); + } finally { + System.setOut(previousSystemOut); + } + } @Test public void instantiates_single_custom_appendable_formatter_with_stdout() {