Skip to content

Commit

Permalink
Minimize the number of constructors in the Runtime class
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
brasmusson committed Jun 24, 2013
1 parent 07902e1 commit c8feb10
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 26 deletions.
2 changes: 1 addition & 1 deletion core/src/main/java/cucumber/api/cli/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
18 changes: 5 additions & 13 deletions core/src/main/java/cucumber/runtime/Runtime.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<? extends Backend> backends, RuntimeOptions runtimeOptions) {
this(resourceLoader, classLoader, backends, runtimeOptions, new UndefinedStepsTracker());
}

private Runtime(ResourceLoader resourceLoader, ClassLoader classLoader, Collection<? extends Backend> backends,
RuntimeOptions runtimeOptions, UndefinedStepsTracker undefinedStepsTracker) {
this(resourceLoader, classLoader, backends, runtimeOptions, undefinedStepsTracker,
new RuntimeGlue(undefinedStepsTracker, new LocalizedXStreams(classLoader)));
}

Runtime(ResourceLoader resourceLoader, ClassLoader classLoader, Collection<? extends Backend> backends,
public Runtime(ResourceLoader resourceLoader, ClassLoader classLoader, Collection<? extends Backend> 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.");
Expand Down
2 changes: 1 addition & 1 deletion core/src/test/java/cucumber/runtime/BackgroundTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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" +
Expand Down
2 changes: 1 addition & 1 deletion core/src/test/java/cucumber/runtime/HookOrderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.<Tag>emptySet());
glue = runtime.getGlue();
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/test/java/cucumber/runtime/HookTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
19 changes: 16 additions & 3 deletions core/src/test/java/cucumber/runtime/RuntimeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -54,7 +55,7 @@ public void runs_feature_with_json_formatter() throws Exception {
List<Backend> 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 = "" +
Expand Down Expand Up @@ -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.<Backend>emptyList(),
createRuntime(new ClasspathResourceLoader(classLoader), classLoader, Collections.<Backend>emptyList(),
new RuntimeOptions(new Properties()));
fail("A CucumberException should have been thrown");
} catch (CucumberException e) {
Expand Down Expand Up @@ -363,7 +364,19 @@ private Runtime createRuntime(String... runtimeArgs) {
Backend backend = mock(Backend.class);
Collection<Backend> 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<? extends Backend> 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<Backend> backends, RuntimeOptions runtimeOptions, RuntimeGlue glue) {
return new Runtime(resourceLoader, classLoader, backends, runtimeOptions, new UndefinedStepsTracker(), glue);
}

private Runtime createRuntimeWithMockedGlue(StepDefinitionMatch match, String... runtimeArgs) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -45,7 +45,7 @@ private File runFeaturesWithJSONPrettyFormatter(final List<String> 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;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -58,7 +58,7 @@ private File runFeaturesWithJunitFormatter(final List<String> 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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -144,4 +150,11 @@ private <T> Set<T> asSet(T... items) {
set.addAll(asList(items));
return set;
}

private Runtime createRuntime(ResourceLoader resourceLoader, ClassLoader classLoader,
Collection<? extends Backend> backends, RuntimeOptions runtimeOptions) {
UndefinedStepsTracker undefinedStepsTracker = new UndefinedStepsTracker();
return new Runtime(resourceLoader, classLoader, backends, runtimeOptions, undefinedStepsTracker,
new RuntimeGlue(undefinedStepsTracker, new LocalizedXStreams(classLoader)));
}
}
2 changes: 1 addition & 1 deletion junit/src/main/java/cucumber/api/junit/Cucumber.java
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down

0 comments on commit c8feb10

Please sign in to comment.