Skip to content

Commit 85793fa

Browse files
Merge pull request #50 from cucumber/single-code-action
Generate a single code action with relative path
2 parents 727958d + b04c92f commit 85793fa

4 files changed

Lines changed: 214 additions & 214 deletions

File tree

src/service/getGenerateSnippetCodeActions.ts renamed to src/service/getGenerateSnippetCodeAction.ts

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,58 +20,59 @@ import { stepDefinitionSnippet } from './snippet/stepDefinitionSnippet.js'
2020
*
2121
* @param diagnostics all the diagnostics
2222
* @param link where the snippet should be added
23+
* @param relativePath the relative path from the workspace root
2324
* @param createFile true if link.targetUri does not exist
2425
* @param mustacheTemplate template to generae the snippet
2526
* @param languageName the name of the language we're generating for
2627
* @param registry parameter types
2728
*/
28-
export function getGenerateSnippetCodeActions(
29+
export function getGenerateSnippetCodeAction(
2930
diagnostics: Diagnostic[],
3031
link: LocationLink,
32+
relativePath: string,
3133
createFile: boolean,
3234
mustacheTemplate: string | undefined,
3335
languageName: LanguageName,
3436
registry: ParameterTypeRegistry
35-
): CodeAction[] {
37+
): CodeAction | null {
3638
const undefinedStepDiagnostic = diagnostics.find((d) => d.code === diagnosticCodeUndefinedStep)
3739
const language = getLanguage(languageName)
3840
const stepKeyword = undefinedStepDiagnostic?.data?.stepKeyword
3941
const stepText = undefinedStepDiagnostic?.data?.stepText
40-
if (undefinedStepDiagnostic && stepText) {
41-
const generator = new CucumberExpressionGenerator(() => registry.parameterTypes)
42-
const generatedExpressions = generator.generateExpressions(stepText)
42+
if (!undefinedStepDiagnostic || !stepText) {
43+
return null
44+
}
45+
const generator = new CucumberExpressionGenerator(() => registry.parameterTypes)
46+
const generatedExpressions = generator.generateExpressions(stepText)
4347

44-
const snippet = stepDefinitionSnippet(
45-
stepKeyword,
46-
generatedExpressions,
47-
mustacheTemplate || language.defaultSnippetTemplate,
48-
language.snippetParameters
49-
)
48+
const snippet = stepDefinitionSnippet(
49+
stepKeyword,
50+
generatedExpressions,
51+
mustacheTemplate || language.defaultSnippetTemplate,
52+
language.snippetParameters
53+
)
5054

51-
const documentChanges: (CreateFile | TextDocumentEdit)[] = []
52-
if (createFile) {
53-
documentChanges.push(
54-
CreateFile.create(link.targetUri, {
55-
ignoreIfExists: true,
56-
overwrite: true,
57-
})
58-
)
59-
}
55+
const documentChanges: (CreateFile | TextDocumentEdit)[] = []
56+
if (createFile) {
6057
documentChanges.push(
61-
TextDocumentEdit.create(VersionedTextDocumentIdentifier.create(link.targetUri, 0), [
62-
TextEdit.replace(link.targetRange, snippet),
63-
])
58+
CreateFile.create(link.targetUri, {
59+
ignoreIfExists: true,
60+
overwrite: true,
61+
})
6462
)
65-
const ca: CodeAction = {
66-
title: 'Generate step definition',
67-
diagnostics: [undefinedStepDiagnostic],
68-
kind: CodeActionKind.QuickFix,
69-
edit: {
70-
documentChanges,
71-
},
72-
isPreferred: true,
73-
}
74-
return [ca]
7563
}
76-
return []
64+
documentChanges.push(
65+
TextDocumentEdit.create(VersionedTextDocumentIdentifier.create(link.targetUri, 0), [
66+
TextEdit.replace(link.targetRange, snippet),
67+
])
68+
)
69+
return {
70+
title: `Define in ${relativePath}`,
71+
diagnostics: [undefinedStepDiagnostic],
72+
kind: CodeActionKind.QuickFix,
73+
edit: {
74+
documentChanges,
75+
},
76+
isPreferred: true,
77+
}
7778
}

src/service/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export * from './getGenerateSnippetCodeActions.js'
1+
export * from './getGenerateSnippetCodeAction.js'
22
export * from './getGherkinCompletionItems.js'
33
export * from './getGherkinDiagnostics.js'
44
export * from './getGherkinFormattingEdits.js'
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
import { ParameterTypeRegistry } from '@cucumber/cucumber-expressions'
2+
import assert from 'assert'
3+
import { CodeAction, LocationLink, Range } from 'vscode-languageserver-types'
4+
5+
import { getGenerateSnippetCodeAction } from '../../src/service/getGenerateSnippetCodeAction.js'
6+
import { makeUndefinedStepDiagnostic } from '../../src/service/getGherkinDiagnostics.js'
7+
8+
describe('getGenerateSnippetCodeAction', () => {
9+
it('generates code in a new file', () => {
10+
const diagnostic = makeUndefinedStepDiagnostic(10, 4, 'Given ', 'I have 43 cukes')
11+
12+
const targetRange = Range.create(10, 0, 10, 0)
13+
const link: LocationLink = {
14+
targetUri: 'file://home/features/step_definitions/steps.ts',
15+
targetRange,
16+
targetSelectionRange: targetRange,
17+
}
18+
const action = getGenerateSnippetCodeAction(
19+
[diagnostic],
20+
link,
21+
'step_definitions/steps.ts',
22+
true,
23+
undefined,
24+
'typescript',
25+
new ParameterTypeRegistry()
26+
)
27+
const expectedAction: CodeAction = {
28+
title: 'Define in step_definitions/steps.ts',
29+
diagnostics: [
30+
{
31+
severity: 2,
32+
range: {
33+
start: {
34+
line: 10,
35+
character: 4,
36+
},
37+
end: {
38+
line: 10,
39+
character: 19,
40+
},
41+
},
42+
message: 'Undefined step: I have 43 cukes',
43+
source: 'Cucumber',
44+
code: 'cucumber.undefined-step',
45+
codeDescription: {
46+
href: 'https://cucumber.io/docs/cucumber/step-definitions/',
47+
},
48+
data: {
49+
stepKeyword: 'Given ',
50+
stepText: 'I have 43 cukes',
51+
},
52+
},
53+
],
54+
kind: 'quickfix',
55+
edit: {
56+
documentChanges: [
57+
{
58+
kind: 'create',
59+
uri: 'file://home/features/step_definitions/steps.ts',
60+
options: {
61+
ignoreIfExists: true,
62+
overwrite: true,
63+
},
64+
},
65+
{
66+
textDocument: {
67+
uri: 'file://home/features/step_definitions/steps.ts',
68+
version: 0,
69+
},
70+
edits: [
71+
{
72+
range: {
73+
start: {
74+
line: 10,
75+
character: 0,
76+
},
77+
end: {
78+
line: 10,
79+
character: 0,
80+
},
81+
},
82+
newText: `
83+
Given('I have {int} cukes', (int: number) => {
84+
// Write code here that turns the phrase above into concrete actions
85+
})
86+
`,
87+
},
88+
],
89+
},
90+
],
91+
},
92+
isPreferred: true,
93+
}
94+
95+
assert.deepStrictEqual(action, expectedAction)
96+
})
97+
98+
it('generates code in an existing file', () => {
99+
const diagnostic = makeUndefinedStepDiagnostic(10, 4, 'Given ', 'I have 43 cukes')
100+
101+
const targetRange = Range.create(10, 0, 10, 0)
102+
const link: LocationLink = {
103+
targetUri: 'file://home/features/step_definitions/steps.ts',
104+
targetRange,
105+
targetSelectionRange: targetRange,
106+
}
107+
108+
const action = getGenerateSnippetCodeAction(
109+
[diagnostic],
110+
link,
111+
'step_definitions/steps.ts',
112+
false,
113+
undefined,
114+
'typescript',
115+
new ParameterTypeRegistry()
116+
)
117+
const expectedAction: CodeAction = {
118+
title: 'Define in step_definitions/steps.ts',
119+
diagnostics: [
120+
{
121+
severity: 2,
122+
range: {
123+
start: {
124+
line: 10,
125+
character: 4,
126+
},
127+
end: {
128+
line: 10,
129+
character: 19,
130+
},
131+
},
132+
message: 'Undefined step: I have 43 cukes',
133+
source: 'Cucumber',
134+
code: 'cucumber.undefined-step',
135+
codeDescription: {
136+
href: 'https://cucumber.io/docs/cucumber/step-definitions/',
137+
},
138+
data: {
139+
stepKeyword: 'Given ',
140+
stepText: 'I have 43 cukes',
141+
},
142+
},
143+
],
144+
kind: 'quickfix',
145+
edit: {
146+
documentChanges: [
147+
{
148+
textDocument: {
149+
uri: 'file://home/features/step_definitions/steps.ts',
150+
version: 0,
151+
},
152+
edits: [
153+
{
154+
range: {
155+
start: {
156+
line: 10,
157+
character: 0,
158+
},
159+
end: {
160+
line: 10,
161+
character: 0,
162+
},
163+
},
164+
newText: `
165+
Given('I have {int} cukes', (int: number) => {
166+
// Write code here that turns the phrase above into concrete actions
167+
})
168+
`,
169+
},
170+
],
171+
},
172+
],
173+
},
174+
isPreferred: true,
175+
}
176+
assert.deepStrictEqual(action, expectedAction)
177+
})
178+
})

0 commit comments

Comments
 (0)