From 2002352c0512bd1fa14dc25260834c365df6b6a7 Mon Sep 17 00:00:00 2001 From: Martin Schneider Date: Sat, 6 Oct 2018 18:20:11 +0800 Subject: [PATCH 1/5] Added a CucumberOptionsProvider to dynamically create and use CucumberOptions at runtime Usage example: ```@RunWith(Cucumber.class) @CucumberOptionsProvider(PropertiesFileCucumberOptionsProvider.class) public class JUnitRunnerClass {}``` `AbstractCucumberOptionsProvider` can be extended to load or create a configuration from any source. Options passed via `@CucumberOptions` will be loaded after the ones from the options provider. --- core/pom.xml | 4 + .../cucumber/api/CucumberOptionsProvider.java | 19 +++ .../AbstractCucumberOptionsProvider.java | 35 +++++ ...PropertiesFileCucumberOptionsProvider.java | 75 ++++++++++ .../runtime/RuntimeOptionsFactory.java | 43 +++++- ...ertiesFileCucumberOptionsProviderTest.java | 131 ++++++++++++++++++ .../runtime/RuntimeOptionsFactoryTest.java | 55 +++++++- .../CucumberOptionsProviderExtraGlue.java | 17 +++ .../CucumberOptionsProviderGlue.java | 16 +++ .../CucumberOptionsProviderNonStrict.java | 17 +++ .../CucumberOptionsProviderStrict.java | 17 +++ .../runtime/cucumberExtraGlue.properties | 1 + .../cucumberMultipleFeaturePaths.properties | 1 + .../runtime/cucumberMultipleGlue.properties | 1 + .../runtime/cucumberNonStrict.properties | 1 + .../cucumberSingleFeaturesPath.properties | 1 + .../runtime/cucumberSingleGlue.properties | 1 + .../cucumberSnippetsCamelCase.properties | 1 + .../cucumberSnippetsUnderscore.properties | 1 + .../runtime/cucumberStrict.properties | 1 + pom.xml | 6 + 21 files changed, 440 insertions(+), 4 deletions(-) create mode 100644 core/src/main/java/cucumber/api/CucumberOptionsProvider.java create mode 100644 core/src/main/java/cucumber/runtime/AbstractCucumberOptionsProvider.java create mode 100644 core/src/main/java/cucumber/runtime/PropertiesFileCucumberOptionsProvider.java create mode 100644 core/src/test/java/cucumber/runtime/PropertiesFileCucumberOptionsProviderTest.java create mode 100644 core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderExtraGlue.java create mode 100644 core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderGlue.java create mode 100644 core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderNonStrict.java create mode 100644 core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderStrict.java create mode 100644 core/src/test/resources/cucumber/runtime/cucumberExtraGlue.properties create mode 100644 core/src/test/resources/cucumber/runtime/cucumberMultipleFeaturePaths.properties create mode 100644 core/src/test/resources/cucumber/runtime/cucumberMultipleGlue.properties create mode 100644 core/src/test/resources/cucumber/runtime/cucumberNonStrict.properties create mode 100644 core/src/test/resources/cucumber/runtime/cucumberSingleFeaturesPath.properties create mode 100644 core/src/test/resources/cucumber/runtime/cucumberSingleGlue.properties create mode 100644 core/src/test/resources/cucumber/runtime/cucumberSnippetsCamelCase.properties create mode 100644 core/src/test/resources/cucumber/runtime/cucumberSnippetsUnderscore.properties create mode 100644 core/src/test/resources/cucumber/runtime/cucumberStrict.properties diff --git a/core/pom.xml b/core/pom.xml index dc0f1a380d..cd45e0afa5 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -32,6 +32,10 @@ io.cucumber datatable + + io.leangen.geantyref + geantyref + junit junit diff --git a/core/src/main/java/cucumber/api/CucumberOptionsProvider.java b/core/src/main/java/cucumber/api/CucumberOptionsProvider.java new file mode 100644 index 0000000000..d842d02a70 --- /dev/null +++ b/core/src/main/java/cucumber/api/CucumberOptionsProvider.java @@ -0,0 +1,19 @@ +package cucumber.api; + +import cucumber.runtime.AbstractCucumberOptionsProvider; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Define a class extending {@link AbstractCucumberOptionsProvider} which will provide additional + * Cucumber options during runtime. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface CucumberOptionsProvider { + /** @return the class used to contribute options */ + Class value() default + AbstractCucumberOptionsProvider.class; +} diff --git a/core/src/main/java/cucumber/runtime/AbstractCucumberOptionsProvider.java b/core/src/main/java/cucumber/runtime/AbstractCucumberOptionsProvider.java new file mode 100644 index 0000000000..6788120bd0 --- /dev/null +++ b/core/src/main/java/cucumber/runtime/AbstractCucumberOptionsProvider.java @@ -0,0 +1,35 @@ +package cucumber.runtime; + +import cucumber.api.CucumberOptions; +import io.leangen.geantyref.AnnotationFormatException; +import io.leangen.geantyref.TypeFactory; +import java.util.Map; + +/** This class allows dynamically contributing Cucumber options at runtime. */ +public abstract class AbstractCucumberOptionsProvider { + + /** + * This default provider returns an "empty" {@link CucumberOptions} object, i.e. all values are + * set to their default. Override this method to retrieve Cucumber options from any source + * (properties file, database etc.) + * + * @return the {@link CucumberOptions} to use + */ + public abstract CucumberOptions getOptions(); + + /** + * @param options map to hold the cucumber options + * @return an instance of {@link CucumberOptions} based on the values in the options mpa + */ + protected CucumberOptions getCucumberOptions(Map options) { + try { + return TypeFactory.annotation(CucumberOptions.class, options); + } catch (AnnotationFormatException e) { + throw new CucumberException( + String.format( + "Error creating %s from options map %s", + CucumberOptions.class.getName(), options.toString()), + e); + } + } +} diff --git a/core/src/main/java/cucumber/runtime/PropertiesFileCucumberOptionsProvider.java b/core/src/main/java/cucumber/runtime/PropertiesFileCucumberOptionsProvider.java new file mode 100644 index 0000000000..0eac22c398 --- /dev/null +++ b/core/src/main/java/cucumber/runtime/PropertiesFileCucumberOptionsProvider.java @@ -0,0 +1,75 @@ +package cucumber.runtime; + +import cucumber.api.CucumberOptions; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * Extension of {@link AbstractCucumberOptionsProvider} which will read Cucumber options from a + * properties file. + * + *

All properties with a key matching any of the methods in {@link CucumberOptions} are used to + * create an instance of {@link CucumberOptions}. All other properties are ignored. + * + *

Values which are of type String[] in {@link CucumberOptions} need to be defined as a single + * string separated by {@link cucumber.runtime.PropertiesFileCucumberOptionsProvider.DELIMITER} in + * the properties file. + * + *

