Skip to content

Commit 5eb8930

Browse files
committed
use lineage for test case names
1 parent efae310 commit 5eb8930

File tree

3 files changed

+130
-13
lines changed

3 files changed

+130
-13
lines changed

javascript/src/ExtendedQuery.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as assert from 'node:assert'
22

33
import {
44
Envelope,
5-
Examples,
65
Feature,
76
getWorstTestStepResult,
87
GherkinDocument,
@@ -11,7 +10,6 @@ import {
1110
Rule,
1211
Scenario,
1312
Step,
14-
TableRow,
1513
TestCase,
1614
TestCaseFinished,
1715
TestCaseStarted,
@@ -24,16 +22,7 @@ import {
2422
} from '@cucumber/messages'
2523
import { ArrayMultimap } from '@teppeis/multimaps'
2624

27-
export interface Lineage {
28-
gherkinDocument?: GherkinDocument
29-
feature?: Feature
30-
rule?: Rule
31-
scenario?: Scenario
32-
examples?: Examples
33-
examplesIndex?: number
34-
example?: TableRow
35-
exampleIndex?: number
36-
}
25+
import { Lineage, NamingStrategy } from './Lineage.js'
3726

3827
export class ExtendedQuery {
3928
private testRunStarted: TestRunStarted
@@ -188,6 +177,11 @@ export class ExtendedQuery {
188177
return this.lineageById.get(deepestAstNodeId)
189178
}
190179

180+
findNameOf(pickle: Pickle, namingStrategy: NamingStrategy) {
181+
const lineage = this.findLineageBy(pickle)
182+
return lineage ? namingStrategy.reduce(lineage, pickle) : pickle.name
183+
}
184+
191185
findStepBy(pickleStep: PickleStep) {
192186
const [astNodeId] = pickleStep.astNodeIds
193187
assert.ok('Expected PickleStep to have an astNodeId')

javascript/src/Lineage.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import {
2+
Examples,
3+
Feature,
4+
GherkinDocument,
5+
Pickle,
6+
Rule,
7+
Scenario,
8+
TableRow,
9+
} from '@cucumber/messages'
10+
11+
export interface Lineage {
12+
gherkinDocument?: GherkinDocument
13+
feature?: Feature
14+
rule?: Rule
15+
scenario?: Scenario
16+
examples?: Examples
17+
examplesIndex?: number
18+
example?: TableRow
19+
exampleIndex?: number
20+
}
21+
22+
export interface LineageReducer<T> {
23+
reduce: (lineage: Lineage, pickle: Pickle) => T
24+
}
25+
26+
export type NamingStrategy = LineageReducer<string>
27+
28+
export enum NamingStrategyLength {
29+
LONG = 'LONG',
30+
SHORT = 'SHORT',
31+
}
32+
33+
export enum NamingStrategyFeatureName {
34+
INCLUDE = 'INCLUDE',
35+
EXCLUDE = 'EXCLUDE',
36+
}
37+
38+
export enum NamingStrategyExampleName {
39+
NUMBER = 'NUMBER',
40+
PICKLE = 'PICKLE',
41+
NUMBER_AND_PICKLE_IF_PARAMETERIZED = 'NUMBER_AND_PICKLE_IF_PARAMETERIZED',
42+
}
43+
44+
class BuiltinNamingStrategy implements NamingStrategy {
45+
constructor(
46+
private readonly length: NamingStrategyLength,
47+
private readonly featureName: NamingStrategyFeatureName,
48+
private readonly exampleName: NamingStrategyExampleName
49+
) {}
50+
51+
reduce(lineage: Lineage, pickle: Pickle): string {
52+
const parts: string[] = []
53+
54+
if (lineage.feature?.name && this.featureName === NamingStrategyFeatureName.INCLUDE) {
55+
parts.push(lineage.feature.name)
56+
}
57+
58+
if (lineage.rule?.name) {
59+
parts.push(lineage.rule.name)
60+
}
61+
62+
if (lineage.scenario?.name) {
63+
parts.push(lineage.scenario.name)
64+
} else {
65+
parts.push(pickle.name)
66+
}
67+
68+
if (lineage.examples?.name) {
69+
parts.push(lineage.examples.name)
70+
}
71+
72+
if (lineage.example) {
73+
const exampleNumber = [
74+
'#',
75+
(lineage.examplesIndex ?? 0) + 1,
76+
'.',
77+
(lineage.exampleIndex ?? 0) + 1,
78+
].join('')
79+
80+
switch (this.exampleName) {
81+
case NamingStrategyExampleName.NUMBER:
82+
parts.push(exampleNumber)
83+
break
84+
case NamingStrategyExampleName.NUMBER_AND_PICKLE_IF_PARAMETERIZED:
85+
if (lineage.scenario?.name !== pickle.name) {
86+
parts.push(exampleNumber + ': ' + pickle.name)
87+
} else {
88+
parts.push(exampleNumber)
89+
}
90+
break
91+
case NamingStrategyExampleName.PICKLE:
92+
parts.push(pickle.name)
93+
break
94+
}
95+
}
96+
97+
if (this.length === NamingStrategyLength.SHORT) {
98+
return parts.at(-1) as string
99+
}
100+
return parts.filter((part) => !!part).join(' - ')
101+
}
102+
}
103+
104+
export function namingStrategy(
105+
length: NamingStrategyLength,
106+
featureName: NamingStrategyFeatureName,
107+
exampleName: NamingStrategyExampleName
108+
): NamingStrategy {
109+
return new BuiltinNamingStrategy(length, featureName, exampleName)
110+
}

javascript/src/index.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@ import xmlbuilder from 'xmlbuilder'
66

77
import { ExtendedQuery } from './ExtendedQuery.js'
88
import { countStatuses, durationToSeconds, formatStep } from './helpers.js'
9+
import {
10+
namingStrategy,
11+
NamingStrategyExampleName,
12+
NamingStrategyFeatureName,
13+
NamingStrategyLength,
14+
} from './Lineage.js'
15+
16+
const NAMING_STRATEGY = namingStrategy(
17+
NamingStrategyLength.LONG,
18+
NamingStrategyFeatureName.EXCLUDE,
19+
NamingStrategyExampleName.NUMBER_AND_PICKLE_IF_PARAMETERIZED
20+
)
921

1022
export default {
1123
type: 'formatter',
@@ -93,9 +105,10 @@ function makeTestCases(query: ExtendedQuery): ReadonlyArray<ReportTestCase> {
93105
const pickle = query.findPickleBy(testCaseStarted)
94106
assert.ok(pickle, 'Expected to find Pickle by TestCaseStarted')
95107
const lineage = query.findLineageBy(pickle)
108+
96109
return {
97110
classname: lineage?.feature?.name ?? pickle.uri,
98-
name: pickle.name,
111+
name: query.findNameOf(pickle, NAMING_STRATEGY),
99112
time: durationToSeconds(query.findTestCaseDurationBy(testCaseStarted)),
100113
failure: makeFailure(query, testCaseStarted),
101114
output: query

0 commit comments

Comments
 (0)