diff --git a/core/src/main/java/cucumber/runtime/FeatureBuilder.java b/core/src/main/java/cucumber/runtime/FeatureBuilder.java index 48afc0634c..ee0b256de6 100644 --- a/core/src/main/java/cucumber/runtime/FeatureBuilder.java +++ b/core/src/main/java/cucumber/runtime/FeatureBuilder.java @@ -15,6 +15,7 @@ import gherkin.parser.Parser; import gherkin.util.FixJava; +import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.math.BigInteger; @@ -28,13 +29,19 @@ public class FeatureBuilder implements Formatter { private static final Charset UTF8 = Charset.forName("UTF-8"); private final List cucumberFeatures; + private final char fileSeparatorChar; private final MessageDigest md5; private final Map pathsByChecksum = new HashMap(); private CucumberFeature currentCucumberFeature; private String uri; public FeatureBuilder(List cucumberFeatures) { + this(cucumberFeatures, File.separatorChar); + } + + FeatureBuilder(List cucumberFeatures, char fileSeparatorChar) { this.cucumberFeatures = cucumberFeatures; + this.fileSeparatorChar = fileSeparatorChar; try { this.md5 = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { @@ -110,7 +117,7 @@ public void parse(Resource resource, List filters) { } Parser parser = new Parser(formatter); - parser.parse(gherkin, resource.getPath(), 0); + parser.parse(gherkin, convertPathToUri(resource.getPath()), 0); I18n i18n = parser.getI18nLanguage(); if (currentCucumberFeature != null) { // The current feature may be null if we used a very restrictive filter, say a tag that isn't used. @@ -119,6 +126,10 @@ public void parse(Resource resource, List filters) { } } + private String convertPathToUri(String path) { + return path.replace(fileSeparatorChar, '/'); + } + private String checksum(String gherkin) { return new BigInteger(1, md5.digest(gherkin.getBytes(UTF8))).toString(16); } diff --git a/core/src/test/java/cucumber/runtime/FeatureBuilderTest.java b/core/src/test/java/cucumber/runtime/FeatureBuilderTest.java index c5af473b8f..a32c5e12e4 100644 --- a/core/src/test/java/cucumber/runtime/FeatureBuilderTest.java +++ b/core/src/test/java/cucumber/runtime/FeatureBuilderTest.java @@ -22,14 +22,50 @@ public class FeatureBuilderTest { public void ignores_duplicate_features() throws IOException { List features = new ArrayList(); FeatureBuilder builder = new FeatureBuilder(features); - Resource resource = mock(Resource.class); - when(resource.getPath()).thenReturn("foo.feature"); - ByteArrayInputStream firstFeature = new ByteArrayInputStream("Feature: foo".getBytes("UTF-8")); - ByteArrayInputStream secondFeature = new ByteArrayInputStream("Feature: foo".getBytes("UTF-8")); - when(resource.getInputStream()).thenReturn(firstFeature, secondFeature); + String featurePath = "foo.feature"; + Resource resource1 = createResourceMock(featurePath); + Resource resource2 = createResourceMock(featurePath); + + builder.parse(resource1, NO_FILTERS); + builder.parse(resource2, NO_FILTERS); + + assertEquals(1, features.size()); + } + + @Test + public void works_when_path_and_uri_are_the_same() throws IOException { + char fileSeparatorChar = '/'; + String featurePath = "path" + fileSeparatorChar + "foo.feature"; + Resource resource = createResourceMock(featurePath); + List features = new ArrayList(); + FeatureBuilder builder = new FeatureBuilder(features, fileSeparatorChar); + builder.parse(resource, NO_FILTERS); + + assertEquals(1, features.size()); + assertEquals(featurePath, features.get(0).getUri()); + } + + @Test + public void converts_windows_path_to_uri() throws IOException { + char fileSeparatorChar = '\\'; + String featurePath = "path" + fileSeparatorChar + "foo.feature"; + Resource resource = createResourceMock(featurePath); + List features = new ArrayList(); + FeatureBuilder builder = new FeatureBuilder(features, fileSeparatorChar); + builder.parse(resource, NO_FILTERS); + assertEquals(1, features.size()); + assertEquals("path/foo.feature", features.get(0).getUri()); + } + + private Resource createResourceMock(String featurePath) throws IOException { + Resource resource = mock(Resource.class); + when(resource.getPath()).thenReturn(featurePath); + ByteArrayInputStream feature = new ByteArrayInputStream("Feature: foo".getBytes("UTF-8")); + when(resource.getInputStream()).thenReturn(feature); + return resource; } } diff --git a/core/src/test/java/cucumber/runtime/formatter/JSONPrettyFormatterTest.java b/core/src/test/java/cucumber/runtime/formatter/JSONPrettyFormatterTest.java index 8d559e39e1..de2ce1ac77 100644 --- a/core/src/test/java/cucumber/runtime/formatter/JSONPrettyFormatterTest.java +++ b/core/src/test/java/cucumber/runtime/formatter/JSONPrettyFormatterTest.java @@ -26,8 +26,6 @@ public class JSONPrettyFormatterTest { public void featureWithOutlineTest() throws Exception { File report = runFeaturesWithJSONPrettyFormatter(asList("cucumber/runtime/formatter/JSONPrettyFormatterTest.feature")); String expected = new Scanner(getClass().getResourceAsStream("JSONPrettyFormatterTest.json"), "UTF-8").useDelimiter("\\A").next(); - expected = expected.replace("cucumber/runtime/formatter/JSONPrettyFormatterTest.feature", "cucumber" + File.separator + "runtime" - + File.separator + "formatter" + File.separator + "JSONPrettyFormatterTest.feature"); String actual = new Scanner(report, "UTF-8").useDelimiter("\\A").next(); assertEquals(expected, actual); }