Skip to content

Commit c8feb10

Browse files
committed
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.
1 parent 07902e1 commit c8feb10

File tree

10 files changed

+44
-26
lines changed

10 files changed

+44
-26
lines changed

core/src/main/java/cucumber/api/cli/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public static void main(String[] argv) throws Throwable {
1515
public static void run(String[] argv, ClassLoader classLoader) throws IOException {
1616
RuntimeOptions runtimeOptions = new RuntimeOptions(System.getProperties(), argv);
1717

18-
Runtime runtime = new Runtime(new MultiLoader(classLoader), classLoader, runtimeOptions);
18+
Runtime runtime = Runtime.createRuntime(new MultiLoader(classLoader), classLoader, runtimeOptions);
1919
runtime.writeStepdefsJson();
2020
runtime.run();
2121
System.exit(runtime.exitStatus());

core/src/main/java/cucumber/runtime/Runtime.java

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,21 +59,13 @@ public class Runtime implements UnreportedStepExecutor {
5959
private boolean skipNextStep = false;
6060
private ScenarioImpl scenarioResult = null;
6161

62-
public Runtime(ResourceLoader resourceLoader, ClassLoader classLoader, RuntimeOptions runtimeOptions) {
63-
this(resourceLoader, classLoader, loadBackends(resourceLoader, classLoader), runtimeOptions);
62+
public static Runtime createRuntime(ResourceLoader resourceLoader, ClassLoader classLoader, RuntimeOptions runtimeOptions) {
63+
UndefinedStepsTracker undefinedStepsTracker = new UndefinedStepsTracker();
64+
return new Runtime(resourceLoader, classLoader, loadBackends(resourceLoader, classLoader), runtimeOptions,
65+
undefinedStepsTracker, new RuntimeGlue(undefinedStepsTracker, new LocalizedXStreams(classLoader)));
6466
}
6567

66-
public Runtime(ResourceLoader resourceLoader, ClassLoader classLoader, Collection<? extends Backend> backends, RuntimeOptions runtimeOptions) {
67-
this(resourceLoader, classLoader, backends, runtimeOptions, new UndefinedStepsTracker());
68-
}
69-
70-
private Runtime(ResourceLoader resourceLoader, ClassLoader classLoader, Collection<? extends Backend> backends,
71-
RuntimeOptions runtimeOptions, UndefinedStepsTracker undefinedStepsTracker) {
72-
this(resourceLoader, classLoader, backends, runtimeOptions, undefinedStepsTracker,
73-
new RuntimeGlue(undefinedStepsTracker, new LocalizedXStreams(classLoader)));
74-
}
75-
76-
Runtime(ResourceLoader resourceLoader, ClassLoader classLoader, Collection<? extends Backend> backends,
68+
public Runtime(ResourceLoader resourceLoader, ClassLoader classLoader, Collection<? extends Backend> backends,
7769
RuntimeOptions runtimeOptions, UndefinedStepsTracker undefinedStepsTracker, RuntimeGlue glue) {
7870
if (backends.isEmpty()) {
7971
throw new CucumberException("No backends were found. Please make sure you have a backend module on your CLASSPATH.");

core/src/test/java/cucumber/runtime/BackgroundTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class BackgroundTest {
1818
public void should_run_background() throws IOException {
1919
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
2020
RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties());
21-
Runtime runtime = new Runtime(new ClasspathResourceLoader(classLoader), classLoader, asList(mock(Backend.class)), runtimeOptions);
21+
Runtime runtime = RuntimeTest.createRuntime(new ClasspathResourceLoader(classLoader), classLoader, asList(mock(Backend.class)), runtimeOptions);
2222
CucumberFeature feature = feature("test.feature", "" +
2323
"Feature:\n" +
2424
" Background:\n" +

core/src/test/java/cucumber/runtime/HookOrderTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class HookOrderTest {
3131
public void buildMockWorld() {
3232
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
3333
RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties());
34-
runtime = new Runtime(mock(ResourceLoader.class), classLoader, asList(mock(Backend.class)), runtimeOptions);
34+
runtime = RuntimeTest.createRuntime(mock(ResourceLoader.class), classLoader, asList(mock(Backend.class)), runtimeOptions);
3535
runtime.buildBackendWorlds(null, Collections.<Tag>emptySet());
3636
glue = runtime.getGlue();
3737
}

core/src/test/java/cucumber/runtime/HookTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public void after_hooks_execute_before_objects_are_disposed() throws Throwable {
4545

4646
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
4747
RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties());
48-
Runtime runtime = new Runtime(new ClasspathResourceLoader(classLoader), classLoader, asList(backend), runtimeOptions);
48+
Runtime runtime = RuntimeTest.createRuntime(new ClasspathResourceLoader(classLoader), classLoader, asList(backend), runtimeOptions);
4949
runtime.getGlue().addAfterHook(hook);
5050

5151
scenario.run(mock(Formatter.class), mock(Reporter.class), runtime);

core/src/test/java/cucumber/runtime/RuntimeTest.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import cucumber.runtime.io.ClasspathResourceLoader;
66
import cucumber.runtime.io.ResourceLoader;
77
import cucumber.runtime.model.CucumberFeature;
8+
import cucumber.runtime.xstream.LocalizedXStreams;
89
import gherkin.I18n;
910
import gherkin.formatter.JSONFormatter;
1011
import gherkin.formatter.Reporter;
@@ -54,7 +55,7 @@ public void runs_feature_with_json_formatter() throws Exception {
5455
List<Backend> backends = asList(mock(Backend.class));
5556
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
5657
RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties());
57-
Runtime runtime = new Runtime(new ClasspathResourceLoader(classLoader), classLoader, backends, runtimeOptions);
58+
Runtime runtime = createRuntime(new ClasspathResourceLoader(classLoader), classLoader, backends, runtimeOptions);
5859
feature.run(jsonFormatter, jsonFormatter, runtime);
5960
jsonFormatter.done();
6061
String expected = "" +
@@ -182,7 +183,7 @@ public void strict_with_errors() {
182183
public void should_throw_cucumer_exception_if_no_backends_are_found() throws Exception {
183184
try {
184185
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
185-
new Runtime(new ClasspathResourceLoader(classLoader), classLoader, Collections.<Backend>emptyList(),
186+
createRuntime(new ClasspathResourceLoader(classLoader), classLoader, Collections.<Backend>emptyList(),
186187
new RuntimeOptions(new Properties()));
187188
fail("A CucumberException should have been thrown");
188189
} catch (CucumberException e) {
@@ -363,7 +364,19 @@ private Runtime createRuntime(String... runtimeArgs) {
363364
Backend backend = mock(Backend.class);
364365
Collection<Backend> backends = Arrays.asList(backend);
365366

366-
return new Runtime(resourceLoader, classLoader, backends, runtimeOptions);
367+
return createRuntime(resourceLoader, classLoader, backends, runtimeOptions);
368+
}
369+
370+
public static Runtime createRuntime(ResourceLoader resourceLoader, ClassLoader classLoader,
371+
Collection<? extends Backend> backends, RuntimeOptions runtimeOptions) {
372+
UndefinedStepsTracker undefinedStepsTracker = new UndefinedStepsTracker();
373+
return new Runtime(resourceLoader, classLoader, backends, runtimeOptions, undefinedStepsTracker,
374+
new RuntimeGlue(undefinedStepsTracker, new LocalizedXStreams(classLoader)));
375+
}
376+
377+
public static Runtime createRuntime(ResourceLoader resourceLoader, ClassLoader classLoader,
378+
Collection<Backend> backends, RuntimeOptions runtimeOptions, RuntimeGlue glue) {
379+
return new Runtime(resourceLoader, classLoader, backends, runtimeOptions, new UndefinedStepsTracker(), glue);
367380
}
368381

369382
private Runtime createRuntimeWithMockedGlue(StepDefinitionMatch match, String... runtimeArgs) {

core/src/test/java/cucumber/runtime/formatter/JSONPrettyFormatterTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package cucumber.runtime.formatter;
22

33
import cucumber.runtime.Backend;
4-
import cucumber.runtime.Runtime;
54
import cucumber.runtime.RuntimeOptions;
5+
import cucumber.runtime.RuntimeTest;
66
import cucumber.runtime.io.ClasspathResourceLoader;
77
import gherkin.formatter.model.Step;
88
import org.junit.Test;
@@ -45,7 +45,7 @@ private File runFeaturesWithJSONPrettyFormatter(final List<String> featurePaths)
4545
RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties(), args.toArray(new String[args.size()]));
4646
Backend backend = mock(Backend.class);
4747
when(backend.getSnippet(any(Step.class))).thenReturn("TEST SNIPPET");
48-
final cucumber.runtime.Runtime runtime = new Runtime(resourceLoader, classLoader, asList(backend), runtimeOptions);
48+
final cucumber.runtime.Runtime runtime = RuntimeTest.createRuntime(resourceLoader, classLoader, asList(backend), runtimeOptions);
4949
runtime.run();
5050
return report;
5151
}

core/src/test/java/cucumber/runtime/formatter/JUnitFormatterTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package cucumber.runtime.formatter;
22

33
import cucumber.runtime.Backend;
4-
import cucumber.runtime.Runtime;
54
import cucumber.runtime.RuntimeOptions;
5+
import cucumber.runtime.RuntimeTest;
66
import cucumber.runtime.io.ClasspathResourceLoader;
77
import gherkin.formatter.model.Step;
88
import org.custommonkey.xmlunit.Diff;
@@ -58,7 +58,7 @@ private File runFeaturesWithJunitFormatter(final List<String> featurePaths) thro
5858
RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties(), args.toArray(new String[args.size()]));
5959
Backend backend = mock(Backend.class);
6060
when(backend.getSnippet(any(Step.class))).thenReturn("TEST SNIPPET");
61-
final cucumber.runtime.Runtime runtime = new Runtime(resourceLoader, classLoader, asList(backend), runtimeOptions);
61+
final cucumber.runtime.Runtime runtime = RuntimeTest.createRuntime(resourceLoader, classLoader, asList(backend), runtimeOptions);
6262
runtime.run();
6363
return report;
6464
}

java/src/test/java/cucumber/runtime/java/JavaStepDefinitionTest.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22

33
import cucumber.api.java.en.Given;
44
import cucumber.runtime.AmbiguousStepDefinitionsException;
5+
import cucumber.runtime.Backend;
56
import cucumber.runtime.DuplicateStepDefinitionException;
67
import cucumber.runtime.Glue;
78
import cucumber.runtime.Runtime;
9+
import cucumber.runtime.RuntimeGlue;
810
import cucumber.runtime.RuntimeOptions;
11+
import cucumber.runtime.UndefinedStepsTracker;
912
import cucumber.runtime.io.ClasspathResourceLoader;
13+
import cucumber.runtime.io.ResourceLoader;
14+
import cucumber.runtime.xstream.LocalizedXStreams;
1015
import gherkin.I18n;
1116
import gherkin.formatter.Reporter;
1217
import gherkin.formatter.model.Comment;
@@ -18,6 +23,7 @@
1823
import org.mockito.ArgumentCaptor;
1924

2025
import java.lang.reflect.Method;
26+
import java.util.Collection;
2127
import java.util.Collections;
2228
import java.util.HashSet;
2329
import java.util.List;
@@ -50,7 +56,7 @@ public class JavaStepDefinitionTest {
5056
private final JavaBackend backend = new JavaBackend(new SingletonFactory(defs));
5157
private final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
5258
private final RuntimeOptions runtimeOptions = new RuntimeOptions(new Properties());
53-
private final Runtime runtime = new Runtime(new ClasspathResourceLoader(classLoader), classLoader, asList(backend), runtimeOptions);
59+
private final Runtime runtime = createRuntime(new ClasspathResourceLoader(classLoader), classLoader, asList(backend), runtimeOptions);
5460
private final Glue glue = runtime.getGlue();
5561

5662
@org.junit.Before
@@ -144,4 +150,11 @@ private <T> Set<T> asSet(T... items) {
144150
set.addAll(asList(items));
145151
return set;
146152
}
153+
154+
private Runtime createRuntime(ResourceLoader resourceLoader, ClassLoader classLoader,
155+
Collection<? extends Backend> backends, RuntimeOptions runtimeOptions) {
156+
UndefinedStepsTracker undefinedStepsTracker = new UndefinedStepsTracker();
157+
return new Runtime(resourceLoader, classLoader, backends, runtimeOptions, undefinedStepsTracker,
158+
new RuntimeGlue(undefinedStepsTracker, new LocalizedXStreams(classLoader)));
159+
}
147160
}

junit/src/main/java/cucumber/api/junit/Cucumber.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public Cucumber(Class clazz) throws InitializationError, IOException {
5656
RuntimeOptions runtimeOptions = runtimeOptionsFactory.create();
5757

5858
ResourceLoader resourceLoader = new MultiLoader(classLoader);
59-
runtime = new Runtime(resourceLoader, classLoader, runtimeOptions);
59+
runtime = Runtime.createRuntime(resourceLoader, classLoader, runtimeOptions);
6060

6161
jUnitReporter = new JUnitReporter(runtimeOptions.reporter(classLoader), runtimeOptions.formatter(classLoader), runtimeOptions.strict);
6262
addChildren(runtimeOptions.cucumberFeatures(resourceLoader));

0 commit comments

Comments
 (0)