From 44fbd939fe5cf4fe2606a32f66d4f2b53bff32b7 Mon Sep 17 00:00:00 2001 From: "M.P. Korstanje" Date: Mon, 24 Jul 2017 23:48:14 +0200 Subject: [PATCH] [Core] Use cucumber-ruby rerun file specification Implemented the rerun file specification from cucumber ruby[1]. It handles spaces, new lines as a separator as well as no separator at all. References: [1] https://github.com/cucumber/cucumber-ruby/blame/master/lib/cucumber/cli/rerun_file.rb --- .../runtime/model/CucumberFeature.java | 20 +++--- .../runtime/model/CucumberFeatureTest.java | 68 +++++++++++++++++++ 2 files changed, 77 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/cucumber/runtime/model/CucumberFeature.java b/core/src/main/java/cucumber/runtime/model/CucumberFeature.java index b12a3ec676..dba75311c6 100644 --- a/core/src/main/java/cucumber/runtime/model/CucumberFeature.java +++ b/core/src/main/java/cucumber/runtime/model/CucumberFeature.java @@ -14,10 +14,11 @@ import java.io.PrintStream; import java.io.Serializable; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class CucumberFeature implements Serializable { private static final long serialVersionUID = 1L; @@ -25,6 +26,7 @@ public class CucumberFeature implements Serializable { private String language; private GherkinDocument gherkinDocument; private String gherkinSource; + public static final Pattern RERUN_PATH_SPECIFICATION = Pattern.compile("(?m:^| |)(.*?\\.feature(?:(?::\\d+)*))"); public static List load(ResourceLoader resourceLoader, List featurePaths, PrintStream out) { final List cucumberFeatures = load(resourceLoader, featurePaths); @@ -53,15 +55,8 @@ public static List load(ResourceLoader resourceLoader, List resources = resourceLoader.resources(rerunPath, null); - for (Resource resource : resources) { - String source = read(resource); - if (!source.isEmpty()) { - for (String featurePath : source.split("[\r\n]+")) { - PathWithLines pathWithLines = new PathWithLines(featurePath); - loadFromFileSystemOrClasspath(builder, resourceLoader, pathWithLines.path); - } - } + for(String path : loadRerunFile(resourceLoader, rerunPath)){ + loadFromFileSystemOrClasspath(builder, resourceLoader, new PathWithLines(path).path); } } @@ -71,7 +66,10 @@ public static List loadRerunFile(ResourceLoader resourceLoader, String r for (Resource resource : resources) { String source = read(resource); if (!source.isEmpty()) { - featurePaths.addAll(Arrays.asList(source.split(" "))); + Matcher matcher = RERUN_PATH_SPECIFICATION.matcher(source); + while(matcher.find()){ + featurePaths.add(matcher.group(1)); + } } } return featurePaths; diff --git a/core/src/test/java/cucumber/runtime/model/CucumberFeatureTest.java b/core/src/test/java/cucumber/runtime/model/CucumberFeatureTest.java index b8734bafd9..c14bc30889 100644 --- a/core/src/test/java/cucumber/runtime/model/CucumberFeatureTest.java +++ b/core/src/test/java/cucumber/runtime/model/CucumberFeatureTest.java @@ -259,6 +259,74 @@ public void understands_whitespace_in_rerun_filepath() throws Exception { assertEquals("scenario bar", features.get(0).getGherkinFeature().getFeature().getChildren().get(0).getName()); } + + @Test + public void understands_rerun_files_separated_by_with_whitespace() throws Exception { + String featurePath1 = "/home/users/mp/My Documents/tests/bar.feature"; + String feature1 = "" + + "Feature: bar\n" + + " Scenario: scenario bar\n" + + " * step\n"; + String featurePath2 = "/home/users/mp/My Documents/tests/foo.feature"; + String feature2 = "" + + "Feature: foo\n" + + " Scenario: scenario 1\n" + + " * step\n" + + " Scenario: scenario 2\n" + + " * step\n"; + String rerunPath = "path/rerun.txt"; + String rerunFile = featurePath1 + ":2 " + featurePath2 + ":4"; + ResourceLoader resourceLoader = mockFeatureFileResource(featurePath1, feature1); + mockFeatureFileResource(resourceLoader, featurePath2, feature2); + mockFileResource(resourceLoader, rerunPath, null, rerunFile); + + List features = CucumberFeature.load( + resourceLoader, + singletonList("@" + rerunPath), + new PrintStream(new ByteArrayOutputStream())); + + assertEquals(2, features.size()); + assertEquals(1, features.get(0).getGherkinFeature().getFeature().getChildren().size()); + assertEquals("scenario bar", features.get(0).getGherkinFeature().getFeature().getChildren().get(0).getName()); + assertEquals(2, features.get(1).getGherkinFeature().getFeature().getChildren().size()); + assertEquals("scenario 1", features.get(1).getGherkinFeature().getFeature().getChildren().get(0).getName()); + assertEquals("scenario 2", features.get(1).getGherkinFeature().getFeature().getChildren().get(1).getName()); + } + + + @Test + public void understands_rerun_files_without_separation_in_rerun_filepath() throws Exception { + String featurePath1 = "/home/users/mp/My Documents/tests/bar.feature"; + String feature1 = "" + + "Feature: bar\n" + + " Scenario: scenario bar\n" + + " * step\n"; + String featurePath2 = "/home/users/mp/My Documents/tests/foo.feature"; + String feature2 = "" + + "Feature: foo\n" + + " Scenario: scenario 1\n" + + " * step\n" + + " Scenario: scenario 2\n" + + " * step\n"; + String rerunPath = "path/rerun.txt"; + String rerunFile = featurePath1 + ":2" + featurePath2 + ":4"; + ResourceLoader resourceLoader = mockFeatureFileResource(featurePath1, feature1); + mockFeatureFileResource(resourceLoader, featurePath2, feature2); + mockFileResource(resourceLoader, rerunPath, null, rerunFile); + + List features = CucumberFeature.load( + resourceLoader, + singletonList("@" + rerunPath), + new PrintStream(new ByteArrayOutputStream())); + + assertEquals(2, features.size()); + assertEquals(1, features.get(0).getGherkinFeature().getFeature().getChildren().size()); + assertEquals("scenario bar", features.get(0).getGherkinFeature().getFeature().getChildren().get(0).getName()); + assertEquals(2, features.get(1).getGherkinFeature().getFeature().getChildren().size()); + assertEquals("scenario 1", features.get(1).getGherkinFeature().getFeature().getChildren().get(0).getName()); + assertEquals("scenario 2", features.get(1).getGherkinFeature().getFeature().getChildren().get(1).getName()); + } + private ResourceLoader mockFeatureFileResource(String featurePath, String feature) throws IOException { ResourceLoader resourceLoader = mock(ResourceLoader.class);