From ff2bec8bc98fca1dc7c89f23129b82dc2f7e863e Mon Sep 17 00:00:00 2001 From: David Goss Date: Sun, 19 Jun 2022 10:20:08 +0100 Subject: [PATCH 1/4] add failing scenario --- features/target_specific_scenarios_by_line.feature | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/features/target_specific_scenarios_by_line.feature b/features/target_specific_scenarios_by_line.feature index 8a7870f36..e9001fd95 100644 --- a/features/target_specific_scenarios_by_line.feature +++ b/features/target_specific_scenarios_by_line.feature @@ -49,3 +49,8 @@ Feature: Target specific scenarios | args | | features/a.feature:2:10 | | features/a.feature:2 features/a.feature:10 | + + Scenario: using absolute paths + When I run cucumber-js with `{{{tmpDir}}}/features/a.feature:2` + Then it fails + And it runs the scenario "first scenario" From 15a2446f4d4d318b34e9ba9b24e936b2c24ba1c9 Mon Sep 17 00:00:00 2001 From: David Goss Date: Sun, 19 Jun 2022 10:35:47 +0100 Subject: [PATCH 2/4] convert to relative path before adding to map --- src/pickle_filter.ts | 10 ++- src/pickle_filter_spec.ts | 168 +++++++++++++++++++++++++++----------- 2 files changed, 131 insertions(+), 47 deletions(-) diff --git a/src/pickle_filter.ts b/src/pickle_filter.ts index 0b7bc24cd..6746638ea 100644 --- a/src/pickle_filter.ts +++ b/src/pickle_filter.ts @@ -56,20 +56,28 @@ export class PickleLineFilter { constructor(cwd: string, featurePaths: string[] = []) { this.featureUriToLinesMapping = this.getFeatureUriToLinesMapping({ + cwd, featurePaths, }) } getFeatureUriToLinesMapping({ + cwd, featurePaths, }: { + cwd: string featurePaths: string[] }): Record { const mapping: Record = {} featurePaths.forEach((featurePath) => { const match = FEATURE_LINENUM_REGEXP.exec(featurePath) if (doesHaveValue(match)) { - const uri = path.normalize(match[1]) + let uri = match[1] + if (path.isAbsolute(uri)) { + uri = path.relative(cwd, uri) + } else { + uri = path.normalize(uri) + } const linesExpression = match[2] if (doesHaveValue(linesExpression)) { if (doesNotHaveValue(mapping[uri])) { diff --git a/src/pickle_filter_spec.ts b/src/pickle_filter_spec.ts index 23529cd7a..e455114b8 100644 --- a/src/pickle_filter_spec.ts +++ b/src/pickle_filter_spec.ts @@ -1,5 +1,6 @@ import { beforeEach, describe, it } from 'mocha' import { expect } from 'chai' +import path from 'path' import PickleFilter from './pickle_filter' import { parse } from '../test/gherkin_helpers' @@ -37,67 +38,142 @@ describe('PickleFilter', () => { }) describe('line filters', () => { - beforeEach(function () { - pickleFilter = new PickleFilter({ - cwd, - featurePaths: ['features/a.feature', 'features/b.feature:2:4'], - names: [], - tagExpression: '', + describe('with relative paths', () => { + beforeEach(function () { + pickleFilter = new PickleFilter({ + cwd, + featurePaths: ['features/a.feature', 'features/b.feature:2:4'], + names: [], + tagExpression: '', + }) }) - }) - describe('pickle in feature without line specified', () => { - it('returns true', async function () { - // Arrange - const { - pickles: [pickle], - gherkinDocument, - } = await parse({ - data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), - uri: 'features/a.feature', + describe('pickle in feature without line specified', () => { + it('returns true', async function () { + // Arrange + const { + pickles: [pickle], + gherkinDocument, + } = await parse({ + data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), + uri: 'features/a.feature', + }) + + // Act + const result = pickleFilter.matches({ pickle, gherkinDocument }) + + // Assert + expect(result).to.eql(true) }) + }) - // Act - const result = pickleFilter.matches({ pickle, gherkinDocument }) + describe('pickle in feature with line specified', () => { + it('returns true if pickle line matches', async function () { + // Arrange + const { + pickles: [pickle], + gherkinDocument, + } = await parse({ + data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), + uri: 'features/b.feature', + }) - // Assert - expect(result).to.eql(true) + // Act + const result = pickleFilter.matches({ pickle, gherkinDocument }) + + // Assert + expect(result).to.eql(true) + }) + + it('returns false if pickle line does not match', async function () { + // Arrange + const { + pickles: [pickle], + gherkinDocument, + } = await parse({ + data: ['Feature: a', '', 'Scenario: b', 'Given a step'].join( + '\n' + ), + uri: 'features/b.feature', + }) + + // Act + const result = pickleFilter.matches({ pickle, gherkinDocument }) + + // Assert + expect(result).to.eql(false) + }) }) }) - describe('pickle in feature with line specified', () => { - it('returns true if pickle line matches', async function () { - // Arrange - const { - pickles: [pickle], - gherkinDocument, - } = await parse({ - data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), - uri: 'features/b.feature', + describe('with absolute paths', () => { + beforeEach(function () { + pickleFilter = new PickleFilter({ + cwd, + featurePaths: [ + path.join(cwd, 'features/a.feature'), + path.join(cwd, 'features/b.feature:2:4'), + ], + names: [], + tagExpression: '', }) + }) - // Act - const result = pickleFilter.matches({ pickle, gherkinDocument }) + describe('pickle in feature without line specified', () => { + it('returns true', async function () { + // Arrange + const { + pickles: [pickle], + gherkinDocument, + } = await parse({ + data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), + uri: 'features/a.feature', + }) - // Assert - expect(result).to.eql(true) - }) + // Act + const result = pickleFilter.matches({ pickle, gherkinDocument }) - it('returns false if pickle line does not match', async function () { - // Arrange - const { - pickles: [pickle], - gherkinDocument, - } = await parse({ - data: ['Feature: a', '', 'Scenario: b', 'Given a step'].join('\n'), - uri: 'features/b.feature', + // Assert + expect(result).to.eql(true) }) + }) - // Act - const result = pickleFilter.matches({ pickle, gherkinDocument }) + describe('pickle in feature with line specified', () => { + it('returns true if pickle line matches', async function () { + // Arrange + const { + pickles: [pickle], + gherkinDocument, + } = await parse({ + data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), + uri: 'features/b.feature', + }) - // Assert - expect(result).to.eql(false) + // Act + const result = pickleFilter.matches({ pickle, gherkinDocument }) + + // Assert + expect(result).to.eql(true) + }) + + it('returns false if pickle line does not match', async function () { + // Arrange + const { + pickles: [pickle], + gherkinDocument, + } = await parse({ + data: ['Feature: a', '', 'Scenario: b', 'Given a step'].join( + '\n' + ), + uri: 'features/b.feature', + }) + + // Act + const result = pickleFilter.matches({ pickle, gherkinDocument }) + + // Assert + expect(result).to.eql(false) + }) }) }) }) From baebb0a36c9e66b3eeaa1b0fda73b1bb7ce198d7 Mon Sep 17 00:00:00 2001 From: David Goss Date: Sun, 19 Jun 2022 10:43:01 +0100 Subject: [PATCH 3/4] refactor test --- src/pickle_filter_spec.ts | 189 ++++++++++++++------------------------ 1 file changed, 67 insertions(+), 122 deletions(-) diff --git a/src/pickle_filter_spec.ts b/src/pickle_filter_spec.ts index e455114b8..9f916a96f 100644 --- a/src/pickle_filter_spec.ts +++ b/src/pickle_filter_spec.ts @@ -38,141 +38,86 @@ describe('PickleFilter', () => { }) describe('line filters', () => { - describe('with relative paths', () => { - beforeEach(function () { - pickleFilter = new PickleFilter({ - cwd, - featurePaths: ['features/a.feature', 'features/b.feature:2:4'], - names: [], - tagExpression: '', - }) - }) - - describe('pickle in feature without line specified', () => { - it('returns true', async function () { - // Arrange - const { - pickles: [pickle], - gherkinDocument, - } = await parse({ - data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), - uri: 'features/a.feature', + const variants = [ + { + name: 'with relative paths', + featurePaths: ['features/a.feature', 'features/b.feature:2:4'], + }, + { + name: 'with absolute paths', + featurePaths: [ + path.join(cwd, 'features/a.feature'), + path.join(cwd, 'features/b.feature:2:4'), + ], + }, + ] + + variants.forEach(({ name, featurePaths }) => { + describe(name, () => { + beforeEach(function () { + pickleFilter = new PickleFilter({ + cwd, + featurePaths, + names: [], + tagExpression: '', }) - - // Act - const result = pickleFilter.matches({ pickle, gherkinDocument }) - - // Assert - expect(result).to.eql(true) }) - }) - describe('pickle in feature with line specified', () => { - it('returns true if pickle line matches', async function () { - // Arrange - const { - pickles: [pickle], - gherkinDocument, - } = await parse({ - data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), - uri: 'features/b.feature', - }) + describe('pickle in feature without line specified', () => { + it('returns true', async function () { + // Arrange + const { + pickles: [pickle], + gherkinDocument, + } = await parse({ + data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), + uri: 'features/a.feature', + }) - // Act - const result = pickleFilter.matches({ pickle, gherkinDocument }) - - // Assert - expect(result).to.eql(true) - }) + // Act + const result = pickleFilter.matches({ pickle, gherkinDocument }) - it('returns false if pickle line does not match', async function () { - // Arrange - const { - pickles: [pickle], - gherkinDocument, - } = await parse({ - data: ['Feature: a', '', 'Scenario: b', 'Given a step'].join( - '\n' - ), - uri: 'features/b.feature', + // Assert + expect(result).to.eql(true) }) - - // Act - const result = pickleFilter.matches({ pickle, gherkinDocument }) - - // Assert - expect(result).to.eql(false) }) - }) - }) - describe('with absolute paths', () => { - beforeEach(function () { - pickleFilter = new PickleFilter({ - cwd, - featurePaths: [ - path.join(cwd, 'features/a.feature'), - path.join(cwd, 'features/b.feature:2:4'), - ], - names: [], - tagExpression: '', - }) - }) - - describe('pickle in feature without line specified', () => { - it('returns true', async function () { - // Arrange - const { - pickles: [pickle], - gherkinDocument, - } = await parse({ - data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), - uri: 'features/a.feature', - }) + describe('pickle in feature with line specified', () => { + it('returns true if pickle line matches', async function () { + // Arrange + const { + pickles: [pickle], + gherkinDocument, + } = await parse({ + data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), + uri: 'features/b.feature', + }) - // Act - const result = pickleFilter.matches({ pickle, gherkinDocument }) + // Act + const result = pickleFilter.matches({ pickle, gherkinDocument }) - // Assert - expect(result).to.eql(true) - }) - }) - - describe('pickle in feature with line specified', () => { - it('returns true if pickle line matches', async function () { - // Arrange - const { - pickles: [pickle], - gherkinDocument, - } = await parse({ - data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), - uri: 'features/b.feature', + // Assert + expect(result).to.eql(true) }) - // Act - const result = pickleFilter.matches({ pickle, gherkinDocument }) - - // Assert - expect(result).to.eql(true) - }) - - it('returns false if pickle line does not match', async function () { - // Arrange - const { - pickles: [pickle], - gherkinDocument, - } = await parse({ - data: ['Feature: a', '', 'Scenario: b', 'Given a step'].join( - '\n' - ), - uri: 'features/b.feature', + it('returns false if pickle line does not match', async function () { + // Arrange + const { + pickles: [pickle], + gherkinDocument, + } = await parse({ + data: ['Feature: a', '', 'Scenario: b', 'Given a step'].join( + '\n' + ), + uri: 'features/b.feature', + }) + + // Act + const result = pickleFilter.matches({ pickle, gherkinDocument }) + + // Assert + expect(result).to.eql(false) }) - - // Act - const result = pickleFilter.matches({ pickle, gherkinDocument }) - - // Assert - expect(result).to.eql(false) }) }) }) From 0b392399e4be59e8aea368d2a45f741772122390 Mon Sep 17 00:00:00 2001 From: David Goss Date: Sun, 19 Jun 2022 10:48:11 +0100 Subject: [PATCH 4/4] update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 371b094c2..936c6c4be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CONTRIBUTING.md) on how to contribute to Cucumber. ## [Unreleased] +### Fixed +- Fix issues with using absolute paths for features ([#2063](https://github.com/cucumber/cucumber-js/pull/2063)) ## [8.3.0] - 2022-06-11 ### Added