Skip to content

Commit

Permalink
Removed OneTimeResourceLoader and made sure glue code is loaded only …
Browse files Browse the repository at this point in the history
…once. The Backend.loadGlue method should ideally be removed, and the World and gluePaths passed to each Backend's constructor. Other TODOs on this branch: rename World to Glue. RuntimeGlue should not have a ref back to Runtime. Make Scala work again (disabled it because I don't have the required Scala fu)
  • Loading branch information
aslakhellesoy committed Jan 18, 2012
1 parent fed7d3b commit bd0634e
Show file tree
Hide file tree
Showing 24 changed files with 112 additions and 115 deletions.
3 changes: 2 additions & 1 deletion build.xml
@@ -1,5 +1,6 @@
<project name="cucumber-jvm" default="publish-local">
<property name="modules" value="core:junit:java:picocontainer:spring:guice:groovy:ioke:rhino:clojure:jruby:jython:scala:openejb:weld"/>
<!-- TODO: put scala back -->
<property name="modules" value="core:junit:java:picocontainer:spring:guice:groovy:ioke:rhino:clojure:jruby:jython:openejb:weld"/>

<target name="publish-local">
<subant target="publish-local" buildpath="${modules}"/>
Expand Down
Expand Up @@ -29,13 +29,18 @@ public ClojureBackend(ResourceLoader resourceLoader) {
}

