package cucumber.runtime.formatter; import cucumber.runtime.CucumberException; import cucumber.runtime.Utils; import cucumber.runtime.io.UTF8OutputStreamWriter; import gherkin.formatter.model.Result; import org.junit.Test; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; public class PluginFactoryTest { private PluginFactory fc = new PluginFactory(); @Test public void instantiates_null_plugin() { Object plugin = fc.create("null"); assertEquals(NullFormatter.class, plugin.getClass()); } @Test public void instantiates_junit_plugin_with_file_arg() throws IOException { Object plugin = fc.create("junit:" + File.createTempFile("cucumber", "xml")); assertEquals(JUnitFormatter.class, plugin.getClass()); } @Test public void instantiates_html_plugin_with_dir_arg() throws IOException { Object plugin = fc.create("html:" + TempDir.createTempDirectory().getAbsolutePath()); assertEquals(HTMLFormatter.class, plugin.getClass()); } @Test public void fails_to_instantiate_html_plugin_without_dir_arg() throws IOException { try { fc.create("html"); fail(); } catch (CucumberException e) { assertEquals("You must supply an output argument to html. Like so: html:output", e.getMessage()); } } @Test public void instantiates_pretty_plugin_with_file_arg() throws IOException { Object plugin = fc.create("pretty:" + Utils.toURL(TempDir.createTempFile().getAbsolutePath())); assertEquals(CucumberPrettyFormatter.class, plugin.getClass()); } @Test public void instantiates_pretty_plugin_without_file_arg() { Object plugin = fc.create("pretty"); assertEquals(CucumberPrettyFormatter.class, plugin.getClass()); } @Test public void instantiates_usage_plugin_without_file_arg() { Object plugin = fc.create("usage"); assertEquals(UsageFormatter.class, plugin.getClass()); } @Test public void instantiates_usage_plugin_with_file_arg() throws IOException { Object plugin = fc.create("usage:" + TempDir.createTempFile().getAbsolutePath()); assertEquals(UsageFormatter.class, plugin.getClass()); } @Test public void plugin_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 plugin factory here since we need it to pick up the new value of System.out fc = new PluginFactory(); ProgressFormatter plugin = (ProgressFormatter) fc.create("progress"); plugin.result(new Result("passed", null, null)); assertThat(mockSystemOut.toString(), is(not(""))); } finally { System.setOut(previousSystemOut); } } @Test public void instantiates_single_custom_appendable_plugin_with_stdout() { WantsAppendable plugin = (WantsAppendable) fc.create("cucumber.runtime.formatter.PluginFactoryTest$WantsAppendable"); assertThat(plugin.out, is(instanceOf(PrintStream.class))); try { fc.create("cucumber.runtime.formatter.PluginFactoryTest$WantsAppendable"); fail(); } catch (CucumberException expected) { assertEquals("Only one formatter can use STDOUT, now both cucumber.runtime.formatter.PluginFactoryTest$WantsAppendable " + "and cucumber.runtime.formatter.PluginFactoryTest$WantsAppendable use it. " + "If you use more than one formatter you must specify output path with PLUGIN:PATH_OR_URL", expected.getMessage()); } } @Test public void instantiates_custom_appendable_plugin_with_stdout_and_file() throws IOException { WantsAppendable plugin = (WantsAppendable) fc.create("cucumber.runtime.formatter.PluginFactoryTest$WantsAppendable"); assertThat(plugin.out, is(instanceOf(PrintStream.class))); WantsAppendable plugin2 = (WantsAppendable) fc.create("cucumber.runtime.formatter.PluginFactoryTest$WantsAppendable:" + TempDir.createTempFile().getAbsolutePath()); assertEquals(UTF8OutputStreamWriter.class, plugin2.out.getClass()); } @Test public void instantiates_custom_url_plugin() throws IOException { WantsUrl plugin = (WantsUrl) fc.create("cucumber.runtime.formatter.PluginFactoryTest$WantsUrl:halp"); assertEquals(new URL("file:halp/"), plugin.out); } @Test public void instantiates_custom_url_plugin_with_http() throws IOException { WantsUrl plugin = (WantsUrl) fc.create("cucumber.runtime.formatter.PluginFactoryTest$WantsUrl:http://halp/"); assertEquals(new URL("http://halp/"), plugin.out); } @Test public void instantiates_custom_uri_plugin_with_ws() throws IOException, URISyntaxException { WantsUri plugin = (WantsUri) fc.create("cucumber.runtime.formatter.PluginFactoryTest$WantsUri:ws://halp/"); assertEquals(new URI("ws://halp/"), plugin.out); } @Test public void instantiates_custom_file_plugin() throws IOException { WantsFile plugin = (WantsFile) fc.create("cucumber.runtime.formatter.PluginFactoryTest$WantsFile:halp.txt"); assertEquals(new File("halp.txt"), plugin.out); } public static class WantsAppendable extends StubFormatter { public final Appendable out; public WantsAppendable(Appendable out) { this.out = out; } } public static class WantsUrl extends StubFormatter { public final URL out; public WantsUrl(URL out) { this.out = out; } } public static class WantsUri extends StubFormatter { public final URI out; public WantsUri(URI out) { this.out = out; } } public static class WantsFile extends StubFormatter { public final File out; public WantsFile(File out) { this.out = out; } } }