Skip to content

Commit

Permalink
Make it easier to correctly create RuntimeOptions from a String, ref #…
Browse files Browse the repository at this point in the history
  • Loading branch information
aslakhellesoy committed Oct 14, 2013
1 parent 05031fd commit 4ed29b0
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 57 deletions.
6 changes: 4 additions & 2 deletions core/src/main/java/cucumber/api/cli/Main.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package cucumber.api.cli;

import cucumber.runtime.ClassFinder;
import cucumber.runtime.Env;
import cucumber.runtime.Runtime;
import cucumber.runtime.RuntimeOptions;
import cucumber.runtime.io.MultiLoader;
import cucumber.runtime.io.ResourceLoader;
import cucumber.runtime.io.ResourceLoaderClassFinder;

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

import static java.util.Arrays.asList;

public class Main {

Expand All @@ -17,7 +19,7 @@ public static void main(String[] argv) throws Throwable {
}

public static void run(String[] argv, ClassLoader classLoader) throws IOException {
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env("cucumber-jvm"), argv);
RuntimeOptions runtimeOptions = new RuntimeOptions(new ArrayList<String>(asList(argv)));

ResourceLoader resourceLoader = new MultiLoader(classLoader);
ClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
Expand Down
36 changes: 31 additions & 5 deletions core/src/main/java/cucumber/runtime/RuntimeOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import java.util.regex.Pattern;

import static cucumber.runtime.model.CucumberFeature.load;
import static java.util.Arrays.asList;

// IMPORTANT! Make sure USAGE.txt is always uptodate if this class changes.
public class RuntimeOptions {
Expand All @@ -41,14 +40,41 @@ public class RuntimeOptions {
private boolean monochrome = false;
private SnippetType snippetType = SnippetType.UNDERSCORE;

public RuntimeOptions(Env env, String... argv) {
/**
* Create a new instance from a string of options, for example:
*
* <pre<{@code "--name 'the fox' --format pretty --strict"}</pre>
*
* @param argv the arguments
*/
public RuntimeOptions(String argv) {
this(new FormatterFactory(), shellWords(argv));
}

/**
* Create a new instance from a list of options, for example:
*
* <pre<{@code Arrays.asList("--name", "the fox", "--format", "pretty", "--strict");}</pre>
*
* @param argv the arguments
*/
public RuntimeOptions(List<String> argv) {
this(new FormatterFactory(), argv);
}

public RuntimeOptions(Env env, List<String> argv) {
this(env, new FormatterFactory(), argv);
}

RuntimeOptions(Env env, FormatterFactory formatterFactory, String... argv) {
public RuntimeOptions(FormatterFactory formatterFactory, List<String> argv) {
this(new Env("cucumber-jvm"), formatterFactory, argv);
}

public RuntimeOptions(Env env, FormatterFactory formatterFactory, List<String> argv) {
this.formatterFactory = formatterFactory;

parse(new ArrayList<String>(asList(argv)));
argv = new ArrayList<String>(argv); // in case the one passed in is unmodifiable.
parse(argv);

String cucumberOptionsFromEnv = env.get("cucumber.options");
if (cucumberOptionsFromEnv != null) {
Expand All @@ -62,7 +88,7 @@ public RuntimeOptions(Env env, String... argv) {
setFormatterOptions();
}

private List<String> shellWords(String cmdline) {
private static List<String> shellWords(String cmdline) {
List<String> matchList = new ArrayList<String>();
Matcher shellwordsMatcher = SHELLWORDS_PATTERN.matcher(cmdline);
while (shellwordsMatcher.find()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ public RuntimeOptionsFactory(Class clazz, Class<? extends Annotation>[] annotati

public RuntimeOptions create() {
List<String> args = buildArgsFromOptions();

return new RuntimeOptions(new Env("cucumber-jvm"), args.toArray(new String[args.size()]));
return new RuntimeOptions(args);
}

private List<String> buildArgsFromOptions() {
Expand Down
2 changes: 1 addition & 1 deletion core/src/test/java/cucumber/runtime/BackgroundTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class BackgroundTest {
@Test
public void should_run_background() throws IOException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env());
RuntimeOptions runtimeOptions = new RuntimeOptions("");
Runtime runtime = new Runtime(new ClasspathResourceLoader(classLoader), classLoader, asList(mock(Backend.class)), runtimeOptions);
CucumberFeature feature = feature("test.feature", "" +
"Feature:\n" +
Expand Down
2 changes: 1 addition & 1 deletion core/src/test/java/cucumber/runtime/HookOrderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class HookOrderTest {
@Before
public void buildMockWorld() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env());
RuntimeOptions runtimeOptions = new RuntimeOptions("");
runtime = new Runtime(mock(ResourceLoader.class), classLoader, asList(mock(Backend.class)), runtimeOptions);
runtime.buildBackendWorlds(null, Collections.<Tag>emptySet());
glue = runtime.getGlue();
Expand Down
2 changes: 1 addition & 1 deletion core/src/test/java/cucumber/runtime/HookTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public void after_hooks_execute_before_objects_are_disposed() throws Throwable {
CucumberScenario scenario = new CucumberScenario(feature, null, gherkinScenario);

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env());
RuntimeOptions runtimeOptions = new RuntimeOptions("");
Runtime runtime = new Runtime(new ClasspathResourceLoader(classLoader), classLoader, asList(backend), runtimeOptions);
runtime.getGlue().addAfterHook(hook);

Expand Down
70 changes: 38 additions & 32 deletions core/src/test/java/cucumber/runtime/RuntimeOptionsTest.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package cucumber.runtime;

import cucumber.api.SnippetType;
import org.junit.Test;
import cucumber.runtime.formatter.ColorAware;
import cucumber.runtime.formatter.FormatterFactory;
import cucumber.runtime.formatter.StrictAware;
import gherkin.formatter.Formatter;
import org.junit.Test;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.Properties;
import java.util.regex.Pattern;

Expand All @@ -36,76 +37,76 @@ public void has_usage() {

@Test
public void assigns_feature_paths() {
RuntimeOptions options = new RuntimeOptions(new Env(), "--glue", "somewhere", "somewhere_else");
RuntimeOptions options = new RuntimeOptions("--glue somewhere somewhere_else");
assertEquals(asList("somewhere_else"), options.getFeaturePaths());
}

@Test
public void assigns_line_filters_from_feature_paths() {
RuntimeOptions options = new RuntimeOptions(new Env(), "--glue", "somewhere", "somewhere_else:3");
RuntimeOptions options = new RuntimeOptions("--glue somewhere somewhere_else:3");
assertEquals(asList("somewhere_else"), options.getFeaturePaths());
assertEquals(asList(3L), options.getFilters());
}

@Test
public void assigns_filters_and_line_filters_from_feature_paths() {
RuntimeOptions options = new RuntimeOptions(new Env(), "--tags", "@keep_this", "somewhere_else:3");
RuntimeOptions options = new RuntimeOptions("--tags @keep_this somewhere_else:3");
assertEquals(asList("somewhere_else"), options.getFeaturePaths());
assertEquals(Arrays.<Object>asList("@keep_this", 3L), options.getFilters());
}

@Test
public void strips_options() {
RuntimeOptions options = new RuntimeOptions(new Env(), " --glue ", "somewhere", "somewhere_else");
RuntimeOptions options = new RuntimeOptions(" --glue somewhere somewhere_else");
assertEquals(asList("somewhere_else"), options.getFeaturePaths());
}

@Test
public void assigns_glue() {
RuntimeOptions options = new RuntimeOptions(new Env(), "--glue", "somewhere");
RuntimeOptions options = new RuntimeOptions("--glue somewhere");
assertEquals(asList("somewhere"), options.getGlue());
}

@Test
public void assigns_dotcucumber() throws MalformedURLException {
RuntimeOptions options = new RuntimeOptions(new Env(), "--dotcucumber", "somewhere", "--glue", "somewhere");
RuntimeOptions options = new RuntimeOptions(asList("--dotcucumber", "somewhere", "--glue", "somewhere"));
assertEquals(new URL("file:somewhere/"), options.getDotCucumber());
}

@Test
public void creates_formatter() {
RuntimeOptions options = new RuntimeOptions(new Env(), "--format", "html:some/dir", "--glue", "somewhere");
RuntimeOptions options = new RuntimeOptions(asList("--format", "html:some/dir", "--glue", "somewhere"));
assertEquals("cucumber.runtime.formatter.HTMLFormatter", options.getFormatters().get(0).getClass().getName());
}

@Test
public void assigns_strict() {
RuntimeOptions options = new RuntimeOptions(new Env(), "--strict", "--glue", "somewhere");
RuntimeOptions options = new RuntimeOptions(asList("--strict", "--glue", "somewhere"));
assertTrue(options.isStrict());
}

@Test
public void assigns_strict_short() {
RuntimeOptions options = new RuntimeOptions(new Env(), "-s", "--glue", "somewhere");
RuntimeOptions options = new RuntimeOptions(asList("-s", "--glue", "somewhere"));
assertTrue(options.isStrict());
}

@Test
public void default_strict() {
RuntimeOptions options = new RuntimeOptions(new Env(), "--glue", "somewhere");
RuntimeOptions options = new RuntimeOptions(asList("--glue", "somewhere"));
assertFalse(options.isStrict());
}

@Test
public void name_without_spaces_is_preserved() {
RuntimeOptions options = new RuntimeOptions(new Env(), "--name", "someName");
RuntimeOptions options = new RuntimeOptions(asList("--name", "someName"));
Pattern actualPattern = (Pattern) options.getFilters().iterator().next();
assertEquals("someName", actualPattern.pattern());
}

@Test
public void name_with_spaces_is_preserved() {
RuntimeOptions options = new RuntimeOptions(new Env(), "--name", "some Name");
RuntimeOptions options = new RuntimeOptions(asList("--name", "some Name"));
Pattern actualPattern = (Pattern) options.getFilters().iterator().next();
assertEquals("some Name", actualPattern.pattern());
}
Expand All @@ -114,16 +115,21 @@ public void name_with_spaces_is_preserved() {
public void ensure_name_with_spaces_works_with_cucumber_options() {
Properties properties = new Properties();
properties.setProperty("cucumber.options", "--name 'some Name'");
RuntimeOptions options = new RuntimeOptions(new Env(properties));
RuntimeOptions options = new RuntimeOptions(new Env(properties), Collections.<String>emptyList());
Pattern actualPattern = (Pattern) options.getFilters().iterator().next();
assertEquals("some Name", actualPattern.pattern());
}

@Test
public void ensure_name_with_spaces_works_with_args() {
RuntimeOptions options = new RuntimeOptions("--name 'some Name'");
Pattern actualPattern = (Pattern) options.getFilters().iterator().next();
assertEquals("some Name", actualPattern.pattern());
}

@Test
public void ensure_multiple_cucumber_options_with_spaces_parse_correctly() throws MalformedURLException {
Properties properties = new Properties();
properties.setProperty("cucumber.options", "--name 'some Name' --dotcucumber 'some file\\path'");
RuntimeOptions options = new RuntimeOptions(new Env(properties));
RuntimeOptions options = new RuntimeOptions("--name 'some Name' --dotcucumber 'some file\\path'");
Pattern actualPattern = (Pattern) options.getFilters().iterator().next();
assertEquals("some Name", actualPattern.pattern());
assertEquals(new URL("file:some file\\path/"), options.getDotCucumber());
Expand All @@ -133,7 +139,7 @@ public void ensure_multiple_cucumber_options_with_spaces_parse_correctly() throw
public void overrides_options_with_system_properties_without_clobbering_non_overridden_ones() {
Properties properties = new Properties();
properties.setProperty("cucumber.options", "--glue lookatme this_clobbers_feature_paths");
RuntimeOptions options = new RuntimeOptions(new Env(properties), "--strict", "--glue", "somewhere", "somewhere_else");
RuntimeOptions options = new RuntimeOptions(new Env(properties), asList("--strict", "--glue", "somewhere", "somewhere_else"));
assertEquals(asList("this_clobbers_feature_paths"), options.getFeaturePaths());
assertEquals(asList("lookatme"), options.getGlue());
assertTrue(options.isStrict());
Expand All @@ -143,47 +149,47 @@ public void overrides_options_with_system_properties_without_clobbering_non_over
public void ensure_cli_glue_is_preserved_when_cucumber_options_property_defined() {
Properties properties = new Properties();
properties.setProperty("cucumber.options", "--tags @foo");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), "--glue", "somewhere");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), asList("--glue", "somewhere"));
assertEquals(asList("somewhere"), runtimeOptions.getGlue());
}

@Test
public void clobbers_filters_from_cli_if_filters_specified_in_cucumber_options_property() {
Properties properties = new Properties();
properties.setProperty("cucumber.options", "--tags @clobber_with_this");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), "--tags", "@should_be_clobbered");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), asList("--tags", "@should_be_clobbered"));
assertEquals(asList("@clobber_with_this"), runtimeOptions.getFilters());
}

@Test
public void preserves_filters_from_cli_if_filters_not_specified_in_cucumber_options_property() {
Properties properties = new Properties();
properties.setProperty("cucumber.options", "--strict");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), "--tags", "@keep_this");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), asList("--tags", "@keep_this"));
assertEquals(asList("@keep_this"), runtimeOptions.getFilters());
}

@Test
public void clobbers_features_from_cli_if_features_specified_in_cucumber_options_property() {
Properties properties = new Properties();
properties.setProperty("cucumber.options", "new newer");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), "old", "older");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), asList("old", "older"));
assertEquals(asList("new", "newer"), runtimeOptions.getFeaturePaths());
}

@Test
public void preserves_features_from_cli_if_features_not_specified_in_cucumber_options_property() {
Properties properties = new Properties();
properties.setProperty("cucumber.options", "--format pretty");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), "old", "older");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), asList("old", "older"));
assertEquals(asList("old", "older"), runtimeOptions.getFeaturePaths());
}

