Last active
December 18, 2015 08:39
-
-
Save brasmusson/5755281 to your computer and use it in GitHub Desktop.
Cucumber-JVM: Cutting back on Runtime constructors.
It is possible to limit them to one constructor and one factory method, but is it the right way to go? 10 files will be affected (mostly test files) in the three projects core, java and junit. To simplify the creation of Runtime in test an additional factory method is introduced in RuntimeTest …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Runtime implements UnreportedStepExecutor { | |
// the factory method is used by cucumber.api.cli.Main and cucumber.api.junit.Cucumber | |
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))); | |
} | |
// The constructor is used in tests both in the core and in the java projects, therefore it needs to be public | |
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."); | |
} | |
this.resourceLoader = resourceLoader; | |
this.classLoader = classLoader; | |
this.backends = backends; | |
this.runtimeOptions = runtimeOptions; | |
this.undefinedStepsTracker = undefinedStepsTracker; | |
this.glue = glue; | |
this.summaryCounter = new SummaryCounter(runtimeOptions.monochrome); | |
for (Backend backend : backends) { | |
backend.loadGlue(glue, runtimeOptions.glue); | |
backend.setUnreportedStepExecutor(this); | |
} | |
} | |
// <snip> | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class RuntimeTest { | |
// this factory method is duplicated in the java project, cucumber.runtime.java.JavaStepDefinitionTest | |
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))); | |
} | |
//<snip> | |
} |
Yes, the UndefinedStepsTracker is localised to the Runtime, but the same instance is also sent to the RuntimeGlue (when the RuntimeGlue is created by the Runtime). To allow to inject a RuntimeGlue, and still have the normal option of using the same UndefinedStepTracker in the Runtime and RuntimeGlue, I did not come up to another solution than to create the UndefinedStepTracker in the factory method together with the RuntimeGlue and send both to the Runtime constructor.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This seems fine to me.
My only query is why we need to pass UndefinedStepsTracker to the constructor. Isn't this now localised to Runtime?