The fully qualified path to the properties file can be passed via the `cucumberProperties` + * System property. The default is cucumber.properties in the user.home directory. + */ +public class PropertiesFileCucumberOptionsProvider extends AbstractCucumberOptionsProvider { + + public static final String PROPERTIES_FILE_PATH_KEY = "cucumberProperties"; + public static final String DELIMITER = ","; + private String propertiesPath; + + public PropertiesFileCucumberOptionsProvider() { + this.propertiesPath = + System.getProperty( + PROPERTIES_FILE_PATH_KEY, + System.getProperty("user.home") + File.pathSeparator + "cucumber.properties"); + } + + public CucumberOptions getOptions() { + Properties properties = new Properties(); + try { + properties.load(new FileInputStream(propertiesPath)); + } catch (IOException exception) { + throw new CucumberException("Error loading properties from file", exception); + } + + // create cucumber options from properties + Map options = new HashMap(); + for (Method method : CucumberOptions.class.getDeclaredMethods()) { + addOptionIfPresent(properties, options, method.getName(), method.getReturnType()); + } + return getCucumberOptions(options); + } + + private void addOptionIfPresent( + Properties props, Map options, String key, Class type) { + String value = props.getProperty(key); + // map property value to the appropriate type + if (value != null && !value.isEmpty()) { + if (type.equals(boolean.class)) { + options.put(key, Boolean.parseBoolean(value)); + } else if (type.equals(String[].class)) { + options.put(key, value.split(DELIMITER)); + } else if (type instanceof Class && ((Class) type).isEnum()) { + // TODO: this is not ideal as we make the assumption that the value of the enum matches its name (except case). + options.put(key, Enum.valueOf((Class) type, value.toUpperCase())); + } else { + throw new UnsupportedOperationException( + String.format( + "%s doesn't support mapping to type %f. Only boolean and String[] are supported.", + this.getClass().getName(), type.getClass().getName())); + } + } + } +} diff --git a/core/src/main/java/cucumber/runtime/RuntimeOptionsFactory.java b/core/src/main/java/cucumber/runtime/RuntimeOptionsFactory.java index d4e2ec1795..9c73b7c0cc 100644 --- a/core/src/main/java/cucumber/runtime/RuntimeOptionsFactory.java +++ b/core/src/main/java/cucumber/runtime/RuntimeOptionsFactory.java @@ -1,14 +1,15 @@ package cucumber.runtime; +import static java.util.Arrays.asList; import cucumber.api.CucumberOptions; +import cucumber.api.CucumberOptionsProvider; import cucumber.runtime.io.MultiLoader; - +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import static java.util.Arrays.asList; - public class RuntimeOptionsFactory { private final Class clazz; private boolean featuresSpecified = false; @@ -28,6 +29,11 @@ private List buildArgsFromOptions() { for (Class classWithOptions = clazz; hasSuperClass(classWithOptions); classWithOptions = classWithOptions.getSuperclass()) { CucumberOptions options = getOptions(classWithOptions); + AbstractCucumberOptionsProvider optionsProvider = getOptionsProvider(classWithOptions); + if (optionsProvider != null) + { + contributeOptions(optionsProvider.getOptions(), args); + } if (options != null) { addDryRun(options, args); addMonochrome(options, args); @@ -46,6 +52,37 @@ private List buildArgsFromOptions() { return args; } + private AbstractCucumberOptionsProvider getOptionsProvider(Class clazz) { + CucumberOptionsProvider optionsProvider = clazz.getAnnotation(CucumberOptionsProvider.class); + if (optionsProvider == null || Modifier.isAbstract(optionsProvider.value().getModifiers())) { + return null; + } + try { + return optionsProvider.value().getDeclaredConstructor().newInstance(); + } catch (InstantiationException + | IllegalAccessException + | IllegalArgumentException + | InvocationTargetException + | NoSuchMethodException + | SecurityException e) { + throw new CucumberException( + String.format("Error instantiating options provider %s", optionsProvider.value()), e); + } + } + + private void contributeOptions(CucumberOptions options, List args) { + addName(options, args); + addSnippets(options, args); + addDryRun(options, args); + addMonochrome(options, args); + addTags(options, args); + addPlugins(options, args); + addFeatures(options, args); + addGlue(options, args); + addStrict(options, args); + addJunitOptions(options, args); + } + private void addName(CucumberOptions options, List args) { for (String name : options.name()) { args.add("--name"); diff --git a/core/src/test/java/cucumber/runtime/PropertiesFileCucumberOptionsProviderTest.java b/core/src/test/java/cucumber/runtime/PropertiesFileCucumberOptionsProviderTest.java new file mode 100644 index 0000000000..c5a919f3b9 --- /dev/null +++ b/core/src/test/java/cucumber/runtime/PropertiesFileCucumberOptionsProviderTest.java @@ -0,0 +1,131 @@ +package cucumber.runtime; + +import static org.assertj.core.api.Assertions.assertThat; +import cucumber.api.CucumberOptions; +import cucumber.api.SnippetType; +import org.junit.Test; + +public class PropertiesFileCucumberOptionsProviderTest { + + private PropertiesFileCucumberOptionsProvider target; + + @Test + public void testExtraGlue() { + System.setProperty( + PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, + PropertiesFileCucumberOptionsProviderTest.class + .getResource("cucumberExtraGlue.properties") + .getPath()); + target = new PropertiesFileCucumberOptionsProvider(); + CucumberOptions options = target.getOptions(); + assertThat(options.extraGlue()) + .as("verify glue") + .isEqualTo( + new String[] {"io.github.martinschneider.steps3", "io.github.martinschneider.steps4"}); + } + + @Test + public void testMultipleFeaturePaths() { + System.setProperty( + PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, + PropertiesFileCucumberOptionsProviderTest.class + .getResource("cucumberMultipleFeaturePaths.properties") + .getPath()); + target = new PropertiesFileCucumberOptionsProvider(); + CucumberOptions options = target.getOptions(); + assertThat(options.features()) + .as("verify feature paths") + .isEqualTo(new String[] {"src/test/resources/features1", "src/test/resources/features2"}); + } + + @Test + public void testMultipleGlue() { + System.setProperty( + PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, + PropertiesFileCucumberOptionsProviderTest.class + .getResource("cucumberMultipleGlue.properties") + .getPath()); + target = new PropertiesFileCucumberOptionsProvider(); + CucumberOptions options = target.getOptions(); + assertThat(options.glue()) + .as("verify glue") + .isEqualTo( + new String[] {"io.github.martinschneider.steps1", "io.github.martinschneider.steps2"}); + } + + @Test + public void testSingleFeaturesPath() { + System.setProperty( + PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, + PropertiesFileCucumberOptionsProviderTest.class + .getResource("cucumberSingleFeaturesPath.properties") + .getPath()); + target = new PropertiesFileCucumberOptionsProvider(); + CucumberOptions options = target.getOptions(); + assertThat(options.features()) + .as("verify feature path") + .isEqualTo(new String[] {"src/test/resources/features1"}); + } + + @Test + public void testSingleGlue() { + System.setProperty( + PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, + PropertiesFileCucumberOptionsProviderTest.class + .getResource("cucumberSingleGlue.properties") + .getPath()); + target = new PropertiesFileCucumberOptionsProvider(); + CucumberOptions options = target.getOptions(); + assertThat(options.glue()) + .as("verify feature path") + .isEqualTo(new String[] {"io.github.martinschneider.steps1"}); + } + + @Test + public void testStrict() { + System.setProperty( + PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, + PropertiesFileCucumberOptionsProviderTest.class + .getResource("cucumberStrict.properties") + .getPath()); + target = new PropertiesFileCucumberOptionsProvider(); + CucumberOptions options = target.getOptions(); + assertThat(options.strict()).as("verify strict").isTrue(); + } + + @Test + public void testNonStrict() { + System.setProperty( + PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, + PropertiesFileCucumberOptionsProviderTest.class + .getResource("cucumberNonStrict.properties") + .getPath()); + target = new PropertiesFileCucumberOptionsProvider(); + CucumberOptions options = target.getOptions(); + assertThat(options.strict()).as("verify strict").isFalse(); + } + + @Test + public void testSnippetsUnderscore() { + System.setProperty( + PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, + PropertiesFileCucumberOptionsProviderTest.class + .getResource("cucumberSnippetsUnderscore.properties") + .getPath()); + target = new PropertiesFileCucumberOptionsProvider(); + CucumberOptions options = target.getOptions(); + assertThat(options.snippets()).as("verify snippet").isEqualTo(SnippetType.UNDERSCORE); + } + + @Test + public void testSnippetsCamelCase() { + System.setProperty( + PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, + PropertiesFileCucumberOptionsProviderTest.class + .getResource("cucumberSnippetsCamelCase.properties") + .getPath()); + target = new PropertiesFileCucumberOptionsProvider(); + CucumberOptions options = target.getOptions(); + assertThat(options.snippets()).as("verify snippet").isEqualTo(SnippetType.CAMELCASE); + } +} diff --git a/core/src/test/java/cucumber/runtime/RuntimeOptionsFactoryTest.java b/core/src/test/java/cucumber/runtime/RuntimeOptionsFactoryTest.java index b198485398..c9ef82a6d4 100644 --- a/core/src/test/java/cucumber/runtime/RuntimeOptionsFactoryTest.java +++ b/core/src/test/java/cucumber/runtime/RuntimeOptionsFactoryTest.java @@ -1,14 +1,18 @@ package cucumber.runtime; import cucumber.api.CucumberOptions; +import cucumber.api.CucumberOptionsProvider; import cucumber.api.Plugin; import cucumber.api.SnippetType; import cucumber.runner.TimeService; import cucumber.runner.TimeServiceEventBus; import cucumber.runtime.formatter.PluginFactory; import cucumber.runtime.formatter.Plugins; +import cucumber.runtime.optionsprovider.CucumberOptionsProviderExtraGlue; +import cucumber.runtime.optionsprovider.CucumberOptionsProviderGlue; +import cucumber.runtime.optionsprovider.CucumberOptionsProviderNonStrict; +import cucumber.runtime.optionsprovider.CucumberOptionsProviderStrict; import org.junit.Test; - import java.util.Iterator; import java.util.List; import java.util.regex.Pattern; @@ -187,6 +191,34 @@ public void cannot_create_with_glue_and_extra_glue() { RuntimeOptionsFactory runtimeOptionsFactory = new RuntimeOptionsFactory(ClassWithGlueAndExtraGlue.class); runtimeOptionsFactory.create(); } + + @Test + public void createOptionsProviderStrict() { + RuntimeOptionsFactory runtimeOptionsFactory = new RuntimeOptionsFactory(ClassWithCucumberOptionsProviderStrict.class); + RuntimeOptions runtimeOptions = runtimeOptionsFactory.create(); + assertTrue(runtimeOptions.isStrict()); + } + + @Test + public void createOptionsProviderNonStrict() { + RuntimeOptionsFactory runtimeOptionsFactory = new RuntimeOptionsFactory(ClassWithCucumberOptionsProviderNonStrict.class); + RuntimeOptions runtimeOptions = runtimeOptionsFactory.create(); + assertFalse(runtimeOptions.isStrict()); + } + + @Test + public void createOptionsProviderWithGlue() { + RuntimeOptionsFactory runtimeOptionsFactory = new RuntimeOptionsFactory(ClassWithCucumberOptionsProviderGlue.class); + RuntimeOptions runtimeOptions = runtimeOptionsFactory.create(); + assertEquals(asList("app.features.user.registration", "app.features.hooks"), runtimeOptions.getGlue()); + } + + @Test + public void createOptionsProviderWithExtraGlue() { + RuntimeOptionsFactory runtimeOptionsFactory = new RuntimeOptionsFactory(ClassWithCucumberOptionsProviderExtraGlue.class); + RuntimeOptions runtimeOptions = runtimeOptionsFactory.create(); + assertEquals(asList("app.features.hooks", "classpath:cucumber/runtime"), runtimeOptions.getGlue()); + } @CucumberOptions(snippets = SnippetType.CAMELCASE) @@ -280,5 +312,26 @@ private static class SubClassWithExtraGlueOfGlue extends ClassWithGlue { private static class ClassWithGlueAndExtraGlue { // empty } + + @CucumberOptionsProvider(CucumberOptionsProviderStrict.class) + private static class ClassWithCucumberOptionsProviderStrict{ + // empty + } + + @CucumberOptionsProvider(CucumberOptionsProviderNonStrict.class) + private static class ClassWithCucumberOptionsProviderNonStrict{ + // empty + } + + @CucumberOptionsProvider(CucumberOptionsProviderGlue.class) + private static class ClassWithCucumberOptionsProviderGlue{ + // empty + } + + @CucumberOptionsProvider(CucumberOptionsProviderExtraGlue.class) + private static class ClassWithCucumberOptionsProviderExtraGlue{ + // empty + } + } diff --git a/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderExtraGlue.java b/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderExtraGlue.java new file mode 100644 index 0000000000..5b227b0780 --- /dev/null +++ b/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderExtraGlue.java @@ -0,0 +1,17 @@ +package cucumber.runtime.optionsprovider; + +import cucumber.api.CucumberOptions; +import cucumber.runtime.AbstractCucumberOptionsProvider; +import java.util.HashMap; +import java.util.Map; + +public class CucumberOptionsProviderExtraGlue extends AbstractCucumberOptionsProvider{ + + @Override + public CucumberOptions getOptions() { + Map options = new HashMap(); + options.put("extraGlue", new String[]{"app.features.hooks"}); + return getCucumberOptions(options); + } + +} diff --git a/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderGlue.java b/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderGlue.java new file mode 100644 index 0000000000..8539685d7b --- /dev/null +++ b/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderGlue.java @@ -0,0 +1,16 @@ +package cucumber.runtime.optionsprovider; + +import cucumber.api.CucumberOptions; +import cucumber.runtime.AbstractCucumberOptionsProvider; +import java.util.HashMap; +import java.util.Map; + +public class CucumberOptionsProviderGlue extends AbstractCucumberOptionsProvider { + + @Override + public CucumberOptions getOptions() { + Map options = new HashMap(); + options.put("glue", new String[] {"app.features.user.registration", "app.features.hooks"}); + return getCucumberOptions(options); + } +} diff --git a/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderNonStrict.java b/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderNonStrict.java new file mode 100644 index 0000000000..fe326bebdc --- /dev/null +++ b/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderNonStrict.java @@ -0,0 +1,17 @@ +package cucumber.runtime.optionsprovider; + +import cucumber.api.CucumberOptions; +import cucumber.runtime.AbstractCucumberOptionsProvider; +import java.util.HashMap; +import java.util.Map; + +public class CucumberOptionsProviderNonStrict extends AbstractCucumberOptionsProvider{ + + @Override + public CucumberOptions getOptions() { + Map options = new HashMap(); + options.put("strict", false); + return getCucumberOptions(options); + } + +} diff --git a/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderStrict.java b/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderStrict.java new file mode 100644 index 0000000000..1cc0ed234a --- /dev/null +++ b/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderStrict.java @@ -0,0 +1,17 @@ +package cucumber.runtime.optionsprovider; + +import cucumber.api.CucumberOptions; +import cucumber.runtime.AbstractCucumberOptionsProvider; +import java.util.HashMap; +import java.util.Map; + +public class CucumberOptionsProviderStrict extends AbstractCucumberOptionsProvider{ + + @Override + public CucumberOptions getOptions() { + Map options = new HashMap(); + options.put("strict", true); + return getCucumberOptions(options); + } + +} diff --git a/core/src/test/resources/cucumber/runtime/cucumberExtraGlue.properties b/core/src/test/resources/cucumber/runtime/cucumberExtraGlue.properties new file mode 100644 index 0000000000..7c8fae024d --- /dev/null +++ b/core/src/test/resources/cucumber/runtime/cucumberExtraGlue.properties @@ -0,0 +1 @@ +extraGlue=io.github.martinschneider.steps3,io.github.martinschneider.steps4 \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberMultipleFeaturePaths.properties b/core/src/test/resources/cucumber/runtime/cucumberMultipleFeaturePaths.properties new file mode 100644 index 0000000000..1327d75447 --- /dev/null +++ b/core/src/test/resources/cucumber/runtime/cucumberMultipleFeaturePaths.properties @@ -0,0 +1 @@ +features=src/test/resources/features1,src/test/resources/features2 \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberMultipleGlue.properties b/core/src/test/resources/cucumber/runtime/cucumberMultipleGlue.properties new file mode 100644 index 0000000000..543c54dd72 --- /dev/null +++ b/core/src/test/resources/cucumber/runtime/cucumberMultipleGlue.properties @@ -0,0 +1 @@ +glue=io.github.martinschneider.steps1,io.github.martinschneider.steps2 \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberNonStrict.properties b/core/src/test/resources/cucumber/runtime/cucumberNonStrict.properties new file mode 100644 index 0000000000..d9b5dab91a --- /dev/null +++ b/core/src/test/resources/cucumber/runtime/cucumberNonStrict.properties @@ -0,0 +1 @@ +strict=false \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberSingleFeaturesPath.properties b/core/src/test/resources/cucumber/runtime/cucumberSingleFeaturesPath.properties new file mode 100644 index 0000000000..f9957214c3 --- /dev/null +++ b/core/src/test/resources/cucumber/runtime/cucumberSingleFeaturesPath.properties @@ -0,0 +1 @@ +features=src/test/resources/features1 \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberSingleGlue.properties b/core/src/test/resources/cucumber/runtime/cucumberSingleGlue.properties new file mode 100644 index 0000000000..9ca07504b6 --- /dev/null +++ b/core/src/test/resources/cucumber/runtime/cucumberSingleGlue.properties @@ -0,0 +1 @@ +glue=io.github.martinschneider.steps1 \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberSnippetsCamelCase.properties b/core/src/test/resources/cucumber/runtime/cucumberSnippetsCamelCase.properties new file mode 100644 index 0000000000..ca0f10f4cd --- /dev/null +++ b/core/src/test/resources/cucumber/runtime/cucumberSnippetsCamelCase.properties @@ -0,0 +1 @@ +snippets=camelcase \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberSnippetsUnderscore.properties b/core/src/test/resources/cucumber/runtime/cucumberSnippetsUnderscore.properties new file mode 100644 index 0000000000..2c47acfe52 --- /dev/null +++ b/core/src/test/resources/cucumber/runtime/cucumberSnippetsUnderscore.properties @@ -0,0 +1 @@ +snippets=underscore \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberStrict.properties b/core/src/test/resources/cucumber/runtime/cucumberStrict.properties new file mode 100644 index 0000000000..d8555b61ab --- /dev/null +++ b/core/src/test/resources/cucumber/runtime/cucumberStrict.properties @@ -0,0 +1 @@ +strict=true \ No newline at end of file diff --git a/pom.xml b/pom.xml index dc70e8de2c..43d5fc8059 100644 --- a/pom.xml +++ b/pom.xml @@ -83,6 +83,7 @@ 0.5.0 6.1.0 1.1.3 + 1.3.4 @@ -480,6 +481,11 @@ typetools ${typetools.version} + + io.leangen.geantyref + geantyref + ${geantyref.version} + From a0c36b0b5fb6a0411b0d005985e3b30d33d4df0d Mon Sep 17 00:00:00 2001 From: Martin Schneider Date: Sat, 6 Oct 2018 20:51:15 +0800 Subject: [PATCH 2/5] Fixing test Updating javadoc --- .../src/test/java/cucumber/runtime/io/ResourceLoaderTest.java | 4 ++-- junit/src/main/java/cucumber/api/junit/Cucumber.java | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/test/java/cucumber/runtime/io/ResourceLoaderTest.java b/core/src/test/java/cucumber/runtime/io/ResourceLoaderTest.java index 79dcf26509..fa901b802b 100644 --- a/core/src/test/java/cucumber/runtime/io/ResourceLoaderTest.java +++ b/core/src/test/java/cucumber/runtime/io/ResourceLoaderTest.java @@ -21,7 +21,7 @@ public ResourceLoaderTest() throws UnsupportedEncodingException { @Test public void loads_resources_from_filesystem_dir() { Iterable files = new FileResourceLoader().resources(dir.getAbsolutePath(), ".properties"); - assertEquals(4, toList(files).size()); + assertEquals(13, toList(files).size()); } @Test @@ -34,7 +34,7 @@ public void loads_resource_from_filesystem_file() { @Test public void loads_resources_from_jar_on_classpath() throws IOException { Iterable files = new ClasspathResourceLoader(Thread.currentThread().getContextClassLoader()).resources("cucumber", ".properties"); - assertEquals(4, toList(files).size()); + assertEquals(13, toList(files).size()); } private List toList(Iterable it) { diff --git a/junit/src/main/java/cucumber/api/junit/Cucumber.java b/junit/src/main/java/cucumber/api/junit/Cucumber.java index 39b2eeab10..8971bc0eac 100644 --- a/junit/src/main/java/cucumber/api/junit/Cucumber.java +++ b/junit/src/main/java/cucumber/api/junit/Cucumber.java @@ -61,6 +61,7 @@ * Cucumber-Eclipse. Instead it is recommended to use Cucumbers `Before` and `After` hooks. * * @see CucumberOptions + * @see CucumberOptionsProvider */ public class Cucumber extends ParentRunner { private final List children = new ArrayList(); From 38b2afe38bd432c5dd35ed3751bc90ef632da816 Mon Sep 17 00:00:00 2001 From: Martin Schneider Date: Sun, 7 Oct 2018 00:46:17 +0800 Subject: [PATCH 3/5] Updating versions --- core/pom.xml | 1 + java/pom.xml | 1 + java8/pom.xml | 1 + junit/pom.xml | 1 + 4 files changed, 4 insertions(+) diff --git a/core/pom.xml b/core/pom.xml index cd45e0afa5..039cb6366f 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -8,6 +8,7 @@ cucumber-core + 4.0.2-SNAPSHOT jar Cucumber-JVM: Core diff --git a/java/pom.xml b/java/pom.xml index f3ae8fcc2a..91c98b2f9a 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -8,6 +8,7 @@ cucumber-java + 4.0.2-SNAPSHOT jar Cucumber-JVM: Java diff --git a/java8/pom.xml b/java8/pom.xml index b2f5b2863a..86a36cd780 100644 --- a/java8/pom.xml +++ b/java8/pom.xml @@ -8,6 +8,7 @@ cucumber-java8 + 4.0.2-SNAPSHOT jar Cucumber-JVM: Java8 diff --git a/junit/pom.xml b/junit/pom.xml index 0940dae9ed..aaa7e2844e 100644 --- a/junit/pom.xml +++ b/junit/pom.xml @@ -8,6 +8,7 @@ cucumber-junit + 4.0.2-SNAPSHOT jar Cucumber-JVM: JUnit From 3ea7568a6b6cc6e0ef02764ed3df5b5b72659c2c Mon Sep 17 00:00:00 2001 From: Martin Schneider Date: Sun, 7 Oct 2018 07:33:41 +0800 Subject: [PATCH 4/5] Fix javadoc --- junit/src/main/java/cucumber/api/junit/Cucumber.java | 1 + 1 file changed, 1 insertion(+) diff --git a/junit/src/main/java/cucumber/api/junit/Cucumber.java b/junit/src/main/java/cucumber/api/junit/Cucumber.java index 8971bc0eac..99aa6d1ead 100644 --- a/junit/src/main/java/cucumber/api/junit/Cucumber.java +++ b/junit/src/main/java/cucumber/api/junit/Cucumber.java @@ -1,6 +1,7 @@ package cucumber.api.junit; import cucumber.api.CucumberOptions; +import cucumber.api.CucumberOptionsProvider; import cucumber.api.StepDefinitionReporter; import cucumber.api.event.TestRunFinished; import cucumber.api.event.TestRunStarted; From cf2ae750b99b9fb142bb4095807736c0c393bef9 Mon Sep 17 00:00:00 2001 From: Martin Schneider Date: Sat, 20 Oct 2018 12:35:38 +0800 Subject: [PATCH 5/5] v2 --- core/pom.xml | 9 +- .../cucumber/api/CucumberConfiguration.java | 18 + .../cucumber/api/CucumberOptionsProvider.java | 19 - .../AbstractCucumberOptionsProvider.java | 35 - .../cucumber/runtime/ConfigurationParser.java | 7 + ...PropertiesFileCucumberOptionsProvider.java | 75 -- .../java/cucumber/runtime/RuntimeOptions.java | 656 +++++++++--------- .../runtime/RuntimeOptionsFactory.java | 327 +++++---- .../OptionsConfigurationParser.java | 65 ++ .../YamlConfigurationParser.java | 21 + ...ertiesFileCucumberOptionsProviderTest.java | 131 ---- .../runtime/RuntimeOptionsFactoryTest.java | 75 +- .../cucumber/runtime/RuntimeOptionsTest.java | 6 - .../runtime/io/ResourceLoaderTest.java | 4 +- .../CucumberOptionsProviderExtraGlue.java | 17 - .../CucumberOptionsProviderGlue.java | 16 - .../CucumberOptionsProviderNonStrict.java | 17 - .../CucumberOptionsProviderStrict.java | 17 - .../runtime/cucumberExtraGlue.properties | 1 - .../cucumberMultipleFeaturePaths.properties | 1 - .../runtime/cucumberMultipleGlue.properties | 1 - .../runtime/cucumberNonStrict.properties | 1 - .../cucumberSingleFeaturesPath.properties | 1 - .../runtime/cucumberSingleGlue.properties | 1 - .../cucumberSnippetsCamelCase.properties | 1 - .../cucumberSnippetsUnderscore.properties | 1 - .../runtime/cucumberStrict.properties | 1 - .../java/cucumber/api/junit/Cucumber.java | 2 - pom.xml | 14 +- 29 files changed, 632 insertions(+), 908 deletions(-) create mode 100644 core/src/main/java/cucumber/api/CucumberConfiguration.java delete mode 100644 core/src/main/java/cucumber/api/CucumberOptionsProvider.java delete mode 100644 core/src/main/java/cucumber/runtime/AbstractCucumberOptionsProvider.java create mode 100644 core/src/main/java/cucumber/runtime/ConfigurationParser.java delete mode 100644 core/src/main/java/cucumber/runtime/PropertiesFileCucumberOptionsProvider.java create mode 100644 core/src/main/java/cucumber/runtime/configuration/OptionsConfigurationParser.java create mode 100644 core/src/main/java/cucumber/runtime/configuration/YamlConfigurationParser.java delete mode 100644 core/src/test/java/cucumber/runtime/PropertiesFileCucumberOptionsProviderTest.java delete mode 100644 core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderExtraGlue.java delete mode 100644 core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderGlue.java delete mode 100644 core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderNonStrict.java delete mode 100644 core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderStrict.java delete mode 100644 core/src/test/resources/cucumber/runtime/cucumberExtraGlue.properties delete mode 100644 core/src/test/resources/cucumber/runtime/cucumberMultipleFeaturePaths.properties delete mode 100644 core/src/test/resources/cucumber/runtime/cucumberMultipleGlue.properties delete mode 100644 core/src/test/resources/cucumber/runtime/cucumberNonStrict.properties delete mode 100644 core/src/test/resources/cucumber/runtime/cucumberSingleFeaturesPath.properties delete mode 100644 core/src/test/resources/cucumber/runtime/cucumberSingleGlue.properties delete mode 100644 core/src/test/resources/cucumber/runtime/cucumberSnippetsCamelCase.properties delete mode 100644 core/src/test/resources/cucumber/runtime/cucumberSnippetsUnderscore.properties delete mode 100644 core/src/test/resources/cucumber/runtime/cucumberStrict.properties diff --git a/core/pom.xml b/core/pom.xml index 039cb6366f..6fe17cced4 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -8,7 +8,6 @@ cucumber-core - 4.0.2-SNAPSHOT jar Cucumber-JVM: Core @@ -34,8 +33,12 @@ datatable - io.leangen.geantyref - geantyref + com.google.code.gson + gson + + + org.yaml + snakeyaml junit diff --git a/core/src/main/java/cucumber/api/CucumberConfiguration.java b/core/src/main/java/cucumber/api/CucumberConfiguration.java new file mode 100644 index 0000000000..e41fff8381 --- /dev/null +++ b/core/src/main/java/cucumber/api/CucumberConfiguration.java @@ -0,0 +1,18 @@ +package cucumber.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface CucumberConfiguration { + Type type() default Type.YAML; + + String path(); + + public enum Type { + YAML, JSON, PROPERTIES, ANNOTATION; + } +} diff --git a/core/src/main/java/cucumber/api/CucumberOptionsProvider.java b/core/src/main/java/cucumber/api/CucumberOptionsProvider.java deleted file mode 100644 index d842d02a70..0000000000 --- a/core/src/main/java/cucumber/api/CucumberOptionsProvider.java +++ /dev/null @@ -1,19 +0,0 @@ -package cucumber.api; - -import cucumber.runtime.AbstractCucumberOptionsProvider; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Define a class extending {@link AbstractCucumberOptionsProvider} which will provide additional - * Cucumber options during runtime. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE}) -public @interface CucumberOptionsProvider { - /** @return the class used to contribute options */ - Class value() default - AbstractCucumberOptionsProvider.class; -} diff --git a/core/src/main/java/cucumber/runtime/AbstractCucumberOptionsProvider.java b/core/src/main/java/cucumber/runtime/AbstractCucumberOptionsProvider.java deleted file mode 100644 index 6788120bd0..0000000000 --- a/core/src/main/java/cucumber/runtime/AbstractCucumberOptionsProvider.java +++ /dev/null @@ -1,35 +0,0 @@ -package cucumber.runtime; - -import cucumber.api.CucumberOptions; -import io.leangen.geantyref.AnnotationFormatException; -import io.leangen.geantyref.TypeFactory; -import java.util.Map; - -/** This class allows dynamically contributing Cucumber options at runtime. */ -public abstract class AbstractCucumberOptionsProvider { - - /** - * This default provider returns an "empty" {@link CucumberOptions} object, i.e. all values are - * set to their default. Override this method to retrieve Cucumber options from any source - * (properties file, database etc.) - * - * @return the {@link CucumberOptions} to use - */ - public abstract CucumberOptions getOptions(); - - /** - * @param options map to hold the cucumber options - * @return an instance of {@link CucumberOptions} based on the values in the options mpa - */ - protected CucumberOptions getCucumberOptions(Map options) { - try { - return TypeFactory.annotation(CucumberOptions.class, options); - } catch (AnnotationFormatException e) { - throw new CucumberException( - String.format( - "Error creating %s from options map %s", - CucumberOptions.class.getName(), options.toString()), - e); - } - } -} diff --git a/core/src/main/java/cucumber/runtime/ConfigurationParser.java b/core/src/main/java/cucumber/runtime/ConfigurationParser.java new file mode 100644 index 0000000000..8924151e40 --- /dev/null +++ b/core/src/main/java/cucumber/runtime/ConfigurationParser.java @@ -0,0 +1,7 @@ +package cucumber.runtime; + +import java.util.Map; + +public interface ConfigurationParser { + public Map getMap(); +} diff --git a/core/src/main/java/cucumber/runtime/PropertiesFileCucumberOptionsProvider.java b/core/src/main/java/cucumber/runtime/PropertiesFileCucumberOptionsProvider.java deleted file mode 100644 index 0eac22c398..0000000000 --- a/core/src/main/java/cucumber/runtime/PropertiesFileCucumberOptionsProvider.java +++ /dev/null @@ -1,75 +0,0 @@ -package cucumber.runtime; - -import cucumber.api.CucumberOptions; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -/** - * Extension of {@link AbstractCucumberOptionsProvider} which will read Cucumber options from a - * properties file. - * - *

All properties with a key matching any of the methods in {@link CucumberOptions} are used to - * create an instance of {@link CucumberOptions}. All other properties are ignored. - * - *

Values which are of type String[] in {@link CucumberOptions} need to be defined as a single - * string separated by {@link cucumber.runtime.PropertiesFileCucumberOptionsProvider.DELIMITER} in - * the properties file. - * - *

The fully qualified path to the properties file can be passed via the `cucumberProperties` - * System property. The default is cucumber.properties in the user.home directory. - */ -public class PropertiesFileCucumberOptionsProvider extends AbstractCucumberOptionsProvider { - - public static final String PROPERTIES_FILE_PATH_KEY = "cucumberProperties"; - public static final String DELIMITER = ","; - private String propertiesPath; - - public PropertiesFileCucumberOptionsProvider() { - this.propertiesPath = - System.getProperty( - PROPERTIES_FILE_PATH_KEY, - System.getProperty("user.home") + File.pathSeparator + "cucumber.properties"); - } - - public CucumberOptions getOptions() { - Properties properties = new Properties(); - try { - properties.load(new FileInputStream(propertiesPath)); - } catch (IOException exception) { - throw new CucumberException("Error loading properties from file", exception); - } - - // create cucumber options from properties - Map options = new HashMap(); - for (Method method : CucumberOptions.class.getDeclaredMethods()) { - addOptionIfPresent(properties, options, method.getName(), method.getReturnType()); - } - return getCucumberOptions(options); - } - - private void addOptionIfPresent( - Properties props, Map options, String key, Class type) { - String value = props.getProperty(key); - // map property value to the appropriate type - if (value != null && !value.isEmpty()) { - if (type.equals(boolean.class)) { - options.put(key, Boolean.parseBoolean(value)); - } else if (type.equals(String[].class)) { - options.put(key, value.split(DELIMITER)); - } else if (type instanceof Class && ((Class) type).isEnum()) { - // TODO: this is not ideal as we make the assumption that the value of the enum matches its name (except case). - options.put(key, Enum.valueOf((Class) type, value.toUpperCase())); - } else { - throw new UnsupportedOperationException( - String.format( - "%s doesn't support mapping to type %f. Only boolean and String[] are supported.", - this.getClass().getName(), type.getClass().getName())); - } - } - } -} diff --git a/core/src/main/java/cucumber/runtime/RuntimeOptions.java b/core/src/main/java/cucumber/runtime/RuntimeOptions.java index 8161ec1cf6..0e6b59ac65 100644 --- a/core/src/main/java/cucumber/runtime/RuntimeOptions.java +++ b/core/src/main/java/cucumber/runtime/RuntimeOptions.java @@ -1,402 +1,370 @@ package cucumber.runtime; import cucumber.api.SnippetType; -import io.cucumber.datatable.DataTable; +import cucumber.runtime.configuration.OptionsConfigurationParser; import cucumber.runtime.formatter.PluginFactory; import cucumber.runtime.model.PathWithLines; -import cucumber.util.FixJava; -import cucumber.util.Mapper; -import gherkin.GherkinDialect; -import gherkin.GherkinDialectProvider; -import gherkin.IGherkinDialectProvider; -import io.cucumber.datatable.DataTable; - -import java.io.InputStreamReader; -import java.io.Reader; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ResourceBundle; import java.util.regex.Pattern; -import static cucumber.util.FixJava.join; -import static cucumber.util.FixJava.map; -import static java.util.Arrays.asList; - // 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_RESOURCE = "/cucumber/api/cli/USAGE.txt"; - - static String usageText; - - private static final Mapper QUOTE_MAPPER = new Mapper() { - @Override - public String map(String o) { - return '"' + o + '"'; - } - }; - private static final Mapper CODE_KEYWORD_MAPPER = new Mapper() { - @Override - public String map(String keyword) { - return keyword.replaceAll("[\\s',!]", ""); - } - }; - - private final List glue = new ArrayList(); - private final List tagFilters = new ArrayList(); - private final List nameFilters = new ArrayList(); - private final Map> lineFilters = new HashMap>(); - private final List featurePaths = new ArrayList(); - - private final List junitOptions = new ArrayList(); - private boolean dryRun; - private boolean strict = false; - private boolean monochrome = false; - private boolean wip = false; - private SnippetType snippetType = SnippetType.UNDERSCORE; - private int threads = 1; - - private final List pluginFormatterNames = new ArrayList(); - private final List pluginStepDefinitionReporterNames = new ArrayList(); - private final List pluginSummaryPrinterNames = new ArrayList(); - - - /** - * Create a new instance from a string of options, for example: - *

- * - * - * @param argv the arguments - */ - public RuntimeOptions(String argv) { - this(Shellwords.parse(argv)); - } - - /** - * Create a new instance from a list of options, for example: - *

- * - * - * @param argv the arguments - */ - public RuntimeOptions(List argv) { - this(Env.INSTANCE, argv); - } - - public RuntimeOptions(Env env, List argv) { - argv = new ArrayList(argv); // in case the one passed in is unmodifiable. - parse(argv); - - String cucumberOptionsFromEnv = env.get("cucumber.options"); - if (cucumberOptionsFromEnv != null) { - parse(Shellwords.parse(cucumberOptionsFromEnv)); - } - - if (pluginFormatterNames.isEmpty()) { - pluginFormatterNames.add("progress"); - } - if (pluginSummaryPrinterNames.isEmpty()) { - pluginSummaryPrinterNames.add("default_summary"); - } + public static final String VERSION = + ResourceBundle.getBundle("cucumber.version").getString("cucumber-jvm.version"); + public static final String USAGE_RESOURCE = "/cucumber/api/cli/USAGE.txt"; + + static String usageText; + + private final List glue = new ArrayList(); + private final List tagFilters = new ArrayList(); + private final List nameFilters = new ArrayList(); + private final Map> lineFilters = new HashMap>(); + private final List featurePaths = new ArrayList(); + + private final List junitOptions = new ArrayList(); + private boolean dryRun; + private boolean strict = false; + private boolean monochrome = false; + private boolean wip = false; + private SnippetType snippetType = SnippetType.UNDERSCORE; + private int threads = 1; + + private final List pluginFormatterNames = new ArrayList(); + private final List pluginStepDefinitionReporterNames = new ArrayList(); + private final List pluginSummaryPrinterNames = new ArrayList(); + + + /** + * Create a new instance from a string of options, for example: + *

+ * + * + * @param argv the arguments + */ + public RuntimeOptions(String argv) { + this(Shellwords.parse(argv)); + } + + public RuntimeOptions(Map map) { + parse(map); + } + + /** + * Create a new instance from a list of options, for example: + *

+ * + * + * @param argv the arguments + */ + public RuntimeOptions(List argv) { + this(Env.INSTANCE, argv); + } + + public RuntimeOptions(Env env, List argv) { + argv = new ArrayList(argv); // in case the one passed in is unmodifiable. + parse(new OptionsConfigurationParser(argv).getMap()); + + String cucumberOptionsFromEnv = env.get("cucumber.options"); + if (cucumberOptionsFromEnv != null) { + parse(new OptionsConfigurationParser(Shellwords.parse(cucumberOptionsFromEnv)).getMap()); } - public boolean isMultiThreaded() { - return threads > 1; + if (pluginFormatterNames.isEmpty()) { + pluginFormatterNames.add("progress"); } - - public RuntimeOptions noSummaryPrinter() { - pluginSummaryPrinterNames.clear(); - return this; - } - - public List getPluginFormatterNames() { - return pluginFormatterNames; - } - - public List getPluginSummaryPrinterNames() { - return pluginSummaryPrinterNames; - } - - public List getPluginStepDefinitionReporterNames() { - return pluginStepDefinitionReporterNames; + if (pluginSummaryPrinterNames.isEmpty()) { + pluginSummaryPrinterNames.add("default_summary"); } - - private void parse(List args) { - List parsedTagFilters = new ArrayList(); - List parsedNameFilters = new ArrayList(); - Map> parsedLineFilters = new HashMap>(); - List parsedFeaturePaths = new ArrayList(); - List parsedGlue = new ArrayList(); - ParsedPluginData parsedPluginData = new ParsedPluginData(); - List parsedJunitOptions = new ArrayList(); - - while (!args.isEmpty()) { - String arg = args.remove(0).trim(); - - if (arg.equals("--help") || arg.equals("-h")) { - printUsage(); - System.exit(0); - } else if (arg.equals("--version") || arg.equals("-v")) { - System.out.println(VERSION); - System.exit(0); - } else if (arg.equals("--i18n")) { - String nextArg = args.remove(0); - System.exit(printI18n(nextArg)); - } else if (arg.equals("--threads")) { - String threads = args.remove(0); - this.threads = Integer.parseInt(threads); - if (this.threads < 1) { - throw new CucumberException("--threads must be > 0"); - } - } else if (arg.equals("--glue") || arg.equals("-g")) { - String gluePath = args.remove(0); - parsedGlue.add(gluePath); - } else if (arg.equals("--tags") || arg.equals("-t")) { - parsedTagFilters.add(args.remove(0)); - } else if (arg.equals("--plugin") || arg.equals("--add-plugin") || arg.equals("-p")) { - parsedPluginData.addPluginName(args.remove(0), arg.equals("--add-plugin")); - } else if (arg.equals("--no-dry-run") || arg.equals("--dry-run") || arg.equals("-d")) { - dryRun = !arg.startsWith("--no-"); - } else if (arg.equals("--no-strict") || arg.equals("--strict") || arg.equals("-s")) { - strict = !arg.startsWith("--no-"); - } else if (arg.equals("--no-monochrome") || arg.equals("--monochrome") || arg.equals("-m")) { - monochrome = !arg.startsWith("--no-"); - } else if (arg.equals("--snippets")) { - String nextArg = args.remove(0); - snippetType = SnippetType.fromString(nextArg); - } else if (arg.equals("--name") || arg.equals("-n")) { - String nextArg = args.remove(0); - Pattern patternFilter = Pattern.compile(nextArg); - parsedNameFilters.add(patternFilter); - } else if (arg.startsWith("--junit,")) { - parsedJunitOptions.addAll(asList(arg.substring("--junit,".length()).split(","))); - } else if (arg.equals("--wip") || arg.equals("-w")) { - wip = true; - } else if (arg.startsWith("-")) { - printUsage(); - throw new CucumberException("Unknown option: " + arg); - } else { - PathWithLines pathWithLines = new PathWithLines(arg); - parsedFeaturePaths.add(pathWithLines.path); - if (!pathWithLines.lines.isEmpty()) { - String key = pathWithLines.path.replace("classpath:", ""); - addLineFilters(parsedLineFilters, key, pathWithLines.lines); - } - } - } - if (!parsedTagFilters.isEmpty() || !parsedNameFilters.isEmpty() || !parsedLineFilters.isEmpty() || haveLineFilters(parsedFeaturePaths)) { - tagFilters.clear(); - tagFilters.addAll(parsedTagFilters); - nameFilters.clear(); - nameFilters.addAll(parsedNameFilters); - lineFilters.clear(); - for (String path : parsedLineFilters.keySet()) { - lineFilters.put(path, parsedLineFilters.get(path)); - } + } + + public boolean isMultiThreaded() { + return threads > 1; + } + + public RuntimeOptions noSummaryPrinter() { + pluginSummaryPrinterNames.clear(); + return this; + } + + public List getPluginFormatterNames() { + return pluginFormatterNames; + } + + public List getPluginSummaryPrinterNames() { + return pluginSummaryPrinterNames; + } + + public List getPluginStepDefinitionReporterNames() { + return pluginStepDefinitionReporterNames; + } + + private List getList(Map map, String key, Class clazz) { + Object object = getValue(map, key, Object.class); + List list = null; + if (object != null) { + if (object instanceof List) { + list = (List) object; + } else { // single element + list = new ArrayList(); + if (!clazz.isAssignableFrom(object.getClass())) { + throw new IllegalArgumentException(String.format( + "Parameter %s is not of expected type %s", object, clazz.getName())); } - if (!parsedFeaturePaths.isEmpty()) { - featurePaths.clear(); - featurePaths.addAll(parsedFeaturePaths); - } - - if (!parsedGlue.isEmpty()) { - glue.clear(); - glue.addAll(parsedGlue); + list.add((T) object); + } + for (Object element : list) { + if (!clazz.isAssignableFrom(element.getClass())) { + throw new IllegalArgumentException(String.format( + "Parameter %s is not of expected type %s", element, clazz.getName())); } - if (!parsedJunitOptions.isEmpty()) { - junitOptions.clear(); - junitOptions.addAll(parsedJunitOptions); - } - - parsedPluginData.updatePluginFormatterNames(pluginFormatterNames); - parsedPluginData.updatePluginStepDefinitionReporterNames(pluginStepDefinitionReporterNames); - parsedPluginData.updatePluginSummaryPrinterNames(pluginSummaryPrinterNames); + } } - - private void addLineFilters(Map> parsedLineFilters, String key, List lines) { - if (parsedLineFilters.containsKey(key)) { - parsedLineFilters.get(key).addAll(lines); - } else { - parsedLineFilters.put(key, lines); - } + if (list == null) { + list = Collections.emptyList(); } - - private boolean haveLineFilters(List parsedFeaturePaths) { - for (String pathName : parsedFeaturePaths) { - if (pathName.startsWith("@") || PathWithLines.hasLineFilters(pathName)) { - return true; - } - } - return false; + return (List) list; + } + + private List getList(Map map, String key) { + return getList(map, key, String.class); + } + + private T getValue(Map map, String key, Class clazz) { + try { + return clazz.cast(map.get(key)); + } catch (ClassCastException exception) { + throw new IllegalArgumentException(String.format("Parameter %s is not of expected type %s", + key, clazz.getName())); } - - private void printUsage() { - loadUsageTextIfNeeded(); - System.out.println(usageText); - } - - static void loadUsageTextIfNeeded() { - if (usageText == null) { - try { - Reader reader = new InputStreamReader(FixJava.class.getResourceAsStream(USAGE_RESOURCE), "UTF-8"); - usageText = FixJava.readReader(reader); - } catch (Exception e) { - usageText = "Could not load usage text: " + e.toString(); - } - } + } + + private String getValue(Map map, String key) { + return getValue(map, key, String.class); + } + + private int getInt(Map map, String key, int defaultValue) { + Integer intValue = getValue(map, key, Integer.class); + return (intValue != null) ? intValue : defaultValue; + } + + private boolean getBoolean(Map map, String key, boolean defaultValue) { + Boolean booleanValue = getValue(map, key, Boolean.class); + return (booleanValue != null) ? booleanValue : defaultValue; + } + + private void parse(Map map) { + List parsedNameFilters = new ArrayList(); + Map> parsedLineFilters = new HashMap>(); + List parsedFeaturePaths = new ArrayList(); + List parsedJunitOptions = new ArrayList(); + + // thread + this.threads = getInt(map, "threads", 1); + if (this.threads < 1) { + throw new CucumberException("--threads must be > 0"); } - private int printI18n(String language) { - IGherkinDialectProvider dialectProvider = new GherkinDialectProvider(); - List languages = dialectProvider.getLanguages(); + // glue + List parsedGlue = getList(map, "glue"); - if (language.equalsIgnoreCase("help")) { - for (String code : languages) { - System.out.println(code); - } - return 0; - } - if (languages.contains(language)) { - return printKeywordsFor(dialectProvider.getDialect(language, null)); - } + // tags + List parsedTagFilters = getList(map, "tags"); - System.err.println("Unrecognised ISO language code"); - return 1; + // plugins + ParsedPluginData parsedPluginData = new ParsedPluginData(); + for (String plugin : getList(map, "plugins")) { + parsedPluginData.addPluginName(plugin, true); } - private int printKeywordsFor(GherkinDialect dialect) { - StringBuilder builder = new StringBuilder(); - List> table = new ArrayList>(); - addKeywordRow(table, "feature", dialect.getFeatureKeywords()); - addKeywordRow(table, "background", dialect.getBackgroundKeywords()); - addKeywordRow(table, "scenario", dialect.getScenarioKeywords()); - addKeywordRow(table, "scenario outline", dialect.getScenarioOutlineKeywords()); - addKeywordRow(table, "examples", dialect.getExamplesKeywords()); - addKeywordRow(table, "given", dialect.getGivenKeywords()); - addKeywordRow(table, "when", dialect.getWhenKeywords()); - addKeywordRow(table, "then", dialect.getThenKeywords()); - addKeywordRow(table, "and", dialect.getAndKeywords()); - addKeywordRow(table, "but", dialect.getButKeywords()); - addCodeKeywordRow(table, "given", dialect.getGivenKeywords()); - addCodeKeywordRow(table, "when", dialect.getWhenKeywords()); - addCodeKeywordRow(table, "then", dialect.getThenKeywords()); - addCodeKeywordRow(table, "and", dialect.getAndKeywords()); - addCodeKeywordRow(table, "but", dialect.getButKeywords()); - DataTable.create(table).print(builder); - System.out.println(builder.toString()); - return 0; - } + // dry-run + dryRun = getBoolean(map, "dryRun", false); - private void addCodeKeywordRow(List> table, String key, List keywords) { - List codeKeywordList = new ArrayList(keywords); - codeKeywordList.remove("* "); - addKeywordRow(table, key + " (code)", map(codeKeywordList, CODE_KEYWORD_MAPPER)); - } + // strict + strict = getBoolean(map, "strict", false); - private void addKeywordRow(List> table, String key, List keywords) { - List cells = asList(key, join(map(keywords, QUOTE_MAPPER), ", ")); - table.add(cells); - } + // monochrome + monochrome = getBoolean(map, "monochrome", false); - public List getGlue() { - return glue; - } + // snippets + String snippets = getValue(map, "snippets"); + snippetType = (snippets != null) ? SnippetType.fromString(snippets) : SnippetType.CAMELCASE; - public boolean isStrict() { - return strict; + // name + List names = getList(map, "name"); + for (String pattern : names) { + Pattern patternFilter = Pattern.compile(pattern); + parsedNameFilters.add(patternFilter); } - public boolean isDryRun() { - return dryRun; - } - - public boolean isWip() { - return wip; + // junit + parsedJunitOptions = getList(map, "junit"); + + // wip + wip = getBoolean(map, "wip", false); + + // features + String features = getValue(map, "features"); + if (features != null && !features.isEmpty()) { + PathWithLines pathWithLines = new PathWithLines(getValue(map, "features")); + parsedFeaturePaths.add(pathWithLines.path); + if (!pathWithLines.lines.isEmpty()) { + String key = pathWithLines.path.replace("classpath:", ""); + addLineFilters(parsedLineFilters, key, pathWithLines.lines); + } + if (!parsedTagFilters.isEmpty() || !parsedNameFilters.isEmpty() + || !parsedLineFilters.isEmpty() || haveLineFilters(parsedFeaturePaths)) { + tagFilters.clear(); + tagFilters.addAll(parsedTagFilters); + nameFilters.clear(); + nameFilters.addAll(parsedNameFilters); + lineFilters.clear(); + for (String path : parsedLineFilters.keySet()) { + lineFilters.put(path, parsedLineFilters.get(path)); + } + } + if (!parsedFeaturePaths.isEmpty()) { + featurePaths.clear(); + featurePaths.addAll(parsedFeaturePaths); + } } - public List getFeaturePaths() { - return featurePaths; + if (!parsedGlue.isEmpty()) { + glue.clear(); + glue.addAll(parsedGlue); } - - public List getNameFilters() { - return nameFilters; + if (!parsedJunitOptions.isEmpty()) { + junitOptions.clear(); + junitOptions.addAll(parsedJunitOptions); } - public List getTagFilters() { - return tagFilters; + parsedPluginData.updatePluginFormatterNames(pluginFormatterNames); + parsedPluginData.updatePluginStepDefinitionReporterNames(pluginStepDefinitionReporterNames); + parsedPluginData.updatePluginSummaryPrinterNames(pluginSummaryPrinterNames); + } + + private void addLineFilters(Map> parsedLineFilters, String key, + List lines) { + if (parsedLineFilters.containsKey(key)) { + parsedLineFilters.get(key).addAll(lines); + } else { + parsedLineFilters.put(key, lines); } + } - public Map> getLineFilters() { - return lineFilters; + private boolean haveLineFilters(List parsedFeaturePaths) { + for (String pathName : parsedFeaturePaths) { + if (pathName.startsWith("@") || PathWithLines.hasLineFilters(pathName)) { + return true; + } } - - public boolean isMonochrome() { - return monochrome; + return false; + } + + public List getGlue() { + return glue; + } + + public boolean isStrict() { + return strict; + } + + public boolean isDryRun() { + return dryRun; + } + + public boolean isWip() { + return wip; + } + + public List getFeaturePaths() { + return featurePaths; + } + + public List getNameFilters() { + return nameFilters; + } + + public List getTagFilters() { + return tagFilters; + } + + public Map> getLineFilters() { + return lineFilters; + } + + public boolean isMonochrome() { + return monochrome; + } + + public SnippetType getSnippetType() { + return snippetType; + } + + public List getJunitOptions() { + return junitOptions; + } + + public int getThreads() { + return threads; + } + + class ParsedPluginData { + ParsedOptionNames formatterNames = new ParsedOptionNames(); + ParsedOptionNames stepDefinitionReporterNames = new ParsedOptionNames(); + ParsedOptionNames summaryPrinterNames = new ParsedOptionNames(); + + public void addPluginName(String name, boolean isAddPlugin) { + if (PluginFactory.isStepDefinitionReporterName(name)) { + stepDefinitionReporterNames.addName(name, isAddPlugin); + } else if (PluginFactory.isSummaryPrinterName(name)) { + summaryPrinterNames.addName(name, isAddPlugin); + } else if (PluginFactory.isFormatterName(name)) { + formatterNames.addName(name, isAddPlugin); + } else { + throw new CucumberException("Unrecognized plugin: " + name); + } } - public SnippetType getSnippetType() { - return snippetType; + public void updatePluginFormatterNames(List pluginFormatterNames) { + formatterNames.updateNameList(pluginFormatterNames); } - public List getJunitOptions() { - return junitOptions; + public void updatePluginStepDefinitionReporterNames( + List pluginStepDefinitionReporterNames) { + stepDefinitionReporterNames.updateNameList(pluginStepDefinitionReporterNames); } - public int getThreads() { - return threads; + public void updatePluginSummaryPrinterNames(List pluginSummaryPrinterNames) { + summaryPrinterNames.updateNameList(pluginSummaryPrinterNames); } + } - class ParsedPluginData { - ParsedOptionNames formatterNames = new ParsedOptionNames(); - ParsedOptionNames stepDefinitionReporterNames = new ParsedOptionNames(); - ParsedOptionNames summaryPrinterNames = new ParsedOptionNames(); - - public void addPluginName(String name, boolean isAddPlugin) { - if (PluginFactory.isStepDefinitionReporterName(name)) { - stepDefinitionReporterNames.addName(name, isAddPlugin); - } else if (PluginFactory.isSummaryPrinterName(name)) { - summaryPrinterNames.addName(name, isAddPlugin); - } else if (PluginFactory.isFormatterName(name)) { - formatterNames.addName(name, isAddPlugin); - } else { - throw new CucumberException("Unrecognized plugin: " + name); - } - } - - public void updatePluginFormatterNames(List pluginFormatterNames) { - formatterNames.updateNameList(pluginFormatterNames); - } + class ParsedOptionNames { + private List names = new ArrayList(); + private boolean clobber = false; - public void updatePluginStepDefinitionReporterNames(List pluginStepDefinitionReporterNames) { - stepDefinitionReporterNames.updateNameList(pluginStepDefinitionReporterNames); - } - - public void updatePluginSummaryPrinterNames(List pluginSummaryPrinterNames) { - summaryPrinterNames.updateNameList(pluginSummaryPrinterNames); - } + public void addName(String name, boolean isAddOption) { + names.add(name); + if (!isAddOption) { + clobber = true; + } } - class ParsedOptionNames { - private List names = new ArrayList(); - private boolean clobber = false; - - public void addName(String name, boolean isAddOption) { - names.add(name); - if (!isAddOption) { - clobber = true; - } - } - - public void updateNameList(List nameList) { - if (!names.isEmpty()) { - if (clobber) { - nameList.clear(); - } - nameList.addAll(names); - } + public void updateNameList(List nameList) { + if (!names.isEmpty()) { + if (clobber) { + nameList.clear(); } + nameList.addAll(names); + } } + } } diff --git a/core/src/main/java/cucumber/runtime/RuntimeOptionsFactory.java b/core/src/main/java/cucumber/runtime/RuntimeOptionsFactory.java index 9c73b7c0cc..7aa6420c42 100644 --- a/core/src/main/java/cucumber/runtime/RuntimeOptionsFactory.java +++ b/core/src/main/java/cucumber/runtime/RuntimeOptionsFactory.java @@ -1,75 +1,112 @@ package cucumber.runtime; import static java.util.Arrays.asList; +import cucumber.api.CucumberConfiguration; +import cucumber.api.CucumberConfiguration.Type; import cucumber.api.CucumberOptions; -import cucumber.api.CucumberOptionsProvider; +import cucumber.runtime.configuration.YamlConfigurationParser; import cucumber.runtime.io.MultiLoader; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class RuntimeOptionsFactory { - private final Class clazz; - private boolean featuresSpecified = false; - private boolean overridingGlueSpecified = false; - - public RuntimeOptionsFactory(Class clazz) { - this.clazz = clazz; - } - - public RuntimeOptions create() { - List args = buildArgsFromOptions(); - return new RuntimeOptions(args); - } - - private List buildArgsFromOptions() { - List args = new ArrayList(); - - for (Class classWithOptions = clazz; hasSuperClass(classWithOptions); classWithOptions = classWithOptions.getSuperclass()) { - CucumberOptions options = getOptions(classWithOptions); - AbstractCucumberOptionsProvider optionsProvider = getOptionsProvider(classWithOptions); - if (optionsProvider != null) - { - contributeOptions(optionsProvider.getOptions(), args); - } - if (options != null) { - addDryRun(options, args); - addMonochrome(options, args); - addTags(options, args); - addPlugins(options, args); - addStrict(options, args); - addName(options, args); - addSnippets(options, args); - addGlue(options, args); - addFeatures(options, args); - addJunitOptions(options, args); - } - } - addDefaultFeaturePathIfNoFeaturePathIsSpecified(args, clazz); - addDefaultGlueIfNoOverridingGlueIsSpecified(args, clazz); - return args; - } + private static final String FILE_PREFIX = "file:"; + private static final String CLASSPATH_PREFIX = "classpath:"; + private final Class clazz; + private boolean featuresSpecified = false; + private boolean overridingGlueSpecified = false; + + public RuntimeOptionsFactory(Class clazz) { + this.clazz = clazz; + } + + public RuntimeOptions create() { + CucumberConfiguration configuration = clazz.getAnnotation(CucumberConfiguration.class); - private AbstractCucumberOptionsProvider getOptionsProvider(Class clazz) { - CucumberOptionsProvider optionsProvider = clazz.getAnnotation(CucumberOptionsProvider.class); - if (optionsProvider == null || Modifier.isAbstract(optionsProvider.value().getModifiers())) { - return null; + // TODO: evaluate annotations on super classes + if (configuration == null || configuration.type().equals(Type.ANNOTATION)) { + return new RuntimeOptions(buildArgsFromOptions()); } + Reader configurationReader = null; try { - return optionsProvider.value().getDeclaredConstructor().newInstance(); - } catch (InstantiationException - | IllegalAccessException - | IllegalArgumentException - | InvocationTargetException - | NoSuchMethodException - | SecurityException e) { - throw new CucumberException( - String.format("Error instantiating options provider %s", optionsProvider.value()), e); + configurationReader = getConfigurationReader(configuration.path()); + switch (configuration.type()) { + case YAML: + ConfigurationParser configurationParser = + new YamlConfigurationParser(configurationReader); + return new RuntimeOptions(configurationParser.getMap()); + + case JSON: + throw new UnsupportedOperationException("JSON configuration is not yet supported"); + + case PROPERTIES: + throw new UnsupportedOperationException("Properties configuration is not yet supported"); + + default: + return new RuntimeOptions(buildArgsFromOptions()); + } + } finally { + if (configurationReader != null) { + try { + configurationReader.close(); + } catch (IOException e) { + // too bad + } + } } } + private Reader getConfigurationReader(String path) { + if (path.startsWith(FILE_PREFIX)) { + try { + return new FileReader(path.replaceFirst("^" + FILE_PREFIX, "")); + } catch (FileNotFoundException e) { + throw new IllegalArgumentException( + String.format("CucumberConfiguration file %s missing!", path)); + } + } else { + InputStream inputStream = + getClass().getResourceAsStream(path.replaceFirst("^" + CLASSPATH_PREFIX, "")); + + if (inputStream == null) { + throw new IllegalArgumentException( + String.format("CucumberConfiguration file %s not found on classpath!", path)); + } + return new InputStreamReader(inputStream); + } + } + + private List buildArgsFromOptions() { + List args = new ArrayList(); + + for (Class classWithOptions = clazz; hasSuperClass(classWithOptions); classWithOptions = + classWithOptions.getSuperclass()) { + CucumberOptions options = getOptions(classWithOptions); + if (options != null) { + addDryRun(options, args); + addMonochrome(options, args); + addTags(options, args); + addPlugins(options, args); + addStrict(options, args); + addName(options, args); + addSnippets(options, args); + addGlue(options, args); + addFeatures(options, args); + addJunitOptions(options, args); + } + } + addDefaultFeaturePathIfNoFeaturePathIsSpecified(args, clazz); + addDefaultGlueIfNoOverridingGlueIsSpecified(args, clazz); + return args; + } + private void contributeOptions(CucumberOptions options, List args) { addName(options, args); addSnippets(options, args); @@ -83,125 +120,125 @@ private void contributeOptions(CucumberOptions options, List args) { addJunitOptions(options, args); } - private void addName(CucumberOptions options, List args) { - for (String name : options.name()) { - args.add("--name"); - args.add(name); - } + private void addName(CucumberOptions options, List args) { + for (String name : options.name()) { + args.add("--name"); + args.add(name); } + } - private void addSnippets(CucumberOptions options, List args) { - args.add("--snippets"); - args.add(options.snippets().toString()); - } + private void addSnippets(CucumberOptions options, List args) { + args.add("--snippets"); + args.add(options.snippets().toString()); + } - private void addDryRun(CucumberOptions options, List args) { - if (options.dryRun()) { - args.add("--dry-run"); - } + private void addDryRun(CucumberOptions options, List args) { + if (options.dryRun()) { + args.add("--dry-run"); } + } - private void addMonochrome(CucumberOptions options, List args) { - if (options.monochrome() || runningInEnvironmentWithoutAnsiSupport()) { - args.add("--monochrome"); - } + private void addMonochrome(CucumberOptions options, List args) { + if (options.monochrome() || runningInEnvironmentWithoutAnsiSupport()) { + args.add("--monochrome"); } + } - private void addTags(CucumberOptions options, List args) { - for (String tags : options.tags()) { - args.add("--tags"); - args.add(tags); - } + private void addTags(CucumberOptions options, List args) { + for (String tags : options.tags()) { + args.add("--tags"); + args.add(tags); } + } - private void addPlugins(CucumberOptions options, List args) { - List plugins = new ArrayList<>(); - plugins.addAll(asList(options.plugin())); - for (String plugin : plugins) { - args.add("--plugin"); - args.add(plugin); - } + private void addPlugins(CucumberOptions options, List args) { + List plugins = new ArrayList<>(); + plugins.addAll(asList(options.plugin())); + for (String plugin : plugins) { + args.add("--plugin"); + args.add(plugin); } + } - private void addFeatures(CucumberOptions options, List args) { - if (options != null && options.features().length != 0) { - Collections.addAll(args, options.features()); - featuresSpecified = true; - } + private void addFeatures(CucumberOptions options, List args) { + if (options != null && options.features().length != 0) { + Collections.addAll(args, options.features()); + featuresSpecified = true; } + } - private void addDefaultFeaturePathIfNoFeaturePathIsSpecified(List args, Class clazz) { - if (!featuresSpecified) { - args.add(MultiLoader.CLASSPATH_SCHEME + packagePath(clazz)); - } + private void addDefaultFeaturePathIfNoFeaturePathIsSpecified(List args, Class clazz) { + if (!featuresSpecified) { + args.add(MultiLoader.CLASSPATH_SCHEME + packagePath(clazz)); } + } - private void addGlue(CucumberOptions options, List args) { - boolean hasExtraGlue = options.extraGlue().length > 0; - boolean hasGlue = options.glue().length > 0; + private void addGlue(CucumberOptions options, List args) { + boolean hasExtraGlue = options.extraGlue().length > 0; + boolean hasGlue = options.glue().length > 0; - if (hasExtraGlue && hasGlue) { - throw new CucumberException("glue and extraGlue cannot be specified at the same time"); - } + if (hasExtraGlue && hasGlue) { + throw new CucumberException("glue and extraGlue cannot be specified at the same time"); + } - String[] gluePaths = {}; - if (hasExtraGlue) { - gluePaths = options.extraGlue(); - } - if (hasGlue) { - gluePaths = options.glue(); - overridingGlueSpecified = true; - } + String[] gluePaths = {}; + if (hasExtraGlue) { + gluePaths = options.extraGlue(); + } + if (hasGlue) { + gluePaths = options.glue(); + overridingGlueSpecified = true; + } - for (String glue : gluePaths) { - args.add("--glue"); - args.add(glue); - } + for (String glue : gluePaths) { + args.add("--glue"); + args.add(glue); } + } - private void addDefaultGlueIfNoOverridingGlueIsSpecified(List args, Class clazz) { - if (!overridingGlueSpecified) { - args.add("--glue"); - args.add(MultiLoader.CLASSPATH_SCHEME + packagePath(clazz)); - } + private void addDefaultGlueIfNoOverridingGlueIsSpecified(List args, Class clazz) { + if (!overridingGlueSpecified) { + args.add("--glue"); + args.add(MultiLoader.CLASSPATH_SCHEME + packagePath(clazz)); } + } - private void addStrict(CucumberOptions options, List args) { - if (options.strict()) { - args.add("--strict"); - } + private void addStrict(CucumberOptions options, List args) { + if (options.strict()) { + args.add("--strict"); } + } - private void addJunitOptions(CucumberOptions options, List args) { - for (String junitOption : options.junit()) { - args.add("--junit," + junitOption); - } + private void addJunitOptions(CucumberOptions options, List args) { + for (String junitOption : options.junit()) { + args.add("--junit," + junitOption); } + } - static String packagePath(Class clazz) { - return packagePath(packageName(clazz.getName())); - } + static String packagePath(Class clazz) { + return packagePath(packageName(clazz.getName())); + } - static String packagePath(String packageName) { - return packageName.replace('.', '/'); - } + static String packagePath(String packageName) { + return packageName.replace('.', '/'); + } - static String packageName(String className) { - return className.substring(0, Math.max(0, className.lastIndexOf("."))); - } + static String packageName(String className) { + return className.substring(0, Math.max(0, className.lastIndexOf("."))); + } - private boolean runningInEnvironmentWithoutAnsiSupport() { - boolean intelliJidea = System.getProperty("idea.launcher.bin.path") != null; - // TODO: What does Eclipse use? - return intelliJidea; - } + private boolean runningInEnvironmentWithoutAnsiSupport() { + boolean intelliJidea = System.getProperty("idea.launcher.bin.path") != null; + // TODO: What does Eclipse use? + return intelliJidea; + } - private boolean hasSuperClass(Class classWithOptions) { - return classWithOptions != Object.class; - } + private boolean hasSuperClass(Class classWithOptions) { + return classWithOptions != Object.class; + } - private CucumberOptions getOptions(Class clazz) { - return clazz.getAnnotation(CucumberOptions.class); - } + private CucumberOptions getOptions(Class clazz) { + return clazz.getAnnotation(CucumberOptions.class); + } } diff --git a/core/src/main/java/cucumber/runtime/configuration/OptionsConfigurationParser.java b/core/src/main/java/cucumber/runtime/configuration/OptionsConfigurationParser.java new file mode 100644 index 0000000000..39edb82602 --- /dev/null +++ b/core/src/main/java/cucumber/runtime/configuration/OptionsConfigurationParser.java @@ -0,0 +1,65 @@ +package cucumber.runtime.configuration; + +import static java.util.Arrays.asList; +import cucumber.runtime.ConfigurationParser; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OptionsConfigurationParser implements ConfigurationParser { + + List args; + + public OptionsConfigurationParser(List args) { + this.args = args; + } + + @Override + public Map getMap() { + Map map = new HashMap(); + while (!args.isEmpty()) { + String arg = args.remove(0).trim(); + + if (arg.equals("--threads")) { + String threads = args.remove(0); + map.put("threads", Integer.valueOf(threads)); + } else if (arg.equals("--glue") || arg.equals("-g")) { + addToList(map, "glue", args.remove(0)); + } else if (arg.equals("--tags") || arg.equals("-t")) { + addToList(map, "tags", args.remove(0)); + } else if (arg.equals("--plugin") || arg.equals("--add-plugin") || arg.equals("-p")) { + addToList(map, "plugins", args.remove(0)); + } else if (arg.equals("--no-dry-run") || arg.equals("--dry-run") || arg.equals("-d")) { + map.put("dryRun", !arg.startsWith("--no-")); + } else if (arg.equals("--no-strict") || arg.equals("--strict") || arg.equals("-s")) { + map.put("strict", !arg.startsWith("--no-")); + } else if (arg.equals("--no-monochrome") || arg.equals("--monochrome") || arg.equals("-m")) { + map.put("monochrome", !arg.startsWith("--no-")); + } else if (arg.equals("--snippets")) { + map.put("snippets", args.remove(0)); + } else if (arg.equals("--name") || arg.equals("-n")) { + map.put("name", args.remove(0)); + } else if (arg.startsWith("--junit,")) { + for (String junit : arg.substring("--junit,".length()).split(",")) { + addToList(map, "junit", junit); + } + } else if (arg.equals("--wip") || arg.equals("-w")) { + map.put("wip", true); + } else { + map.put("features", arg); + } + } + return map; + } + + private void addToList(Map map, String key, String value) { + // TODO: add some checks + List list = (List)map.get(key); + if (list == null) { + list = new ArrayList(); + } + list.add(value); + map.put(key, list); + } +} diff --git a/core/src/main/java/cucumber/runtime/configuration/YamlConfigurationParser.java b/core/src/main/java/cucumber/runtime/configuration/YamlConfigurationParser.java new file mode 100644 index 0000000000..9b135fda9d --- /dev/null +++ b/core/src/main/java/cucumber/runtime/configuration/YamlConfigurationParser.java @@ -0,0 +1,21 @@ +package cucumber.runtime.configuration; + +import cucumber.runtime.ConfigurationParser; +import java.io.Reader; +import java.util.Map; +import org.yaml.snakeyaml.Yaml; + +public class YamlConfigurationParser implements ConfigurationParser { + + private Reader reader; + + public YamlConfigurationParser(Reader reader) { + this.reader = reader; + } + + @Override + public Map getMap() { + return new Yaml().load(reader); + } + +} diff --git a/core/src/test/java/cucumber/runtime/PropertiesFileCucumberOptionsProviderTest.java b/core/src/test/java/cucumber/runtime/PropertiesFileCucumberOptionsProviderTest.java deleted file mode 100644 index c5a919f3b9..0000000000 --- a/core/src/test/java/cucumber/runtime/PropertiesFileCucumberOptionsProviderTest.java +++ /dev/null @@ -1,131 +0,0 @@ -package cucumber.runtime; - -import static org.assertj.core.api.Assertions.assertThat; -import cucumber.api.CucumberOptions; -import cucumber.api.SnippetType; -import org.junit.Test; - -public class PropertiesFileCucumberOptionsProviderTest { - - private PropertiesFileCucumberOptionsProvider target; - - @Test - public void testExtraGlue() { - System.setProperty( - PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, - PropertiesFileCucumberOptionsProviderTest.class - .getResource("cucumberExtraGlue.properties") - .getPath()); - target = new PropertiesFileCucumberOptionsProvider(); - CucumberOptions options = target.getOptions(); - assertThat(options.extraGlue()) - .as("verify glue") - .isEqualTo( - new String[] {"io.github.martinschneider.steps3", "io.github.martinschneider.steps4"}); - } - - @Test - public void testMultipleFeaturePaths() { - System.setProperty( - PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, - PropertiesFileCucumberOptionsProviderTest.class - .getResource("cucumberMultipleFeaturePaths.properties") - .getPath()); - target = new PropertiesFileCucumberOptionsProvider(); - CucumberOptions options = target.getOptions(); - assertThat(options.features()) - .as("verify feature paths") - .isEqualTo(new String[] {"src/test/resources/features1", "src/test/resources/features2"}); - } - - @Test - public void testMultipleGlue() { - System.setProperty( - PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, - PropertiesFileCucumberOptionsProviderTest.class - .getResource("cucumberMultipleGlue.properties") - .getPath()); - target = new PropertiesFileCucumberOptionsProvider(); - CucumberOptions options = target.getOptions(); - assertThat(options.glue()) - .as("verify glue") - .isEqualTo( - new String[] {"io.github.martinschneider.steps1", "io.github.martinschneider.steps2"}); - } - - @Test - public void testSingleFeaturesPath() { - System.setProperty( - PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, - PropertiesFileCucumberOptionsProviderTest.class - .getResource("cucumberSingleFeaturesPath.properties") - .getPath()); - target = new PropertiesFileCucumberOptionsProvider(); - CucumberOptions options = target.getOptions(); - assertThat(options.features()) - .as("verify feature path") - .isEqualTo(new String[] {"src/test/resources/features1"}); - } - - @Test - public void testSingleGlue() { - System.setProperty( - PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, - PropertiesFileCucumberOptionsProviderTest.class - .getResource("cucumberSingleGlue.properties") - .getPath()); - target = new PropertiesFileCucumberOptionsProvider(); - CucumberOptions options = target.getOptions(); - assertThat(options.glue()) - .as("verify feature path") - .isEqualTo(new String[] {"io.github.martinschneider.steps1"}); - } - - @Test - public void testStrict() { - System.setProperty( - PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, - PropertiesFileCucumberOptionsProviderTest.class - .getResource("cucumberStrict.properties") - .getPath()); - target = new PropertiesFileCucumberOptionsProvider(); - CucumberOptions options = target.getOptions(); - assertThat(options.strict()).as("verify strict").isTrue(); - } - - @Test - public void testNonStrict() { - System.setProperty( - PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, - PropertiesFileCucumberOptionsProviderTest.class - .getResource("cucumberNonStrict.properties") - .getPath()); - target = new PropertiesFileCucumberOptionsProvider(); - CucumberOptions options = target.getOptions(); - assertThat(options.strict()).as("verify strict").isFalse(); - } - - @Test - public void testSnippetsUnderscore() { - System.setProperty( - PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, - PropertiesFileCucumberOptionsProviderTest.class - .getResource("cucumberSnippetsUnderscore.properties") - .getPath()); - target = new PropertiesFileCucumberOptionsProvider(); - CucumberOptions options = target.getOptions(); - assertThat(options.snippets()).as("verify snippet").isEqualTo(SnippetType.UNDERSCORE); - } - - @Test - public void testSnippetsCamelCase() { - System.setProperty( - PropertiesFileCucumberOptionsProvider.PROPERTIES_FILE_PATH_KEY, - PropertiesFileCucumberOptionsProviderTest.class - .getResource("cucumberSnippetsCamelCase.properties") - .getPath()); - target = new PropertiesFileCucumberOptionsProvider(); - CucumberOptions options = target.getOptions(); - assertThat(options.snippets()).as("verify snippet").isEqualTo(SnippetType.CAMELCASE); - } -} diff --git a/core/src/test/java/cucumber/runtime/RuntimeOptionsFactoryTest.java b/core/src/test/java/cucumber/runtime/RuntimeOptionsFactoryTest.java index c9ef82a6d4..f8fab81d36 100644 --- a/core/src/test/java/cucumber/runtime/RuntimeOptionsFactoryTest.java +++ b/core/src/test/java/cucumber/runtime/RuntimeOptionsFactoryTest.java @@ -1,30 +1,24 @@ package cucumber.runtime; +import static cucumber.runtime.RuntimeOptionsFactory.packageName; +import static cucumber.runtime.RuntimeOptionsFactory.packagePath; +import static java.util.Arrays.asList; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import cucumber.api.CucumberOptions; -import cucumber.api.CucumberOptionsProvider; import cucumber.api.Plugin; import cucumber.api.SnippetType; import cucumber.runner.TimeService; import cucumber.runner.TimeServiceEventBus; import cucumber.runtime.formatter.PluginFactory; import cucumber.runtime.formatter.Plugins; -import cucumber.runtime.optionsprovider.CucumberOptionsProviderExtraGlue; -import cucumber.runtime.optionsprovider.CucumberOptionsProviderGlue; -import cucumber.runtime.optionsprovider.CucumberOptionsProviderNonStrict; -import cucumber.runtime.optionsprovider.CucumberOptionsProviderStrict; -import org.junit.Test; import java.util.Iterator; import java.util.List; import java.util.regex.Pattern; - -import static cucumber.runtime.RuntimeOptionsFactory.packageName; -import static cucumber.runtime.RuntimeOptionsFactory.packagePath; -import static java.util.Arrays.asList; -import static org.hamcrest.collection.IsCollectionWithSize.hasSize; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; +import org.junit.Test; public class RuntimeOptionsFactoryTest { @Test @@ -191,35 +185,6 @@ public void cannot_create_with_glue_and_extra_glue() { RuntimeOptionsFactory runtimeOptionsFactory = new RuntimeOptionsFactory(ClassWithGlueAndExtraGlue.class); runtimeOptionsFactory.create(); } - - @Test - public void createOptionsProviderStrict() { - RuntimeOptionsFactory runtimeOptionsFactory = new RuntimeOptionsFactory(ClassWithCucumberOptionsProviderStrict.class); - RuntimeOptions runtimeOptions = runtimeOptionsFactory.create(); - assertTrue(runtimeOptions.isStrict()); - } - - @Test - public void createOptionsProviderNonStrict() { - RuntimeOptionsFactory runtimeOptionsFactory = new RuntimeOptionsFactory(ClassWithCucumberOptionsProviderNonStrict.class); - RuntimeOptions runtimeOptions = runtimeOptionsFactory.create(); - assertFalse(runtimeOptions.isStrict()); - } - - @Test - public void createOptionsProviderWithGlue() { - RuntimeOptionsFactory runtimeOptionsFactory = new RuntimeOptionsFactory(ClassWithCucumberOptionsProviderGlue.class); - RuntimeOptions runtimeOptions = runtimeOptionsFactory.create(); - assertEquals(asList("app.features.user.registration", "app.features.hooks"), runtimeOptions.getGlue()); - } - - @Test - public void createOptionsProviderWithExtraGlue() { - RuntimeOptionsFactory runtimeOptionsFactory = new RuntimeOptionsFactory(ClassWithCucumberOptionsProviderExtraGlue.class); - RuntimeOptions runtimeOptions = runtimeOptionsFactory.create(); - assertEquals(asList("app.features.hooks", "classpath:cucumber/runtime"), runtimeOptions.getGlue()); - } - @CucumberOptions(snippets = SnippetType.CAMELCASE) private static class Snippets { @@ -312,26 +277,4 @@ private static class SubClassWithExtraGlueOfGlue extends ClassWithGlue { private static class ClassWithGlueAndExtraGlue { // empty } - - @CucumberOptionsProvider(CucumberOptionsProviderStrict.class) - private static class ClassWithCucumberOptionsProviderStrict{ - // empty - } - - @CucumberOptionsProvider(CucumberOptionsProviderNonStrict.class) - private static class ClassWithCucumberOptionsProviderNonStrict{ - // empty - } - - @CucumberOptionsProvider(CucumberOptionsProviderGlue.class) - private static class ClassWithCucumberOptionsProviderGlue{ - // empty - } - - @CucumberOptionsProvider(CucumberOptionsProviderExtraGlue.class) - private static class ClassWithCucumberOptionsProviderExtraGlue{ - // empty - } - - } diff --git a/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java b/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java index 4324db7433..3e7f8c2719 100644 --- a/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java +++ b/core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java @@ -37,12 +37,6 @@ public void has_version_from_properties_file() { assertTrue(RuntimeOptions.VERSION.matches("\\d+\\.\\d+\\.\\d+(-SNAPSHOT)?")); } - @Test - public void has_usage() { - RuntimeOptions.loadUsageTextIfNeeded(); - assertTrue(RuntimeOptions.usageText.startsWith("Usage")); - } - @Test public void assigns_feature_paths() { RuntimeOptions options = new RuntimeOptions("--glue somewhere somewhere_else"); diff --git a/core/src/test/java/cucumber/runtime/io/ResourceLoaderTest.java b/core/src/test/java/cucumber/runtime/io/ResourceLoaderTest.java index fa901b802b..79dcf26509 100644 --- a/core/src/test/java/cucumber/runtime/io/ResourceLoaderTest.java +++ b/core/src/test/java/cucumber/runtime/io/ResourceLoaderTest.java @@ -21,7 +21,7 @@ public ResourceLoaderTest() throws UnsupportedEncodingException { @Test public void loads_resources_from_filesystem_dir() { Iterable files = new FileResourceLoader().resources(dir.getAbsolutePath(), ".properties"); - assertEquals(13, toList(files).size()); + assertEquals(4, toList(files).size()); } @Test @@ -34,7 +34,7 @@ public void loads_resource_from_filesystem_file() { @Test public void loads_resources_from_jar_on_classpath() throws IOException { Iterable files = new ClasspathResourceLoader(Thread.currentThread().getContextClassLoader()).resources("cucumber", ".properties"); - assertEquals(13, toList(files).size()); + assertEquals(4, toList(files).size()); } private List toList(Iterable it) { diff --git a/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderExtraGlue.java b/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderExtraGlue.java deleted file mode 100644 index 5b227b0780..0000000000 --- a/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderExtraGlue.java +++ /dev/null @@ -1,17 +0,0 @@ -package cucumber.runtime.optionsprovider; - -import cucumber.api.CucumberOptions; -import cucumber.runtime.AbstractCucumberOptionsProvider; -import java.util.HashMap; -import java.util.Map; - -public class CucumberOptionsProviderExtraGlue extends AbstractCucumberOptionsProvider{ - - @Override - public CucumberOptions getOptions() { - Map options = new HashMap(); - options.put("extraGlue", new String[]{"app.features.hooks"}); - return getCucumberOptions(options); - } - -} diff --git a/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderGlue.java b/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderGlue.java deleted file mode 100644 index 8539685d7b..0000000000 --- a/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderGlue.java +++ /dev/null @@ -1,16 +0,0 @@ -package cucumber.runtime.optionsprovider; - -import cucumber.api.CucumberOptions; -import cucumber.runtime.AbstractCucumberOptionsProvider; -import java.util.HashMap; -import java.util.Map; - -public class CucumberOptionsProviderGlue extends AbstractCucumberOptionsProvider { - - @Override - public CucumberOptions getOptions() { - Map options = new HashMap(); - options.put("glue", new String[] {"app.features.user.registration", "app.features.hooks"}); - return getCucumberOptions(options); - } -} diff --git a/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderNonStrict.java b/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderNonStrict.java deleted file mode 100644 index fe326bebdc..0000000000 --- a/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderNonStrict.java +++ /dev/null @@ -1,17 +0,0 @@ -package cucumber.runtime.optionsprovider; - -import cucumber.api.CucumberOptions; -import cucumber.runtime.AbstractCucumberOptionsProvider; -import java.util.HashMap; -import java.util.Map; - -public class CucumberOptionsProviderNonStrict extends AbstractCucumberOptionsProvider{ - - @Override - public CucumberOptions getOptions() { - Map options = new HashMap(); - options.put("strict", false); - return getCucumberOptions(options); - } - -} diff --git a/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderStrict.java b/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderStrict.java deleted file mode 100644 index 1cc0ed234a..0000000000 --- a/core/src/test/java/cucumber/runtime/optionsprovider/CucumberOptionsProviderStrict.java +++ /dev/null @@ -1,17 +0,0 @@ -package cucumber.runtime.optionsprovider; - -import cucumber.api.CucumberOptions; -import cucumber.runtime.AbstractCucumberOptionsProvider; -import java.util.HashMap; -import java.util.Map; - -public class CucumberOptionsProviderStrict extends AbstractCucumberOptionsProvider{ - - @Override - public CucumberOptions getOptions() { - Map options = new HashMap(); - options.put("strict", true); - return getCucumberOptions(options); - } - -} diff --git a/core/src/test/resources/cucumber/runtime/cucumberExtraGlue.properties b/core/src/test/resources/cucumber/runtime/cucumberExtraGlue.properties deleted file mode 100644 index 7c8fae024d..0000000000 --- a/core/src/test/resources/cucumber/runtime/cucumberExtraGlue.properties +++ /dev/null @@ -1 +0,0 @@ -extraGlue=io.github.martinschneider.steps3,io.github.martinschneider.steps4 \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberMultipleFeaturePaths.properties b/core/src/test/resources/cucumber/runtime/cucumberMultipleFeaturePaths.properties deleted file mode 100644 index 1327d75447..0000000000 --- a/core/src/test/resources/cucumber/runtime/cucumberMultipleFeaturePaths.properties +++ /dev/null @@ -1 +0,0 @@ -features=src/test/resources/features1,src/test/resources/features2 \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberMultipleGlue.properties b/core/src/test/resources/cucumber/runtime/cucumberMultipleGlue.properties deleted file mode 100644 index 543c54dd72..0000000000 --- a/core/src/test/resources/cucumber/runtime/cucumberMultipleGlue.properties +++ /dev/null @@ -1 +0,0 @@ -glue=io.github.martinschneider.steps1,io.github.martinschneider.steps2 \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberNonStrict.properties b/core/src/test/resources/cucumber/runtime/cucumberNonStrict.properties deleted file mode 100644 index d9b5dab91a..0000000000 --- a/core/src/test/resources/cucumber/runtime/cucumberNonStrict.properties +++ /dev/null @@ -1 +0,0 @@ -strict=false \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberSingleFeaturesPath.properties b/core/src/test/resources/cucumber/runtime/cucumberSingleFeaturesPath.properties deleted file mode 100644 index f9957214c3..0000000000 --- a/core/src/test/resources/cucumber/runtime/cucumberSingleFeaturesPath.properties +++ /dev/null @@ -1 +0,0 @@ -features=src/test/resources/features1 \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberSingleGlue.properties b/core/src/test/resources/cucumber/runtime/cucumberSingleGlue.properties deleted file mode 100644 index 9ca07504b6..0000000000 --- a/core/src/test/resources/cucumber/runtime/cucumberSingleGlue.properties +++ /dev/null @@ -1 +0,0 @@ -glue=io.github.martinschneider.steps1 \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberSnippetsCamelCase.properties b/core/src/test/resources/cucumber/runtime/cucumberSnippetsCamelCase.properties deleted file mode 100644 index ca0f10f4cd..0000000000 --- a/core/src/test/resources/cucumber/runtime/cucumberSnippetsCamelCase.properties +++ /dev/null @@ -1 +0,0 @@ -snippets=camelcase \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberSnippetsUnderscore.properties b/core/src/test/resources/cucumber/runtime/cucumberSnippetsUnderscore.properties deleted file mode 100644 index 2c47acfe52..0000000000 --- a/core/src/test/resources/cucumber/runtime/cucumberSnippetsUnderscore.properties +++ /dev/null @@ -1 +0,0 @@ -snippets=underscore \ No newline at end of file diff --git a/core/src/test/resources/cucumber/runtime/cucumberStrict.properties b/core/src/test/resources/cucumber/runtime/cucumberStrict.properties deleted file mode 100644 index d8555b61ab..0000000000 --- a/core/src/test/resources/cucumber/runtime/cucumberStrict.properties +++ /dev/null @@ -1 +0,0 @@ -strict=true \ No newline at end of file diff --git a/junit/src/main/java/cucumber/api/junit/Cucumber.java b/junit/src/main/java/cucumber/api/junit/Cucumber.java index 99aa6d1ead..39b2eeab10 100644 --- a/junit/src/main/java/cucumber/api/junit/Cucumber.java +++ b/junit/src/main/java/cucumber/api/junit/Cucumber.java @@ -1,7 +1,6 @@ package cucumber.api.junit; import cucumber.api.CucumberOptions; -import cucumber.api.CucumberOptionsProvider; import cucumber.api.StepDefinitionReporter; import cucumber.api.event.TestRunFinished; import cucumber.api.event.TestRunStarted; @@ -62,7 +61,6 @@ * Cucumber-Eclipse. Instead it is recommended to use Cucumbers `Before` and `After` hooks. * * @see CucumberOptions - * @see CucumberOptionsProvider */ public class Cucumber extends ParentRunner { private final List children = new ArrayList(); diff --git a/pom.xml b/pom.xml index 43d5fc8059..1e9f2782c0 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,8 @@ 0.5.0 6.1.0 1.1.3 - 1.3.4 + 2.8.5 + 1.23 @@ -482,9 +483,14 @@ ${typetools.version} - io.leangen.geantyref - geantyref - ${geantyref.version} + com.google.code.gson + gson + ${gson.version} + + + org.yaml + snakeyaml + ${snakeyaml.version}