From 3cda8a8db6df1bba36dca453dc8a63a40ac90386 Mon Sep 17 00:00:00 2001 From: Marty Kube Date: Wed, 13 Nov 2013 19:17:01 -0500 Subject: [PATCH 1/2] Eliminate duplicate glue paths by changing the type of RuntimeOptions.glue from a list to a set --- core/src/main/java/cucumber/runtime/Backend.java | 4 ++-- core/src/main/java/cucumber/runtime/RuntimeOptions.java | 6 ++++-- .../java/cucumber/runtime/RuntimeOptionsFactoryTest.java | 3 ++- .../src/test/java/cucumber/runtime/RuntimeOptionsTest.java | 7 ++++--- .../java/cucumber/runtime/UndefinedStepsTrackerTest.java | 3 ++- .../main/java/cucumber/runtime/groovy/GroovyBackend.java | 3 +-- ioke/src/main/java/cucumber/runtime/ioke/IokeBackend.java | 3 ++- java/src/main/java/cucumber/runtime/java/JavaBackend.java | 4 ++-- .../src/main/java/cucumber/runtime/java/MethodScanner.java | 4 ++-- .../test/java/cucumber/runtime/java/JavaBackendTest.java | 7 ++++--- java/src/test/java/cucumber/runtime/java/JavaHookTest.java | 2 +- .../java/cucumber/runtime/java/JavaStepDefinitionTest.java | 2 +- .../src/main/java/cucumber/runtime/jruby/JRubyBackend.java | 2 +- junit/src/test/java/cucumber/runtime/stub/StubBackend.java | 4 ++-- .../main/java/cucumber/runtime/jython/JythonBackend.java | 3 ++- .../src/main/java/cucumber/runtime/rhino/RhinoBackend.java | 5 +++-- .../test/java/cucumber/runtime/rhino/RhinoHooksTest.java | 7 ++++--- .../main/scala/cucumber/runtime/scala/ScalaBackend.scala | 6 ++++-- .../src/test/java/cucumber/runtime/stub/StubBackend.java | 4 ++-- 19 files changed, 45 insertions(+), 34 deletions(-) diff --git a/core/src/main/java/cucumber/runtime/Backend.java b/core/src/main/java/cucumber/runtime/Backend.java index ebfa09040b..8949c2b026 100644 --- a/core/src/main/java/cucumber/runtime/Backend.java +++ b/core/src/main/java/cucumber/runtime/Backend.java @@ -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 gluePaths); + void loadGlue(Glue glue, Set gluePaths); /** * invoked once, handing the backend a reference to a step executor diff --git a/core/src/main/java/cucumber/runtime/RuntimeOptions.java b/core/src/main/java/cucumber/runtime/RuntimeOptions.java index 3bec831669..209b7becc5 100644 --- a/core/src/main/java/cucumber/runtime/RuntimeOptions.java +++ b/core/src/main/java/cucumber/runtime/RuntimeOptions.java @@ -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 glue = new ArrayList(); + private final Set glue = new HashSet(); private final List filters = new ArrayList(); private final List lineFilters = new ArrayList(); private final List formatters = new ArrayList(); @@ -204,7 +206,7 @@ private void setStrictOnStrictAwareFormatters(Formatter formatter) { } } - public List getGlue() { + public Set getGlue() { return glue; } diff --git a/core/src/test/java/cucumber/runtime/RuntimeOptionsFactoryTest.java b/core/src/test/java/cucumber/runtime/RuntimeOptionsFactoryTest.java index fec3fe276f..82da2f64f7 100644 --- a/core/src/test/java/cucumber/runtime/RuntimeOptionsFactoryTest.java +++ b/core/src/test/java/cucumber/runtime/RuntimeOptionsFactoryTest.java @@ -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; @@ -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 diff --git a/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java b/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java index 176dd88c82..e12d4b7622 100644 --- a/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java +++ b/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java @@ -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; @@ -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 @@ -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()); } @@ -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 diff --git a/core/src/test/java/cucumber/runtime/UndefinedStepsTrackerTest.java b/core/src/test/java/cucumber/runtime/UndefinedStepsTrackerTest.java index f4b3631b7c..ca685550de 100644 --- a/core/src/test/java/cucumber/runtime/UndefinedStepsTrackerTest.java +++ b/core/src/test/java/cucumber/runtime/UndefinedStepsTrackerTest.java @@ -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; @@ -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 gluePaths) { + public void loadGlue(Glue glue, Set gluePaths) { throw new UnsupportedOperationException(); } diff --git a/groovy/src/main/java/cucumber/runtime/groovy/GroovyBackend.java b/groovy/src/main/java/cucumber/runtime/groovy/GroovyBackend.java index 05f701c6d3..e3575ae40f 100644 --- a/groovy/src/main/java/cucumber/runtime/groovy/GroovyBackend.java +++ b/groovy/src/main/java/cucumber/runtime/groovy/GroovyBackend.java @@ -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; @@ -60,7 +59,7 @@ public GroovyBackend(GroovyShell shell, ResourceLoader resourceLoader) { } @Override - public void loadGlue(Glue glue, List gluePaths) { + public void loadGlue(Glue glue, Set gluePaths) { this.glue = glue; final Binding context = shell.getContext(); diff --git a/ioke/src/main/java/cucumber/runtime/ioke/IokeBackend.java b/ioke/src/main/java/cucumber/runtime/ioke/IokeBackend.java index 5759310023..7f3ab5c2b8 100644 --- a/ioke/src/main/java/cucumber/runtime/ioke/IokeBackend.java +++ b/ioke/src/main/java/cucumber/runtime/ioke/IokeBackend.java @@ -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()); @@ -43,7 +44,7 @@ public IokeBackend(ResourceLoader resourceLoader) { } @Override - public void loadGlue(Glue glue, List gluePaths) { + public void loadGlue(Glue glue, Set gluePaths) { this.glue = glue; for (String gluePath : gluePaths) { diff --git a/java/src/main/java/cucumber/runtime/java/JavaBackend.java b/java/src/main/java/cucumber/runtime/java/JavaBackend.java index e93003f546..4043892441 100644 --- a/java/src/main/java/cucumber/runtime/java/JavaBackend.java +++ b/java/src/main/java/cucumber/runtime/java/JavaBackend.java @@ -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 { @@ -73,7 +73,7 @@ public static ObjectFactory loadObjectFactory(ClassFinder classFinder) { } @Override - public void loadGlue(Glue glue, List gluePaths) { + public void loadGlue(Glue glue, Set gluePaths) { this.glue = glue; methodScanner.scan(this, gluePaths); } diff --git a/java/src/main/java/cucumber/runtime/java/MethodScanner.java b/java/src/main/java/cucumber/runtime/java/MethodScanner.java index d97b56a65b..add066a9ff 100644 --- a/java/src/main/java/cucumber/runtime/java/MethodScanner.java +++ b/java/src/main/java/cucumber/runtime/java/MethodScanner.java @@ -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> cucumberAnnotationClasses; @@ -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 gluePaths) { + public void scan(JavaBackend javaBackend, Set gluePaths) { for (String gluePath : gluePaths) { for (Class glueCodeClass : classFinder.getDescendants(Object.class, packageName(gluePath))) { while (glueCodeClass != null && glueCodeClass != Object.class && !Utils.isInstantiable(glueCodeClass)) { diff --git a/java/src/test/java/cucumber/runtime/java/JavaBackendTest.java b/java/src/test/java/cucumber/runtime/java/JavaBackendTest.java index 7a54aee7d5..bfcc6e6349 100644 --- a/java/src/test/java/cucumber/runtime/java/JavaBackendTest.java +++ b/java/src/test/java/cucumber/runtime/java/JavaBackendTest.java @@ -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 { @@ -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()); } @@ -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()); } @@ -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 { diff --git a/java/src/test/java/cucumber/runtime/java/JavaHookTest.java b/java/src/test/java/cucumber/runtime/java/JavaHookTest.java index e6f7c4a30f..2d961cc9a7 100644 --- a/java/src/test/java/cucumber/runtime/java/JavaHookTest.java +++ b/java/src/test/java/cucumber/runtime/java/JavaHookTest.java @@ -44,7 +44,7 @@ public class JavaHookTest { @org.junit.Before public void loadNoGlue() { - backend.loadGlue(glue, Collections.emptyList()); + backend.loadGlue(glue, Collections.emptySet()); } @Test diff --git a/java/src/test/java/cucumber/runtime/java/JavaStepDefinitionTest.java b/java/src/test/java/cucumber/runtime/java/JavaStepDefinitionTest.java index 289cdae765..906780ea23 100644 --- a/java/src/test/java/cucumber/runtime/java/JavaStepDefinitionTest.java +++ b/java/src/test/java/cucumber/runtime/java/JavaStepDefinitionTest.java @@ -54,7 +54,7 @@ public class JavaStepDefinitionTest { @org.junit.Before public void loadNoGlue() { - backend.loadGlue(glue, Collections.emptyList()); + backend.loadGlue(glue, Collections.emptySet()); } @Test(expected = DuplicateStepDefinitionException.class) diff --git a/jruby/src/main/java/cucumber/runtime/jruby/JRubyBackend.java b/jruby/src/main/java/cucumber/runtime/jruby/JRubyBackend.java index ef2decfb90..e08ba10098 100644 --- a/jruby/src/main/java/cucumber/runtime/jruby/JRubyBackend.java +++ b/jruby/src/main/java/cucumber/runtime/jruby/JRubyBackend.java @@ -79,7 +79,7 @@ public JRubyBackend(ResourceLoader resourceLoader) throws UnsupportedEncodingExc } @Override - public void loadGlue(Glue glue, List gluePaths) { + public void loadGlue(Glue glue, Set gluePaths) { this.glue = glue; for (String gluePath : gluePaths) { for (Resource resource : resourceLoader.resources(gluePath, ".rb")) { diff --git a/junit/src/test/java/cucumber/runtime/stub/StubBackend.java b/junit/src/test/java/cucumber/runtime/stub/StubBackend.java index 3ac8f248b1..2c36628208 100644 --- a/junit/src/test/java/cucumber/runtime/stub/StubBackend.java +++ b/junit/src/test/java/cucumber/runtime/stub/StubBackend.java @@ -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. @@ -18,7 +18,7 @@ public StubBackend(ResourceLoader resourceLoader) { } @Override - public void loadGlue(Glue glue, List gluePaths) { + public void loadGlue(Glue glue, Set gluePaths) { } @Override diff --git a/jython/src/main/java/cucumber/runtime/jython/JythonBackend.java b/jython/src/main/java/cucumber/runtime/jython/JythonBackend.java index 79dfbc04c2..03e9b4b14a 100644 --- a/jython/src/main/java/cucumber/runtime/jython/JythonBackend.java +++ b/jython/src/main/java/cucumber/runtime/jython/JythonBackend.java @@ -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"; @@ -44,7 +45,7 @@ public JythonBackend(ResourceLoader resourceLoader) { } @Override - public void loadGlue(Glue glue, List gluePaths) { + public void loadGlue(Glue glue, Set gluePaths) { this.glue = glue; for (String gluePath : gluePaths) { diff --git a/rhino/src/main/java/cucumber/runtime/rhino/RhinoBackend.java b/rhino/src/main/java/cucumber/runtime/rhino/RhinoBackend.java index 4010f0d1f6..e810b10c3e 100644 --- a/rhino/src/main/java/cucumber/runtime/rhino/RhinoBackend.java +++ b/rhino/src/main/java/cucumber/runtime/rhino/RhinoBackend.java @@ -22,6 +22,7 @@ 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"; @@ -29,7 +30,7 @@ public class RhinoBackend implements Backend { private final ResourceLoader resourceLoader; private final Context cx; private final Scriptable scope; - private List gluePaths; + private Set gluePaths; private Glue glue; private Function buildWorldFn; private Function disposeWorldFn; @@ -44,7 +45,7 @@ public RhinoBackend(ResourceLoader resourceLoader) throws IOException { } @Override - public void loadGlue(Glue glue, List gluePaths) { + public void loadGlue(Glue glue, Set gluePaths) { this.glue = glue; this.gluePaths = gluePaths; for (String gluePath : gluePaths) { diff --git a/rhino/src/test/java/cucumber/runtime/rhino/RhinoHooksTest.java b/rhino/src/test/java/cucumber/runtime/rhino/RhinoHooksTest.java index b7c13905a5..55d9779183 100644 --- a/rhino/src/test/java/cucumber/runtime/rhino/RhinoHooksTest.java +++ b/rhino/src/test/java/cucumber/runtime/rhino/RhinoHooksTest.java @@ -8,7 +8,6 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import org.junit.Before; @@ -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) @@ -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 beforeHooks = beforeHookCaptor.getAllValues(); List afterHooks = afterHookCaptor.getAllValues(); @@ -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 beforeHooks = beforeHookCaptor.getAllValues(); try { diff --git a/scala/src/main/scala/cucumber/runtime/scala/ScalaBackend.scala b/scala/src/main/scala/cucumber/runtime/scala/ScalaBackend.scala index 34d54b673f..ae1846bb93 100644 --- a/scala/src/main/scala/cucumber/runtime/scala/ScalaBackend.scala +++ b/scala/src/main/scala/cucumber/runtime/scala/ScalaBackend.scala @@ -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 @@ -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(_) } @@ -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(_)} diff --git a/testng/src/test/java/cucumber/runtime/stub/StubBackend.java b/testng/src/test/java/cucumber/runtime/stub/StubBackend.java index 3ac8f248b1..2c36628208 100644 --- a/testng/src/test/java/cucumber/runtime/stub/StubBackend.java +++ b/testng/src/test/java/cucumber/runtime/stub/StubBackend.java @@ -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. @@ -18,7 +18,7 @@ public StubBackend(ResourceLoader resourceLoader) { } @Override - public void loadGlue(Glue glue, List gluePaths) { + public void loadGlue(Glue glue, Set gluePaths) { } @Override From 68e003306fb92f97164a68d958a188e4b7626dd2 Mon Sep 17 00:00:00 2001 From: Marty Kube Date: Wed, 13 Nov 2013 19:26:56 -0500 Subject: [PATCH 2/2] Added test to verify duplicate glue paths are prevent --- .../test/java/cucumber/runtime/RuntimeOptionsTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java b/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java index e12d4b7622..ef613a07f1 100644 --- a/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java +++ b/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java @@ -249,5 +249,14 @@ public void set_snippet_type() { RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), Collections.emptyList()); assertEquals(SnippetType.CAMELCASE, runtimeOptions.getSnippetType()); } + + @Test + public void prevent_duplicate_glue_paths() { + String gluePath = "/src/test/java/cucumber"; + RuntimeOptions runtimeOptions = new RuntimeOptions(Collections.emptyList()); + runtimeOptions.getGlue().add(gluePath); + runtimeOptions.getGlue().add(gluePath); + assertEquals(1, runtimeOptions.getGlue().size()); + } }