@Test
public void clobbers_line_filters_from_cli_if_features_specified_in_cucumber_options_property() {
Properties properties = new Properties();
properties.setProperty("cucumber.options", "new newer");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), "--tags", "@keep_this", "path/file1.feature:1");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), asList("--tags", "@keep_this", "path/file1.feature:1"));
assertEquals(asList("new", "newer"), runtimeOptions.getFeaturePaths());
assertEquals(asList("@keep_this"), runtimeOptions.getFilters());
}
Expand All @@ -192,14 +198,14 @@ public void clobbers_line_filters_from_cli_if_features_specified_in_cucumber_opt
public void allows_removal_of_strict_in_cucumber_options_property() {
Properties properties = new Properties();
properties.setProperty("cucumber.options", "--no-strict");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), "--strict");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), asList("--strict"));
assertFalse(runtimeOptions.isStrict());
}

@Test
public void fail_on_unsupported_options() {
try {
new RuntimeOptions(new Env(), "-concreteUnsupportedOption", "somewhere", "somewhere_else");
new RuntimeOptions(asList("-concreteUnsupportedOption", "somewhere", "somewhere_else"));
fail();
} catch (CucumberException e) {
assertEquals("Unknown option: -concreteUnsupportedOption", e.getMessage());
Expand All @@ -212,9 +218,9 @@ public void set_monochrome_on_color_aware_formatters() throws Exception {
Formatter colorAwareFormatter = mock(Formatter.class, withSettings().extraInterfaces(ColorAware.class));
when(factory.create("progress")).thenReturn(colorAwareFormatter);

new RuntimeOptions(new Env(), factory, "--monochrome", "--format", "progress");
new RuntimeOptions(new Env(), factory, asList("--monochrome", "--format", "progress"));

verify((ColorAware)colorAwareFormatter).setMonochrome(true);
verify((ColorAware) colorAwareFormatter).setMonochrome(true);
}

@Test
Expand All @@ -223,23 +229,23 @@ public void set_strict_on_strict_aware_formatters() throws Exception {
Formatter strictAwareFormatter = mock(Formatter.class, withSettings().extraInterfaces(StrictAware.class));
when(factory.create("junit:out/dir")).thenReturn(strictAwareFormatter);

new RuntimeOptions(new Env(), factory, "--strict", "--format", "junit:out/dir");
new RuntimeOptions(new Env(), factory, asList("--strict", "--format", "junit:out/dir"));

verify((StrictAware)strictAwareFormatter).setStrict(true);
verify((StrictAware) strictAwareFormatter).setStrict(true);
}

@Test
public void ensure_default_snippet_type_is_underscore() {
Properties properties = new Properties();
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties));
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), Collections.<String>emptyList());
assertEquals(SnippetType.UNDERSCORE, runtimeOptions.getSnippetType());
}

@Test
public void set_snippet_type() {
Properties properties = new Properties();
properties.setProperty("cucumber.options", "--snippets camelcase");
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties));
RuntimeOptions runtimeOptions = new RuntimeOptions(new Env(properties), Collections.<String>emptyList());
assertEquals(SnippetType.CAMELCASE, runtimeOptions.getSnippetType());
}

Expand Down
Loading

0 comments on commit 4ed29b0

Please sign in to comment.