@Override
public void buildWorld(List<String> gluePaths, World world) {
public void loadGlue(World world, List<String> gluePaths) {
this.world = world;
for (String gluePath : gluePaths) {
for (Resource resource : resourceLoader.resources(gluePath, ".clj")) {
loadScript(resource);
}
}

}

@Override
public void buildWorld() {
}

private void loadScript(String path) {
Expand Down
3 changes: 1 addition & 2 deletions core/src/main/java/cucumber/cli/Main.java
Expand Up @@ -3,7 +3,6 @@
import cucumber.formatter.FormatterFactory;
import cucumber.formatter.MultiFormatter;
import cucumber.io.FileResourceLoader;
import cucumber.io.OneTimeResourceLoader;
import cucumber.runtime.Runtime;
import cucumber.runtime.snippets.SummaryPrinter;
import gherkin.formatter.Formatter;
Expand Down Expand Up @@ -72,7 +71,7 @@ public static void main(String[] argv) throws Throwable {
System.exit(1);
}

Runtime runtime = new Runtime(gluePaths, new OneTimeResourceLoader(new FileResourceLoader()), isDryRun);
Runtime runtime = new Runtime(gluePaths, new FileResourceLoader(), isDryRun);

if (dotCucumber != null) {
writeDotCucumber(featurePaths, dotCucumber, runtime);
Expand Down
5 changes: 1 addition & 4 deletions core/src/main/java/cucumber/io/ClasspathResourceLoader.java
Expand Up @@ -45,10 +45,7 @@ public <T> Collection<? extends T> instantiateSubclasses(Class<T> parentType, St
Collection<T> result = new HashSet<T>();
for (Class<? extends T> clazz : getDescendants(parentType, packagePath)) {
if (Utils.isInstantiable(clazz)) {
try {
result.add(newInstance(constructorParams, constructorArgs, clazz));
} catch (CucumberException ignore) {
}
result.add(newInstance(constructorParams, constructorArgs, clazz));
}
}
return result;
Expand Down
33 changes: 0 additions & 33 deletions core/src/main/java/cucumber/io/OneTimeResourceLoader.java

This file was deleted.

10 changes: 6 additions & 4 deletions core/src/main/java/cucumber/runtime/Backend.java
Expand Up @@ -5,14 +5,16 @@
import java.util.List;

public interface Backend {
/**
* Invoked once before all features. This is where stepdefs and hooks should be loaded.
*/
void loadGlue(World world, List<String> gluePaths);

/**
* Invoked before a new scenario starts. Implementations should do any necessary
* setup of new, isolated state here.
*
* @param gluePaths where to load from
* @param world into where
*/
void buildWorld(List<String> gluePaths, World world);
void buildWorld();

void disposeWorld();

Expand Down
14 changes: 6 additions & 8 deletions core/src/main/java/cucumber/runtime/Runtime.java
Expand Up @@ -29,13 +29,11 @@
public class Runtime {
private static final byte ERRORS = 0x1;
private static final List<Object> NO_FILTERS = emptyList();
private static final Collection<String> NO_TAGS = emptyList();

private final UndefinedStepsTracker tracker;
private final List<Throwable> errors = new ArrayList<Throwable>();
private final Collection<? extends Backend> backends;
private final boolean isDryRun;
private final List<String> gluePaths;
private final ResourceLoader resourceLoader;

private World world;
Expand All @@ -49,13 +47,15 @@ public Runtime(List<String> gluePaths, ResourceLoader resourceLoader, boolean is
}

public Runtime(List<String> gluePaths, ResourceLoader resourceLoader, Collection<? extends Backend> backends, boolean isDryRun) {
this.gluePaths = gluePaths;
this.backends = backends;
this.resourceLoader = resourceLoader;
this.isDryRun = isDryRun;
this.tracker = new UndefinedStepsTracker(backends);

this.world = new RuntimeWorld(this);
for (Backend backend : backends) {
backend.loadGlue(world, gluePaths);
}
}

private static Collection<? extends Backend> loadBackends(ResourceLoader resourceLoader) {
Expand Down Expand Up @@ -89,9 +89,9 @@ public void run(CucumberFeature cucumberFeature, Formatter formatter, Reporter r
formatter.eof();
}

public void buildBackendWorlds(World world) {
public void buildBackendWorlds() {
for (Backend backend : backends) {
backend.buildWorld(gluePaths, world);
backend.buildWorld();
}
tracker.reset();
}
Expand All @@ -111,9 +111,7 @@ public void disposeBackendWorlds() {
*/
public void writeStepdefsJson(List<String> featurePaths, File dotCucumber) throws IOException {
List<CucumberFeature> features = load(resourceLoader, featurePaths, NO_FILTERS);
//TODO: ensure that tagging still works
//World world = new RuntimeWorld(this, NO_TAGS);
buildBackendWorlds(world);
buildBackendWorlds();
List<StepDefinition> stepDefs = world.getStepDefinitions();
List<MetaStepdef> metaStepdefs = new StepdefGenerator().generate(stepDefs, features);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Expand Down
6 changes: 5 additions & 1 deletion core/src/main/java/cucumber/runtime/RuntimeWorld.java
Expand Up @@ -14,6 +14,9 @@ public class RuntimeWorld implements World {
private static final Object DUMMY_ARG = new Object();

// TODO - it's expensive to create a new LocalizedXStreams for each scenario - reuse a global one. (heh, except world is being recreated each time!)
/*
In the light of how this class is now used - one instance - purpose is to store glue code - I think we should rename it to RuntimeGlue implements Glue.
*/
private final LocalizedXStreams localizedXStreams = new LocalizedXStreams();
private final List<StepDefinition> stepDefinitions = new ArrayList<StepDefinition>();
private final List<HookDefinition> beforeHooks = new ArrayList<HookDefinition>();
Expand All @@ -26,12 +29,13 @@ public class RuntimeWorld implements World {

public RuntimeWorld(Runtime runtime) {
//TODO: does the runtime world need to see the runtime?
// AH: No, it shouldn't - it's a cyclic dependency we should get rid of
this.runtime = runtime;
}

@Override
public void buildBackendContextAndRunBeforeHooks(Reporter reporter, Set<String> tags) {
runtime.buildBackendWorlds(this);
runtime.buildBackendWorlds();
Collections.sort(beforeHooks, new HookComparator(true));
runHooks(beforeHooks, reporter, tags);
}
Expand Down
6 changes: 3 additions & 3 deletions core/src/test/java/cucumber/formatter/HTMLFormatterTest.java
@@ -1,8 +1,8 @@
package cucumber.formatter;

import cucumber.io.ClasspathResourceLoader;
import cucumber.runtime.Backend;
import cucumber.runtime.Runtime;
import cucumber.runtime.StubBackend;
import cucumber.runtime.model.CucumberFeature;
import org.junit.Test;
import org.mozilla.javascript.Context;
Expand All @@ -14,11 +14,11 @@
import java.io.IOException;
import java.util.List;

import static gherkin.util.FixJava.readReader;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;

public class HTMLFormatterTest {
@Test
Expand All @@ -28,7 +28,7 @@ public void writes_proper_html() throws IOException {
ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader();
List<CucumberFeature> features = CucumberFeature.load(resourceLoader, asList("cucumber/formatter/HTMLFormatterTest.feature"), emptyList());
List<String> gluePaths = emptyList();
Runtime runtime = new Runtime(gluePaths, resourceLoader, asList(new StubBackend()), false);
Runtime runtime = new Runtime(gluePaths, resourceLoader, asList(mock(Backend.class)), false);
runtime.run(features.get(0), f, f);
f.done();

Expand Down
4 changes: 2 additions & 2 deletions core/src/test/java/cucumber/runtime/BackgroundTest.java
Expand Up @@ -11,12 +11,12 @@
import static cucumber.runtime.TestHelper.feature;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;

public class BackgroundTest {
@Test
public void should_run_background() throws IOException {
Backend backend = new StubBackend();
Runtime runtime = new Runtime(new ArrayList<String>(), new ClasspathResourceLoader(), asList(backend), false);
Runtime runtime = new Runtime(new ArrayList<String>(), new ClasspathResourceLoader(), asList(mock(Backend.class)), false);
CucumberFeature feature = feature("test.feature", "" +
"Feature:\n" +
" Background:\n" +
Expand Down
20 changes: 0 additions & 20 deletions core/src/test/java/cucumber/runtime/StubBackend.java

This file was deleted.

Expand Up @@ -52,7 +52,12 @@ public void star_keyword_becomes_given_when_no_previous_step() {

private class TestBackend implements Backend {
@Override
public void buildWorld(List<String> gluePaths, World world) {
public void loadGlue(World world, List<String> gluePaths) {
throw new UnsupportedOperationException();
}

@Override
public void buildWorld() {
throw new UnsupportedOperationException();
}

Expand Down
5 changes: 4 additions & 1 deletion cucumber-jvm.ipr
Expand Up @@ -21,6 +21,10 @@
<entry name="?*.tld" />
<entry name="?*.ftl" />
<entry name="?*.feature" />
<entry name="?*.rb" />
<entry name="?*.groovy" />
<entry name="?*.py" />
<entry name="?*.ik" />
</wildcardResourcePatterns>
<annotationProcessing enabled="false" useClasspath="true" />
</component>
Expand Down Expand Up @@ -282,7 +286,6 @@
<module fileurl="file://$PROJECT_DIR$/openejb/cucumber-openejb.iml" filepath="$PROJECT_DIR$/openejb/cucumber-openejb.iml" />
<module fileurl="file://$PROJECT_DIR$/picocontainer/cucumber-picocontainer.iml" filepath="$PROJECT_DIR$/picocontainer/cucumber-picocontainer.iml" />
<module fileurl="file://$PROJECT_DIR$/rhino/cucumber-rhino.iml" filepath="$PROJECT_DIR$/rhino/cucumber-rhino.iml" />
<module fileurl="file://$PROJECT_DIR$/scala/cucumber-scala.iml" filepath="$PROJECT_DIR$/scala/cucumber-scala.iml" />
<module fileurl="file://$PROJECT_DIR$/spring/cucumber-spring.iml" filepath="$PROJECT_DIR$/spring/cucumber-spring.iml" />
<module fileurl="file://$PROJECT_DIR$/weld/cucumber-weld.iml" filepath="$PROJECT_DIR$/weld/cucumber-weld.iml" />
</modules>
Expand Down
Expand Up @@ -40,7 +40,7 @@ public GroovyBackend(GroovyShell shell, ResourceLoader resourceLoader) {
}

@Override
public void buildWorld(List<String> gluePaths, World world) {
public void loadGlue(World world, List<String> gluePaths) {
this.world = world;
final Binding context = new Binding();

Expand All @@ -53,7 +53,10 @@ public void buildWorld(List<String> gluePaths, World world) {
}
}
}

}

@Override
public void buildWorld() {
}

private Script parse(Resource resource) {
Expand Down
6 changes: 5 additions & 1 deletion ioke/src/main/java/cucumber/runtime/ioke/IokeBackend.java
Expand Up @@ -41,7 +41,7 @@ public IokeBackend(ResourceLoader resourceLoader) {
}

@Override
public void buildWorld(List<String> gluePaths, World world) {
public void loadGlue(World world, List<String> gluePaths) {
this.world = world;

for (String gluePath : gluePaths) {
Expand All @@ -52,6 +52,10 @@ public void buildWorld(List<String> gluePaths, World world) {
}
}

@Override
public void buildWorld() {
}

private void evaluate(Resource resource) {
try {
String path = resource.getPath().replace('\\', '/'); // Need forward paths, even whn on Windows
Expand Down
6 changes: 5 additions & 1 deletion java/src/main/java/cucumber/runtime/java/JavaBackend.java
Expand Up @@ -47,9 +47,13 @@ public JavaBackend(ObjectFactory objectFactory) {
}

@Override
public void buildWorld(List<String> gluePaths, World world) {
public void loadGlue(World world, List<String> gluePaths) {
this.world = world;
classpathMethodScanner.scan(this, gluePaths);
}

@Override
public void buildWorld() {
objectFactory.createInstances();
}

Expand Down
Expand Up @@ -23,7 +23,8 @@ public void finds_step_definitions_by_scanning_for_annotations() {
ObjectFactory factory = new DefaultJavaObjectFactory();
JavaBackend backend = new JavaBackend(factory);
WorldStub world = new WorldStub();
backend.buildWorld(asList("cucumber/runtime/java/test"), world);
backend.loadGlue(world, asList("cucumber/runtime/java/test"));
backend.buildWorld();
assertEquals(Stepdefs.class, factory.getInstance(Stepdefs.class).getClass());
}

Expand Down

0 comments on commit bd0634e

Please sign in to comment.