Skip to content

Commit

Permalink
fix: do not run features skipped through only
Browse files Browse the repository at this point in the history
but ensure dependencies are run
  • Loading branch information
coderbyheart committed Oct 19, 2022
1 parent 77b10e2 commit a57bbf6
Show file tree
Hide file tree
Showing 12 changed files with 173 additions and 14 deletions.
40 changes: 32 additions & 8 deletions runner/orderFeatures.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,38 @@ describe('orderFeatures()', () => {
assert.deepEqual(executionOrder, ['Run this feature'])
})

it('should skip dependent features', async () => {
const features = await parseFeaturesInFolder(
path.join(process.cwd(), 'runner', 'test-data', 'orderFeatures', 'only'),
)
const executionOrder = orderFeatures(features)
.filter(({ skip }) => skip !== true)
.map(({ feature }) => feature.title)
assert.deepEqual(executionOrder, ['Run this feature'])
describe('run: only', () => {
it('should skip dependent features', async () => {
const features = await parseFeaturesInFolder(
path.join(
process.cwd(),
'runner',
'test-data',
'orderFeatures',
'only',
),
)
const executionOrder = orderFeatures(features)
.filter(({ skip }) => skip !== true)
.map(({ feature }) => feature.title)
assert.deepEqual(executionOrder, ['Run this feature'])
})

it('should run dependencies', async () => {
const features = await parseFeaturesInFolder(
path.join(
process.cwd(),
'runner',
'test-data',
'orderFeatures',
'only-with-dependencies',
),
)
const executionOrder = orderFeatures(features)
.filter(({ skip }) => skip !== true)
.map(({ feature }) => feature.title)
assert.deepEqual(executionOrder, ['Dependency', 'Run this feature'])
})
})

it('dependencies override order', async () => {
Expand Down
22 changes: 19 additions & 3 deletions runner/orderFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,32 @@ export const orderFeatures = (featureFiles: FeatureFile[]): FeatureFile[] => {
.map(({ file }) => file.name)
const hasRunOnly = runOnlyThese.length > 0

// Build map of dependencies
const dependencyMap = edges.reduce(
(dependencyMap, [dependency, dependent]) => {
if (dependent === undefined) return dependencyMap
return {
...dependencyMap,
[dependency]: [...(dependencyMap[dependency] ?? []), dependent],
}
},
{} as Record<string, string[]>,
)

const skippedFeaturesMap = featureFiles.reduce(
(skipped, { file: { name }, feature }) => ({
...skipped,
[name]: {
// Mark a feature as skipped ...
skipped:
// if it should not run, ...
feature.frontMatter?.run === 'never' ||
// or there are other features marked as `only`
(hasRunOnly && !runOnlyThese.includes(name)),
(feature.frontMatter?.run === 'never' ||
// or there are other features marked as `only`
(hasRunOnly && !runOnlyThese.includes(name))) &&
// but not if it is needed by an onlyFeature
dependencyMap[name]?.find(
(name) => runOnlyThese.find((f) => f === name) !== undefined,
) === undefined,
// Make sure the dependency exists
needs: (feature.frontMatter?.needs ?? []).map((dependencyName) => {
const dependency = featureFiles.find(
Expand Down
45 changes: 45 additions & 0 deletions runner/runSuite.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,49 @@ describe('runSuite()', () => {
const result = await runner.run()
assert.equal(result.ok, false)
})

describe('run: only', () => {
it('if a feature is marked with `run: only` all other features should not be run', async () => {
const runner = runSuite(
await parseFeaturesInFolder(
path.join(process.cwd(), 'runner', 'test-data', 'runSuite', 'only'),
),
'Example',
)

runner.addStepRunners(async () => undefined)

const result = await runner.run()
assert.equal(result.ok, true)
assert.deepEqual(result.summary.failed, 0)
assert.deepEqual(result.summary.passed, 1)
assert.deepEqual(result.summary.skipped, 1)
assert.deepEqual(result.summary.total, 2)
})

it('dependencies should be run', async () => {
const runner = runSuite(
await parseFeaturesInFolder(
path.join(
process.cwd(),
'runner',
'test-data',
'runSuite',
'only-with-dependencies',
),
),
'Example',
)

runner.addStepRunners(async () => undefined)

const result = await runner.run()

assert.equal(result.ok, true)
assert.deepEqual(result.summary.failed, 0)
assert.deepEqual(result.summary.passed, 2)
assert.deepEqual(result.summary.skipped, 1)
assert.deepEqual(result.summary.total, 3)
})
})
})
16 changes: 13 additions & 3 deletions runner/runSuite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const runSuite = <Context extends Record<string, any>>(
const featureResults: [ParsedPath, FeatureResult][] = []
const featureNameResultMap: Record<string, boolean> = {}

for (const { file, feature } of orderFeatures(featureFiles)) {
for (const { file, feature, skip } of orderFeatures(featureFiles)) {
// Have dependency failed?
const failedDependencies = (feature.frontMatter?.needs ?? []).filter(
(dependencyName) => featureNameResultMap[dependencyName] === false,
Expand All @@ -67,6 +67,14 @@ export const runSuite = <Context extends Record<string, any>>(
duration: 0,
logs: [],
}
: skip === true
? {
ok: true,
skipped: true,
results: [],
duration: 0,
logs: [],
}
: await runFeature({
stepRunners,
feature,
Expand Down Expand Up @@ -94,11 +102,13 @@ export const runSuite = <Context extends Record<string, any>>(
}

const summarize = (results: FeatureResult[]): Summary => {
const passed = results.filter(({ ok }) => ok === true).length
const passed = results.filter(
({ ok, skipped }) => ok === true && skipped === false,
).length
const failed = results.filter(
({ ok, skipped }) => ok === false && skipped === false,
).length
const skipped = results.filter(({ skipped }) => skipped === false).length
const skipped = results.filter(({ skipped }) => skipped === true).length
const duration = results.reduce((total, result) => total + result.duration, 0)
return {
total: results.length,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Dependency

<!-- This feature runs, because it is a dependency -->

## Scenario

Given this is the first step
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This feature will be skipped

## Scenario

Given this is the first step
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
run: only
needs:
- Dependency
---

<!-- This feature runs, all other features are skipped -->

# Run this feature

## Scenario

Given this is the first step
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Dependency

<!-- This feature runs, because it is a dependency -->

## Scenario

Given this is the first step
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This feature will be skipped

## Scenario

Given this is the first step
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
run: only
needs:
- Dependency
---

<!-- This feature runs, all other features are skipped -->

# Run this feature

## Scenario

Given this is the first step
5 changes: 5 additions & 0 deletions runner/test-data/runSuite/only/DoNotRun.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This feature will be skipped

## Scenario

Given this is the first step
9 changes: 9 additions & 0 deletions runner/test-data/runSuite/only/RunThisOnly.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
run: only
---

# This feature runs, all other features are skipped

## Scenario

Given this is the first step

0 comments on commit a57bbf6

Please sign in to comment.