Skip to content

Prevent duplicate glue paths #632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions core/src/main/java/cucumber/runtime/Backend.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import cucumber.runtime.snippets.FunctionNameGenerator;
import gherkin.formatter.model.Step;

import java.util.List;
import java.util.Set;

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

/**
* invoked once, handing the backend a reference to a step executor
Expand Down
6 changes: 4 additions & 2 deletions core/src/main/java/cucumber/runtime/RuntimeOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
import java.util.regex.Pattern;

import static cucumber.runtime.model.CucumberFeature.load;
import java.util.HashSet;
import java.util.Set;

// IMPORTANT! Make sure USAGE.txt is always uptodate if this class changes.
public class RuntimeOptions {
public static final String VERSION = ResourceBundle.getBundle("cucumber.version").getString("cucumber-jvm.version");
public static final String USAGE = FixJava.readResource("/cucumber/runtime/USAGE.txt");

private final List<String> glue = new ArrayList<String>();
private final Set<String> glue = new HashSet<String>();
private final List<Object> filters = new ArrayList<Object>();
private final List<Object> lineFilters = new ArrayList<Object>();
private final List<Formatter> formatters = new ArrayList<Formatter>();
Expand Down Expand Up @@ -204,7 +206,7 @@ private void setStrictOnStrictAwareFormatters(Formatter formatter) {
}
}

public List<String> getGlue() {
public Set<String> getGlue() {
return glue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import static cucumber.runtime.RuntimeOptionsFactory.packageName;
import static cucumber.runtime.RuntimeOptionsFactory.packagePath;
import static java.util.Arrays.asList;
import java.util.HashSet;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
Expand All @@ -41,7 +42,7 @@ public void create_without_options() throws Exception {
RuntimeOptions runtimeOptions = runtimeOptionsFactory.create();
assertFalse(runtimeOptions.isStrict());
assertEquals(asList("classpath:cucumber/runtime"), runtimeOptions.getFeaturePaths());
assertEquals(asList("classpath:cucumber/runtime"), runtimeOptions.getGlue());
assertEquals(new HashSet(asList("classpath:cucumber/runtime")), runtimeOptions.getGlue());
}

@Test
Expand Down
16 changes: 13 additions & 3 deletions core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.regex.Pattern;

import static java.util.Arrays.asList;
import java.util.HashSet;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
Expand Down Expand Up @@ -64,7 +65,7 @@ public void strips_options() {
@Test
public void assigns_glue() {
RuntimeOptions options = new RuntimeOptions("--glue somewhere");
assertEquals(asList("somewhere"), options.getGlue());
assertEquals(new HashSet(asList("somewhere")), options.getGlue());
}

@Test
Expand Down Expand Up @@ -141,7 +142,7 @@ public void overrides_options_with_system_properties_without_clobbering_non_over
properties.setProperty("cucumber.options", "--glue lookatme this_clobbers_feature_paths");
RuntimeOptions options = new RuntimeOptions(new Env(properties), asList("--strict", "--glue", "somewhere", "somewhere_else"));
assertEquals(asList("this_clobbers_feature_paths"), options.getFeaturePaths());
assertEquals(asList("lookatme"), options.getGlue());
assertEquals(new HashSet(asList("lookatme")), options.getGlue());
assertTrue(options.isStrict());
}

Expand All @@ -150,7 +151,7 @@ public void ensure_cli_glue_is_preserved_when_cucumber_options_property_defined(
Properties properties = new Properties();
properties.setProperty("cucumber.options", "--tags @foo");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), asList("--glue", "somewhere"));
assertEquals(asList("somewhere"), runtimeOptions.getGlue());
assertEquals(new HashSet(asList("somewhere")), runtimeOptions.getGlue());
}

@Test
Expand Down Expand Up @@ -248,5 +249,14 @@ public void set_snippet_type() {
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), Collections.<String>emptyList());
assertEquals(SnippetType.CAMELCASE, runtimeOptions.getSnippetType());
}

@Test
public void prevent_duplicate_glue_paths() {
String gluePath = "/src/test/java/cucumber";
RuntimeOptions runtimeOptions = new RuntimeOptions(Collections.<String>emptyList());
runtimeOptions.getGlue().add(gluePath);
runtimeOptions.getGlue().add(gluePath);
assertEquals(1, runtimeOptions.getGlue().size());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.List;

import static java.util.Arrays.asList;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
Expand Down Expand Up @@ -81,7 +82,7 @@ public void snippets_are_generated_for_correct_locale() throws Exception {

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -60,7 +59,7 @@ public GroovyBackend(GroovyShell shell, ResourceLoader resourceLoader) {
}

@Override
public void loadGlue(Glue glue, List<String> gluePaths) {
public void loadGlue(Glue glue, Set<String> gluePaths) {
this.glue = glue;
final Binding context = shell.getContext();

Expand Down
3 changes: 2 additions & 1 deletion ioke/src/main/java/cucumber/runtime/ioke/IokeBackend.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

public class IokeBackend implements Backend {
private final SnippetGenerator snippetGenerator = new SnippetGenerator(new IokeSnippet());
Expand All @@ -43,7 +44,7 @@ public IokeBackend(ResourceLoader resourceLoader) {
}

@Override
public void loadGlue(Glue glue, List<String> gluePaths) {
public void loadGlue(Glue glue, Set<String> gluePaths) {
this.glue = glue;

for (String gluePath : gluePaths) {
Expand Down
4 changes: 2 additions & 2 deletions java/src/main/java/cucumber/runtime/java/JavaBackend.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

public class JavaBackend implements Backend {
Expand Down Expand Up @@ -73,7 +73,7 @@ public static ObjectFactory loadObjectFactory(ClassFinder classFinder) {
}

@Override
public void loadGlue(Glue glue, List<String> gluePaths) {
public void loadGlue(Glue glue, Set<String> gluePaths) {
this.glue = glue;
methodScanner.scan(this, gluePaths);
}
Expand Down
4 changes: 2 additions & 2 deletions java/src/main/java/cucumber/runtime/java/MethodScanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;

import static cucumber.runtime.io.MultiLoader.packageName;
import java.util.Set;

class MethodScanner {
private final Collection<Class<? extends Annotation>> cucumberAnnotationClasses;
Expand All @@ -29,7 +29,7 @@ public MethodScanner(ClassFinder classFinder) {
* @param javaBackend the backend where stepdefs and hooks will be registered
* @param gluePaths where to look
*/
public void scan(JavaBackend javaBackend, List<String> gluePaths) {
public void scan(JavaBackend javaBackend, Set<String> gluePaths) {
for (String gluePath : gluePaths) {
for (Class<?> glueCodeClass : classFinder.getDescendants(Object.class, packageName(gluePath))) {
while (glueCodeClass != null && glueCodeClass != Object.class && !Utils.isInstantiable(glueCodeClass)) {
Expand Down
7 changes: 4 additions & 3 deletions java/src/test/java/cucumber/runtime/java/JavaBackendTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.util.List;

import static java.util.Arrays.asList;
import java.util.HashSet;
import static org.junit.Assert.assertEquals;

public class JavaBackendTest {
Expand All @@ -24,7 +25,7 @@ public void finds_step_definitions_by_classpath_url() {
ObjectFactory factory = new DefaultJavaObjectFactory();
JavaBackend backend = new JavaBackend(factory);
GlueStub glue = new GlueStub();
backend.loadGlue(glue, asList("classpath:cucumber/runtime/java/stepdefs"));
backend.loadGlue(glue, new HashSet(asList("classpath:cucumber/runtime/java/stepdefs")));
backend.buildWorld();
assertEquals(Stepdefs.class, factory.getInstance(Stepdefs.class).getClass());
}
Expand All @@ -34,7 +35,7 @@ public void finds_step_definitions_by_package_name() {
ObjectFactory factory = new DefaultJavaObjectFactory();
JavaBackend backend = new JavaBackend(factory);
GlueStub glue = new GlueStub();
backend.loadGlue(glue, asList("cucumber.runtime.java.stepdefs"));
backend.loadGlue(glue, new HashSet(asList("cucumber.runtime.java.stepdefs")));
backend.buildWorld();
assertEquals(Stepdefs.class, factory.getInstance(Stepdefs.class).getClass());
}
Expand All @@ -44,7 +45,7 @@ public void detects_subclassed_glue_and_throws_exception() {
ObjectFactory factory = new DefaultJavaObjectFactory();
JavaBackend backend = new JavaBackend(factory);
GlueStub glue = new GlueStub();
backend.loadGlue(glue, asList("cucumber.runtime.java.stepdefs", "cucumber.runtime.java.incorrectlysubclassedstepdefs"));
backend.loadGlue(glue, new HashSet(asList("cucumber.runtime.java.stepdefs", "cucumber.runtime.java.incorrectlysubclassedstepdefs")));
}

private class GlueStub implements Glue {
Expand Down
2 changes: 1 addition & 1 deletion java/src/test/java/cucumber/runtime/java/JavaHookTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class JavaHookTest {

@org.junit.Before
public void loadNoGlue() {
backend.loadGlue(glue, Collections.<String>emptyList());
backend.loadGlue(glue, Collections.<String>emptySet());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class JavaStepDefinitionTest {

@org.junit.Before
public void loadNoGlue() {
backend.loadGlue(glue, Collections.<String>emptyList());
backend.loadGlue(glue, Collections.<String>emptySet());
}

@Test(expected = DuplicateStepDefinitionException.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public JRubyBackend(ResourceLoader resourceLoader) throws UnsupportedEncodingExc
}

@Override
public void loadGlue(Glue glue, List<String> gluePaths) {
public void loadGlue(Glue glue, Set<String> gluePaths) {
this.glue = glue;
for (String gluePath : gluePaths) {
for (Resource resource : resourceLoader.resources(gluePath, ".rb")) {
Expand Down
4 changes: 2 additions & 2 deletions junit/src/test/java/cucumber/runtime/stub/StubBackend.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import cucumber.runtime.snippets.FunctionNameGenerator;
import gherkin.formatter.model.Step;

import java.util.List;
import java.util.Set;

/**
* We need an implementation of Backend to prevent Runtime from blowing up.
Expand All @@ -18,7 +18,7 @@ public StubBackend(ResourceLoader resourceLoader) {
}

@Override
public void loadGlue(Glue glue, List<String> gluePaths) {
public void loadGlue(Glue glue, Set<String> gluePaths) {
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import java.util.Set;

public class JythonBackend implements Backend {
private static final String DSL = "/cucumber/runtime/jython/dsl.py";
Expand All @@ -44,7 +45,7 @@ public JythonBackend(ResourceLoader resourceLoader) {
}

@Override
public void loadGlue(Glue glue, List<String> gluePaths) {
public void loadGlue(Glue glue, Set<String> gluePaths) {
this.glue = glue;

for (String gluePath : gluePaths) {
Expand Down
5 changes: 3 additions & 2 deletions rhino/src/main/java/cucumber/runtime/rhino/RhinoBackend.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@
import cucumber.runtime.io.ResourceLoader;
import cucumber.runtime.snippets.FunctionNameGenerator;
import cucumber.runtime.snippets.SnippetGenerator;
import java.util.Set;

public class RhinoBackend implements Backend {
private static final String JS_DSL = "/cucumber/runtime/rhino/dsl.js";
private final SnippetGenerator snippetGenerator = new SnippetGenerator(new JavaScriptSnippet());
private final ResourceLoader resourceLoader;
private final Context cx;
private final Scriptable scope;
private List<String> gluePaths;
private Set<String> gluePaths;
private Glue glue;
private Function buildWorldFn;
private Function disposeWorldFn;
Expand All @@ -44,7 +45,7 @@ public RhinoBackend(ResourceLoader resourceLoader) throws IOException {
}

@Override
public void loadGlue(Glue glue, List<String> gluePaths) {
public void loadGlue(Glue glue, Set<String> gluePaths) {
this.glue = glue;
this.gluePaths = gluePaths;
for (String gluePath : gluePaths) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.junit.Before;
Expand All @@ -22,6 +21,8 @@
import cucumber.runtime.RuntimeGlue;
import cucumber.runtime.io.ClasspathResourceLoader;
import cucumber.runtime.io.ResourceLoader;
import java.util.Arrays;
import java.util.HashSet;
import org.mozilla.javascript.WrappedException;

@RunWith(MockitoJUnitRunner.class)
Expand Down Expand Up @@ -56,7 +57,7 @@ public void startCapturingHooksArguments() {
public void shouldCallAddBeforeAndAfterHook() throws IOException {
// when
RhinoBackend jsBackend = new RhinoBackend(resourceLoader);
jsBackend.loadGlue(glue, Collections.singletonList("cucumber/runtime/rhino_hooks"));
jsBackend.loadGlue(glue, new HashSet(Arrays.asList("cucumber/runtime/rhino_hooks")));
List<HookDefinition> beforeHooks = beforeHookCaptor.getAllValues();
List<HookDefinition> afterHooks = afterHookCaptor.getAllValues();

Expand All @@ -73,7 +74,7 @@ public void shouldCallAddBeforeAndAfterHook() throws IOException {
public void shouldFailWithTimeout() throws Throwable {
// when
RhinoBackend jsBackend = new RhinoBackend(resourceLoader);
jsBackend.loadGlue(glue, Collections.singletonList("cucumber/runtime/rhino_hooks_timeout"));
jsBackend.loadGlue(glue, new HashSet(Arrays.asList("cucumber/runtime/rhino_hooks_timeout")));
List<HookDefinition> beforeHooks = beforeHookCaptor.getAllValues();

try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cucumber.runtime.scala

import _root_.java.util.{List => JList}
import _root_.java.util.{ArrayList => JArrayList}
import _root_.java.util.{Set => JSet}
import _root_.gherkin.formatter.model.Step
import _root_.java.lang.reflect.Modifier
import _root_.cucumber.runtime.snippets.SnippetGenerator
Expand Down Expand Up @@ -35,7 +37,7 @@ class ScalaBackend(resourceLoader:ResourceLoader) extends Backend {
//I don't believe scala has to do anything to clean out its world
}

def loadGlue(glue: Glue, gluePaths: JList[String]) {
def loadGlue(glue: Glue, gluePaths: JSet[String]) {
val cl = Thread.currentThread().getContextClassLoader
val classFinder = new ResourceLoaderClassFinder(resourceLoader, cl)
val packages = gluePaths map { cucumber.runtime.io.MultiLoader.packageName(_) }
Expand All @@ -61,7 +63,7 @@ class ScalaBackend(resourceLoader:ResourceLoader) extends Backend {
}
val clsInstances = (clsClasses map {_.newInstance()})

instances = objInstances ++ clsInstances
instances = new JArrayList(objInstances) ++ clsInstances

getStepDefinitions map {glue.addStepDefinition(_)}
getBeforeHooks map {glue.addBeforeHook(_)}
Expand Down
Loading