From c8feb10d8e6c86c3a22532a3ed594cb87fed6594 Mon Sep 17 00:00:00 2001 From: brasmusson Date: Tue, 11 Jun 2013 21:35:54 +0200 Subject: [PATCH] Minimize the number of constructors in the Runtime class To minimize the number of constructors in the Runtime class, and to handle that by default a UndefinedStepTracker is created and then injected both into the Runtime and the RuntimeGlue, create a factory method as the main entry. Expose additional conveniece factory methods for testing in the core module in RuntimeTest. --- core/src/main/java/cucumber/api/cli/Main.java | 2 +- .../main/java/cucumber/runtime/Runtime.java | 18 +++++------------- .../java/cucumber/runtime/BackgroundTest.java | 2 +- .../java/cucumber/runtime/HookOrderTest.java | 2 +- .../test/java/cucumber/runtime/HookTest.java | 2 +- .../java/cucumber/runtime/RuntimeTest.java | 19 ++++++++++++++++--- .../formatter/JSONPrettyFormatterTest.java | 4 ++-- .../runtime/formatter/JUnitFormatterTest.java | 4 ++-- .../runtime/java/JavaStepDefinitionTest.java | 15 ++++++++++++++- .../java/cucumber/api/junit/Cucumber.java | 2 +- 10 files changed, 44 insertions(+), 26 deletions(-) diff --git a/core/src/main/java/cucumber/api/cli/Main.java b/core/src/main/java/cucumber/api/cli/Main.java index 2621774a16..25be6d8080 100644 --- a/core/src/main/java/cucumber/api/cli/Main.java +++ b/core/src/main/java/cucumber/api/cli/Main.java @@ -15,7 +15,7 @@ public static void main(String[] argv) throws Throwable { public static void run(String[] argv, ClassLoader classLoader) throws IOException { RuntimeOptions runtimeOptions = new RuntimeOptions(System.getProperties(), argv); - Runtime runtime = new Runtime(new MultiLoader(classLoader), classLoader, runtimeOptions); + Runtime runtime = Runtime.createRuntime(new MultiLoader(classLoader), classLoader, runtimeOptions); runtime.writeStepdefsJson(); runtime.run(); System.exit(runtime.exitStatus()); diff --git a/core/src/main/java/cucumber/runtime/Runtime.java b/core/src/main/java/cucumber/runtime/Runtime.java index cf9489d875..7c56e67f34 100644 --- a/core/src/main/java/cucumber/runtime/Runtime.java +++ b/core/src/main/java/cucumber/runtime/Runtime.java @@ -59,21 +59,13 @@ public class Runtime implements UnreportedStepExecutor { private boolean skipNextStep = false; private ScenarioImpl scenarioResult = null; - public Runtime(ResourceLoader resourceLoader, ClassLoader classLoader, RuntimeOptions runtimeOptions) { - this(resourceLoader, classLoader, loadBackends(resourceLoader, classLoader), runtimeOptions); + public static Runtime createRuntime(ResourceLoader resourceLoader, ClassLoader classLoader, RuntimeOptions runtimeOptions) { + UndefinedStepsTracker undefinedStepsTracker = new UndefinedStepsTracker(); + return new Runtime(resourceLoader, classLoader, loadBackends(resourceLoader, classLoader), runtimeOptions, + undefinedStepsTracker, new RuntimeGlue(undefinedStepsTracker, new LocalizedXStreams(classLoader))); } - public Runtime(ResourceLoader resourceLoader, ClassLoader classLoader, Collection backends, RuntimeOptions runtimeOptions) { - this(resourceLoader, classLoader, backends, runtimeOptions, new UndefinedStepsTracker()); - } - - private Runtime(ResourceLoader resourceLoader, ClassLoader classLoader, Collection backends, - RuntimeOptions runtimeOptions, UndefinedStepsTracker undefinedStepsTracker) { - this(resourceLoader, classLoader, backends, runtimeOptions, undefinedStepsTracker, - new RuntimeGlue(undefinedStepsTracker, new LocalizedXStreams(classLoader))); - } - - Runtime(ResourceLoader resourceLoader, ClassLoader classLoader, Collection backends, + public Runtime(ResourceLoader resourceLoader, ClassLoader classLoader, Collection backends, RuntimeOptions runtimeOptions, UndefinedStepsTracker undefinedStepsTracker, RuntimeGlue glue) { if (backends.isEmpty()) { throw new CucumberException("No backends were found. Please make sure you have a backend module on your CLASSPATH."); diff --git a/core/src/test/java/cucumber/runtime/BackgroundTest.java b/core/src/test/java/cucumber/runtime/BackgroundTest.java index eb558aa829..30cbd466a8 100644 --- a/core/src/test/java/cucumber/runtime/BackgroundTest.java +++ b/core/src/test/java/cucumber/runtime/BackgroundTest.java @@ -18,7 +18,7 @@ public class BackgroundTest { public void should_run_background() throws IOException { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties()); - Runtime runtime = new Runtime(new ClasspathResourceLoader(classLoader), classLoader, asList(mock(Backend.class)), runtimeOptions); + Runtime runtime = RuntimeTest.createRuntime(new ClasspathResourceLoader(classLoader), classLoader, asList(mock(Backend.class)), runtimeOptions); CucumberFeature feature = feature("test.feature", "" + "Feature:\n" + " Background:\n" + diff --git a/core/src/test/java/cucumber/runtime/HookOrderTest.java b/core/src/test/java/cucumber/runtime/HookOrderTest.java index b8025382a9..a3de0cbdbe 100644 --- a/core/src/test/java/cucumber/runtime/HookOrderTest.java +++ b/core/src/test/java/cucumber/runtime/HookOrderTest.java @@ -31,7 +31,7 @@ public class HookOrderTest { public void buildMockWorld() { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties()); - runtime = new Runtime(mock(ResourceLoader.class), classLoader, asList(mock(Backend.class)), runtimeOptions); + runtime = RuntimeTest.createRuntime(mock(ResourceLoader.class), classLoader, asList(mock(Backend.class)), runtimeOptions); runtime.buildBackendWorlds(null, Collections.emptySet()); glue = runtime.getGlue(); } diff --git a/core/src/test/java/cucumber/runtime/HookTest.java b/core/src/test/java/cucumber/runtime/HookTest.java index 9f9f6ca7ac..74bac6b42d 100644 --- a/core/src/test/java/cucumber/runtime/HookTest.java +++ b/core/src/test/java/cucumber/runtime/HookTest.java @@ -45,7 +45,7 @@ public void after_hooks_execute_before_objects_are_disposed() throws Throwable { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties()); - Runtime runtime = new Runtime(new ClasspathResourceLoader(classLoader), classLoader, asList(backend), runtimeOptions); + Runtime runtime = RuntimeTest.createRuntime(new ClasspathResourceLoader(classLoader), classLoader, asList(backend), runtimeOptions); runtime.getGlue().addAfterHook(hook); scenario.run(mock(Formatter.class), mock(Reporter.class), runtime); diff --git a/core/src/test/java/cucumber/runtime/RuntimeTest.java b/core/src/test/java/cucumber/runtime/RuntimeTest.java index cdb563d387..953b8aa98e 100644 --- a/core/src/test/java/cucumber/runtime/RuntimeTest.java +++ b/core/src/test/java/cucumber/runtime/RuntimeTest.java @@ -5,6 +5,7 @@ import cucumber.runtime.io.ClasspathResourceLoader; import cucumber.runtime.io.ResourceLoader; import cucumber.runtime.model.CucumberFeature; +import cucumber.runtime.xstream.LocalizedXStreams; import gherkin.I18n; import gherkin.formatter.JSONFormatter; import gherkin.formatter.Reporter; @@ -54,7 +55,7 @@ public void runs_feature_with_json_formatter() throws Exception { List backends = asList(mock(Backend.class)); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties()); - Runtime runtime = new Runtime(new ClasspathResourceLoader(classLoader), classLoader, backends, runtimeOptions); + Runtime runtime = createRuntime(new ClasspathResourceLoader(classLoader), classLoader, backends, runtimeOptions); feature.run(jsonFormatter, jsonFormatter, runtime); jsonFormatter.done(); String expected = "" + @@ -182,7 +183,7 @@ public void strict_with_errors() { public void should_throw_cucumer_exception_if_no_backends_are_found() throws Exception { try { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - new Runtime(new ClasspathResourceLoader(classLoader), classLoader, Collections.emptyList(), + createRuntime(new ClasspathResourceLoader(classLoader), classLoader, Collections.emptyList(), new RuntimeOptions(new Properties())); fail("A CucumberException should have been thrown"); } catch (CucumberException e) { @@ -363,7 +364,19 @@ private Runtime createRuntime(String... runtimeArgs) { Backend backend = mock(Backend.class); Collection backends = Arrays.asList(backend); - return new Runtime(resourceLoader, classLoader, backends, runtimeOptions); + return createRuntime(resourceLoader, classLoader, backends, runtimeOptions); + } + + public static Runtime createRuntime(ResourceLoader resourceLoader, ClassLoader classLoader, + Collection backends, RuntimeOptions runtimeOptions) { + UndefinedStepsTracker undefinedStepsTracker = new UndefinedStepsTracker(); + return new Runtime(resourceLoader, classLoader, backends, runtimeOptions, undefinedStepsTracker, + new RuntimeGlue(undefinedStepsTracker, new LocalizedXStreams(classLoader))); + } + + public static Runtime createRuntime(ResourceLoader resourceLoader, ClassLoader classLoader, + Collection backends, RuntimeOptions runtimeOptions, RuntimeGlue glue) { + return new Runtime(resourceLoader, classLoader, backends, runtimeOptions, new UndefinedStepsTracker(), glue); } private Runtime createRuntimeWithMockedGlue(StepDefinitionMatch match, String... runtimeArgs) { diff --git a/core/src/test/java/cucumber/runtime/formatter/JSONPrettyFormatterTest.java b/core/src/test/java/cucumber/runtime/formatter/JSONPrettyFormatterTest.java index 8d559e39e1..0660e5d328 100644 --- a/core/src/test/java/cucumber/runtime/formatter/JSONPrettyFormatterTest.java +++ b/core/src/test/java/cucumber/runtime/formatter/JSONPrettyFormatterTest.java @@ -1,8 +1,8 @@ package cucumber.runtime.formatter; import cucumber.runtime.Backend; -import cucumber.runtime.Runtime; import cucumber.runtime.RuntimeOptions; +import cucumber.runtime.RuntimeTest; import cucumber.runtime.io.ClasspathResourceLoader; import gherkin.formatter.model.Step; import org.junit.Test; @@ -45,7 +45,7 @@ private File runFeaturesWithJSONPrettyFormatter(final List featurePaths) RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties(), args.toArray(new String[args.size()])); Backend backend = mock(Backend.class); when(backend.getSnippet(any(Step.class))).thenReturn("TEST SNIPPET"); - final cucumber.runtime.Runtime runtime = new Runtime(resourceLoader, classLoader, asList(backend), runtimeOptions); + final cucumber.runtime.Runtime runtime = RuntimeTest.createRuntime(resourceLoader, classLoader, asList(backend), runtimeOptions); runtime.run(); return report; } diff --git a/core/src/test/java/cucumber/runtime/formatter/JUnitFormatterTest.java b/core/src/test/java/cucumber/runtime/formatter/JUnitFormatterTest.java index 70fc5e693d..01267c5a23 100644 --- a/core/src/test/java/cucumber/runtime/formatter/JUnitFormatterTest.java +++ b/core/src/test/java/cucumber/runtime/formatter/JUnitFormatterTest.java @@ -1,8 +1,8 @@ package cucumber.runtime.formatter; import cucumber.runtime.Backend; -import cucumber.runtime.Runtime; import cucumber.runtime.RuntimeOptions; +import cucumber.runtime.RuntimeTest; import cucumber.runtime.io.ClasspathResourceLoader; import gherkin.formatter.model.Step; import org.custommonkey.xmlunit.Diff; @@ -58,7 +58,7 @@ private File runFeaturesWithJunitFormatter(final List featurePaths) thro RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties(), args.toArray(new String[args.size()])); Backend backend = mock(Backend.class); when(backend.getSnippet(any(Step.class))).thenReturn("TEST SNIPPET"); - final cucumber.runtime.Runtime runtime = new Runtime(resourceLoader, classLoader, asList(backend), runtimeOptions); + final cucumber.runtime.Runtime runtime = RuntimeTest.createRuntime(resourceLoader, classLoader, asList(backend), runtimeOptions); runtime.run(); return report; } diff --git a/java/src/test/java/cucumber/runtime/java/JavaStepDefinitionTest.java b/java/src/test/java/cucumber/runtime/java/JavaStepDefinitionTest.java index 0c3fb06220..5b5a4d97a8 100644 --- a/java/src/test/java/cucumber/runtime/java/JavaStepDefinitionTest.java +++ b/java/src/test/java/cucumber/runtime/java/JavaStepDefinitionTest.java @@ -2,11 +2,16 @@ import cucumber.api.java.en.Given; import cucumber.runtime.AmbiguousStepDefinitionsException; +import cucumber.runtime.Backend; import cucumber.runtime.DuplicateStepDefinitionException; import cucumber.runtime.Glue; import cucumber.runtime.Runtime; +import cucumber.runtime.RuntimeGlue; import cucumber.runtime.RuntimeOptions; +import cucumber.runtime.UndefinedStepsTracker; import cucumber.runtime.io.ClasspathResourceLoader; +import cucumber.runtime.io.ResourceLoader; +import cucumber.runtime.xstream.LocalizedXStreams; import gherkin.I18n; import gherkin.formatter.Reporter; import gherkin.formatter.model.Comment; @@ -18,6 +23,7 @@ import org.mockito.ArgumentCaptor; import java.lang.reflect.Method; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -50,7 +56,7 @@ public class JavaStepDefinitionTest { private final JavaBackend backend = new JavaBackend(new SingletonFactory(defs)); private final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); private final RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties()); - private final Runtime runtime = new Runtime(new ClasspathResourceLoader(classLoader), classLoader, asList(backend), runtimeOptions); + private final Runtime runtime = createRuntime(new ClasspathResourceLoader(classLoader), classLoader, asList(backend), runtimeOptions); private final Glue glue = runtime.getGlue(); @org.junit.Before @@ -144,4 +150,11 @@ private Set asSet(T... items) { set.addAll(asList(items)); return set; } + + private Runtime createRuntime(ResourceLoader resourceLoader, ClassLoader classLoader, + Collection backends, RuntimeOptions runtimeOptions) { + UndefinedStepsTracker undefinedStepsTracker = new UndefinedStepsTracker(); + return new Runtime(resourceLoader, classLoader, backends, runtimeOptions, undefinedStepsTracker, + new RuntimeGlue(undefinedStepsTracker, new LocalizedXStreams(classLoader))); + } } diff --git a/junit/src/main/java/cucumber/api/junit/Cucumber.java b/junit/src/main/java/cucumber/api/junit/Cucumber.java index cdbbf82692..e8453231c9 100644 --- a/junit/src/main/java/cucumber/api/junit/Cucumber.java +++ b/junit/src/main/java/cucumber/api/junit/Cucumber.java @@ -56,7 +56,7 @@ public Cucumber(Class clazz) throws InitializationError, IOException { RuntimeOptions runtimeOptions = runtimeOptionsFactory.create(); ResourceLoader resourceLoader = new MultiLoader(classLoader); - runtime = new Runtime(resourceLoader, classLoader, runtimeOptions); + runtime = Runtime.createRuntime(resourceLoader, classLoader, runtimeOptions); jUnitReporter = new JUnitReporter(runtimeOptions.reporter(classLoader), runtimeOptions.formatter(classLoader), runtimeOptions.strict); addChildren(runtimeOptions.cucumberFeatures(resourceLoader));