Skip to content

Commit adb4861

Browse files
committed
fix: remove duplications in steps due to empty parameters
1 parent a819407 commit adb4861

File tree

1 file changed

+129
-129
lines changed

1 file changed

+129
-129
lines changed
Lines changed: 129 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,129 @@
1-
import {
2-
DataTable,
3-
DocString,
4-
getWorstTestStepResult,
5-
PickleDocString,
6-
PickleStep,
7-
PickleTable,
8-
Step,
9-
} from '@cucumber/messages'
10-
import React from 'react'
11-
12-
import CucumberQueryContext from '../../CucumberQueryContext.js'
13-
import GherkinQueryContext from '../../GherkinQueryContext.js'
14-
import { HighLight } from '../app/HighLight.js'
15-
import { DefaultComponent, GherkinStepProps, useCustomRendering } from '../customise/index.js'
16-
import { TestStepResultDetails } from '../results/index.js'
17-
import { Attachment } from './attachment/index.js'
18-
import { DataTable as DataTableComponent } from './DataTable.js'
19-
import { DocString as DocStringComponent } from './DocString.js'
20-
import { Keyword } from './Keyword.js'
21-
import { Parameter } from './Parameter.js'
22-
import { StepItem } from './StepItem.js'
23-
import { Title } from './Title.js'
24-
25-
interface RenderableStep {
26-
id: string
27-
keyword: string
28-
text: string
29-
dataTable?: DataTable | PickleTable
30-
docString?: DocString | PickleDocString
31-
}
32-
33-
function resolveStep(gherkinStep: Step, pickleStep?: PickleStep): RenderableStep {
34-
const step: RenderableStep = { ...gherkinStep }
35-
if (pickleStep) {
36-
step.text = pickleStep.text
37-
step.dataTable = pickleStep.argument?.dataTable
38-
step.docString = pickleStep.argument?.docString
39-
}
40-
return step
41-
}
42-
43-
const DefaultRenderer: DefaultComponent<GherkinStepProps> = ({
44-
step: gherkinStep,
45-
pickleStep,
46-
hasExamples,
47-
}) => {
48-
const step = resolveStep(gherkinStep, pickleStep)
49-
50-
const gherkinQuery = React.useContext(GherkinQueryContext)
51-
const cucumberQuery = React.useContext(CucumberQueryContext)
52-
53-
const pickleStepIds = pickleStep ? [pickleStep.id] : gherkinQuery.getPickleStepIds(step.id)
54-
const pickleStepTestStepResults = cucumberQuery.getPickleStepTestStepResults(pickleStepIds)
55-
const testStepResult = getWorstTestStepResult(pickleStepTestStepResults)
56-
const attachments = cucumberQuery.getPickleStepAttachments(pickleStepIds)
57-
58-
const stepTextElements: JSX.Element[] = []
59-
60-
if (!hasExamples) {
61-
const stepMatchArgumentsLists =
62-
pickleStepIds.length === 0
63-
? // This can happen in rare cases for background steps in a document that only has step-less scenarios,
64-
// because background steps are not added to the pickle when the scenario has no steps. In this case
65-
// the background step will be rendered as undefined (even if there are matching step definitions). This
66-
// is not ideal, but it is rare enough that we don't care about it for now.
67-
[]
68-
: cucumberQuery.getStepMatchArgumentsLists(pickleStepIds[0]) || []
69-
if (stepMatchArgumentsLists.length === 1) {
70-
// Step is defined
71-
const stepMatchArguments = stepMatchArgumentsLists[0].stepMatchArguments
72-
let offset = 0
73-
let plain: string
74-
stepMatchArguments.forEach((argument, index) => {
75-
plain = step.text.slice(offset, argument.group.start)
76-
if (plain.length > 0) {
77-
stepTextElements.push(<HighLight key={`plain-${index}`} text={plain} />)
78-
}
79-
const arg = argument.group.value
80-
if (arg) {
81-
if (arg.length > 0) {
82-
stepTextElements.push(
83-
<Parameter
84-
parameterTypeName={argument.parameterTypeName || 'anonymous'}
85-
value={arg}
86-
key={`param-${index}`}
87-
>
88-
<HighLight text={arg} />
89-
</Parameter>
90-
)
91-
}
92-
offset += plain.length + arg.length
93-
}
94-
})
95-
plain = step.text.slice(offset)
96-
if (plain.length > 0) {
97-
stepTextElements.push(<HighLight key={`plain-rest`} text={plain} />)
98-
}
99-
} else if (stepMatchArgumentsLists.length >= 2) {
100-
// Step is ambiguous
101-
stepTextElements.push(<HighLight key={`plain-ambiguous`} text={step.text} />)
102-
} else {
103-
// Step is undefined
104-
stepTextElements.push(<HighLight key={`plain-undefined`} text={step.text} />)
105-
}
106-
} else {
107-
// Step is from scenario with examples, and has <> placeholders.
108-
stepTextElements.push(<HighLight key={`plain-placeholders`} text={step.text} />)
109-
}
110-
111-
return (
112-
<StepItem status={testStepResult.status}>
113-
<Title header="h3" id={step.id}>
114-
<Keyword>{step.keyword.trim()}</Keyword>
115-
<span>{stepTextElements}</span>
116-
</Title>
117-
{step.dataTable && <DataTableComponent dataTable={step.dataTable} />}
118-
{step.docString && <DocStringComponent docString={step.docString} />}
119-
{!hasExamples && <TestStepResultDetails {...testStepResult} />}
120-
{!hasExamples &&
121-
attachments.map((attachment, i) => <Attachment key={i} attachment={attachment} />)}
122-
</StepItem>
123-
)
124-
}
125-
126-
export const GherkinStep: React.FunctionComponent<GherkinStepProps> = (props) => {
127-
const ResolvedRenderer = useCustomRendering<GherkinStepProps>('GherkinStep', {}, DefaultRenderer)
128-
return <ResolvedRenderer {...props} />
129-
}
1+
import {
2+
DataTable,
3+
DocString,
4+
getWorstTestStepResult,
5+
PickleDocString,
6+
PickleStep,
7+
PickleTable,
8+
Step,
9+
} from '@cucumber/messages'
10+
import React from 'react'
11+
12+
import CucumberQueryContext from '../../CucumberQueryContext.js'
13+
import GherkinQueryContext from '../../GherkinQueryContext.js'
14+
import { HighLight } from '../app/HighLight.js'
15+
import { DefaultComponent, GherkinStepProps, useCustomRendering } from '../customise/index.js'
16+
import { TestStepResultDetails } from '../results/index.js'
17+
import { Attachment } from './attachment/index.js'
18+
import { DataTable as DataTableComponent } from './DataTable.js'
19+
import { DocString as DocStringComponent } from './DocString.js'
20+
import { Keyword } from './Keyword.js'
21+
import { Parameter } from './Parameter.js'
22+
import { StepItem } from './StepItem.js'
23+
import { Title } from './Title.js'
24+
25+
interface RenderableStep {
26+
id: string
27+
keyword: string
28+
text: string
29+
dataTable?: DataTable | PickleTable
30+
docString?: DocString | PickleDocString
31+
}
32+
33+
function resolveStep(gherkinStep: Step, pickleStep?: PickleStep): RenderableStep {
34+
const step: RenderableStep = { ...gherkinStep }
35+
if (pickleStep) {
36+
step.text = pickleStep.text
37+
step.dataTable = pickleStep.argument?.dataTable
38+
step.docString = pickleStep.argument?.docString
39+
}
40+
return step
41+
}
42+
43+
const DefaultRenderer: DefaultComponent<GherkinStepProps> = ({
44+
step: gherkinStep,
45+
pickleStep,
46+
hasExamples,
47+
}) => {
48+
const step = resolveStep(gherkinStep, pickleStep)
49+
50+
const gherkinQuery = React.useContext(GherkinQueryContext)
51+
const cucumberQuery = React.useContext(CucumberQueryContext)
52+
53+
const pickleStepIds = pickleStep ? [pickleStep.id] : gherkinQuery.getPickleStepIds(step.id)
54+
const pickleStepTestStepResults = cucumberQuery.getPickleStepTestStepResults(pickleStepIds)
55+
const testStepResult = getWorstTestStepResult(pickleStepTestStepResults)
56+
const attachments = cucumberQuery.getPickleStepAttachments(pickleStepIds)
57+
58+
const stepTextElements: JSX.Element[] = []
59+
60+
if (!hasExamples) {
61+
const stepMatchArgumentsLists =
62+
pickleStepIds.length === 0
63+
? // This can happen in rare cases for background steps in a document that only has step-less scenarios,
64+
// because background steps are not added to the pickle when the scenario has no steps. In this case
65+
// the background step will be rendered as undefined (even if there are matching step definitions). This
66+
// is not ideal, but it is rare enough that we don't care about it for now.
67+
[]
68+
: cucumberQuery.getStepMatchArgumentsLists(pickleStepIds[0]) || []
69+
if (stepMatchArgumentsLists.length === 1) {
70+
// Step is defined
71+
const stepMatchArguments = stepMatchArgumentsLists[0].stepMatchArguments
72+
let offset = 0
73+
let plain: string
74+
stepMatchArguments.forEach((argument, index) => {
75+
plain = step.text.slice(offset, argument.group.start)
76+
if (plain.length > 0) {
77+
stepTextElements.push(<HighLight key={`plain-${index}`} text={plain} />)
78+
}
79+
const arg = argument.group.value
80+
if (arg !== undefined && arg !== null) {
81+
if (arg.length > 0) {
82+
stepTextElements.push(
83+
<Parameter
84+
parameterTypeName={argument.parameterTypeName || 'anonymous'}
85+
value={arg}
86+
key={`param-${index}`}
87+
>
88+
<HighLight text={arg} />
89+
</Parameter>
90+
)
91+
}
92+
offset += plain.length + arg.length
93+
}
94+
})
95+
plain = step.text.slice(offset)
96+
if (plain.length > 0) {
97+
stepTextElements.push(<HighLight key={`plain-rest`} text={plain} />)
98+
}
99+
} else if (stepMatchArgumentsLists.length >= 2) {
100+
// Step is ambiguous
101+
stepTextElements.push(<HighLight key={`plain-ambiguous`} text={step.text} />)
102+
} else {
103+
// Step is undefined
104+
stepTextElements.push(<HighLight key={`plain-undefined`} text={step.text} />)
105+
}
106+
} else {
107+
// Step is from scenario with examples, and has <> placeholders.
108+
stepTextElements.push(<HighLight key={`plain-placeholders`} text={step.text} />)
109+
}
110+
111+
return (
112+
<StepItem status={testStepResult.status}>
113+
<Title header="h3" id={step.id}>
114+
<Keyword>{step.keyword.trim()}</Keyword>
115+
<span>{stepTextElements}</span>
116+
</Title>
117+
{step.dataTable && <DataTableComponent dataTable={step.dataTable} />}
118+
{step.docString && <DocStringComponent docString={step.docString} />}
119+
{!hasExamples && <TestStepResultDetails {...testStepResult} />}
120+
{!hasExamples &&
121+
attachments.map((attachment, i) => <Attachment key={i} attachment={attachment} />)}
122+
</StepItem>
123+
)
124+
}
125+
126+
export const GherkinStep: React.FunctionComponent<GherkinStepProps> = (props) => {
127+
const ResolvedRenderer = useCustomRendering<GherkinStepProps>('GherkinStep', {}, DefaultRenderer)
128+
return <ResolvedRenderer {...props} />
129+
}

0 commit comments

Comments
 (0)