From 26a0e0e7723ce354774e99c60f69c4b53282ac35 Mon Sep 17 00:00:00 2001 From: Muhammed ikinci Date: Fri, 19 Nov 2021 22:49:41 +0300 Subject: [PATCH 1/4] Adding support for duplicates steps --- gserver/src/steps.handler.ts | 40 +++++++++++++++++++----------- gserver/test/steps.handler.spec.ts | 8 +++--- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/gserver/src/steps.handler.ts b/gserver/src/steps.handler.ts index 0daf978..cba826c 100644 --- a/gserver/src/steps.handler.ts +++ b/gserver/src/steps.handler.ts @@ -88,9 +88,9 @@ export default class StepsHandler { text.split(/\r?\n/g).forEach(line => { const match = this.getGherkinMatch(line, text); if (match) { - const step = this.getStepByText(match[4]); - if (step) { - this.incrementElementCount(step.id); + const steps = this.getStepByText(match[4]); + if (steps) { + this.incrementElementCount(steps[0].id); } } }); @@ -478,18 +478,17 @@ export default class StepsHandler { .reduce((files, path) => files.concat(glob.sync(root + '/' + path, { ignore: '.gitignore' })), []) .reduce((elements, f) => elements.concat( this.getFileSteps(f).reduce((steps, step) => { - if (!this.elementsHash[step.id]) { - steps.push(step); - this.elementsHash[step.id] = true; - } + steps.push(step); return steps; }, []) ), []); } - getStepByText(text: string, gherkin?: GherkinType): Step { - return this.elements - .find(s => (gherkin !== undefined ? s.gherkin === gherkin : true) && s.reg.test(text)); + getStepByText(text: string, gherkin?: GherkinType): Step[] | undefined { + const filteredElements = this.elements + .filter(s => (gherkin !== undefined ? s.gherkin === gherkin : true) && s.reg.test(text)); + + return filteredElements.length > 0 ? filteredElements : undefined; } validate(line: string, lineNum: number, text: string): Diagnostic | null { @@ -501,11 +500,11 @@ export default class StepsHandler { } const beforeGherkin = match[1]; const gherkinPart = match[2]; - const step = this.getStepByText(match[4], this.settings.cucumberautocomplete.strictGherkinValidation + const steps = this.getStepByText(match[4], this.settings.cucumberautocomplete.strictGherkinValidation ? this.getStrictGherkinType(gherkinPart, lineNum, text) : undefined ); - if (step) { + if (steps) { return null; } else { return { @@ -520,13 +519,24 @@ export default class StepsHandler { } } - getDefinition(line: string, text: string): Definition | null { + getDefinition(line: string, text: string): Location[] | null { const match = this.getGherkinMatch(line, text); if (!match) { return null; } - const step = this.getStepByText(match[4]); - return step ? step.def : null; + + let locations: Location[] = []; + + let steps : any = this.getStepByText(match[4]); + + if (!steps) + return null; + + for (let step of steps) { + locations.push(Location.create(step.def.uri, step.def.range)); + } + + return locations.length > 0 ? locations : null; } getStrictGherkinType(gherkinPart: string, lineNumber: number, text: string) { diff --git a/gserver/test/steps.handler.spec.ts b/gserver/test/steps.handler.spec.ts index 00b66b6..bc0ebce 100644 --- a/gserver/test/steps.handler.spec.ts +++ b/gserver/test/steps.handler.spec.ts @@ -23,7 +23,7 @@ const settings = { } }; -const stepsDefinitionNum = 7; +const stepsDefinitionNum = 8; const s = new StepsHandler(__dirname, settings); @@ -191,7 +191,7 @@ describe('constructor', () => { expect(e[0]).to.have.property('count', 2); expect(e[1]).to.have.property('count', 1); expect(e[2]).to.have.property('count', 2); - expect(e[3]).to.have.property('count', 1); + expect(e[3]).to.have.property('count', 2); }); it('should correcly fill all the step element fields', () => { const firstElement = e[0]; @@ -205,8 +205,8 @@ describe('constructor', () => { expect(firstElement.def['uri']).to.have.string('test.steps.js'); }); it('should set correct names to the invariants steps', () => { - expect(e[2]).to.have.property('text', 'I say a'); - expect(e[3]).to.have.property('text', 'I say b'); + expect(e[3]).to.have.property('text', 'I say a'); + expect(e[4]).to.have.property('text', 'I say b'); }); }); From fc98b606fa260d05e1df57fcc270e15e66b820f7 Mon Sep 17 00:00:00 2001 From: Muhammed ikinci Date: Sat, 20 Nov 2021 13:31:18 +0300 Subject: [PATCH 2/4] allowDuplicates settings added --- gserver/src/steps.handler.ts | 25 ++++++++++++++++++------- gserver/src/typings.d.ts | 3 ++- gserver/test/steps.handler.spec.ts | 8 ++++---- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/gserver/src/steps.handler.ts b/gserver/src/steps.handler.ts index cba826c..ba93860 100644 --- a/gserver/src/steps.handler.ts +++ b/gserver/src/steps.handler.ts @@ -90,7 +90,7 @@ export default class StepsHandler { if (match) { const steps = this.getStepByText(match[4]); if (steps) { - this.incrementElementCount(steps[0].id); + this.incrementElementCount(Array.isArray(steps) ? steps[0].id : steps.id); } } }); @@ -478,17 +478,24 @@ export default class StepsHandler { .reduce((files, path) => files.concat(glob.sync(root + '/' + path, { ignore: '.gitignore' })), []) .reduce((elements, f) => elements.concat( this.getFileSteps(f).reduce((steps, step) => { - steps.push(step); + if (!this.elementsHash[step.id]) { + steps.push(step); + this.elementsHash[step.id] = !this.settings.cucumberautocomplete.allowDuplicates; + } return steps; }, []) ), []); } - getStepByText(text: string, gherkin?: GherkinType): Step[] | undefined { + getStepByText(text: string, gherkin?: GherkinType): Step[] | Step | undefined { const filteredElements = this.elements .filter(s => (gherkin !== undefined ? s.gherkin === gherkin : true) && s.reg.test(text)); - return filteredElements.length > 0 ? filteredElements : undefined; + if (this.settings.cucumberautocomplete.allowDuplicates) { + return filteredElements.length > 0 ? filteredElements : undefined; + } + + return filteredElements.length > 0 ? filteredElements[0] : undefined; } validate(line: string, lineNum: number, text: string): Diagnostic | null { @@ -519,19 +526,23 @@ export default class StepsHandler { } } - getDefinition(line: string, text: string): Location[] | null { + getDefinition(line: string, text: string): Definition | Location[] | null { const match = this.getGherkinMatch(line, text); if (!match) { return null; } - let locations: Location[] = []; - let steps : any = this.getStepByText(match[4]); if (!steps) return null; + if (!Array.isArray(steps)) { + return steps.def; + } + + let locations: Location[] = []; + for (let step of steps) { locations.push(Location.create(step.def.uri, step.def.range)); } diff --git a/gserver/src/typings.d.ts b/gserver/src/typings.d.ts index e85a4a9..4bdd569 100644 --- a/gserver/src/typings.d.ts +++ b/gserver/src/typings.d.ts @@ -27,6 +27,7 @@ interface Settings { formatConfOverride?: FormatConf[], onTypeFormat?: boolean, gherkinDefinitionPart?: string, - stepRegExSymbol?: string + stepRegExSymbol?: string, + allowDuplicates?: boolean } } \ No newline at end of file diff --git a/gserver/test/steps.handler.spec.ts b/gserver/test/steps.handler.spec.ts index bc0ebce..00b66b6 100644 --- a/gserver/test/steps.handler.spec.ts +++ b/gserver/test/steps.handler.spec.ts @@ -23,7 +23,7 @@ const settings = { } }; -const stepsDefinitionNum = 8; +const stepsDefinitionNum = 7; const s = new StepsHandler(__dirname, settings); @@ -191,7 +191,7 @@ describe('constructor', () => { expect(e[0]).to.have.property('count', 2); expect(e[1]).to.have.property('count', 1); expect(e[2]).to.have.property('count', 2); - expect(e[3]).to.have.property('count', 2); + expect(e[3]).to.have.property('count', 1); }); it('should correcly fill all the step element fields', () => { const firstElement = e[0]; @@ -205,8 +205,8 @@ describe('constructor', () => { expect(firstElement.def['uri']).to.have.string('test.steps.js'); }); it('should set correct names to the invariants steps', () => { - expect(e[3]).to.have.property('text', 'I say a'); - expect(e[4]).to.have.property('text', 'I say b'); + expect(e[2]).to.have.property('text', 'I say a'); + expect(e[3]).to.have.property('text', 'I say b'); }); }); From 5afe94f381acf2a093d8dcc293ac81f99c0c5c79 Mon Sep 17 00:00:00 2001 From: Muhammed ikinci Date: Sat, 20 Nov 2021 13:41:26 +0300 Subject: [PATCH 3/4] updated extension properties for allowDuplicates --- gclient/package.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gclient/package.json b/gclient/package.json index 6b94930..e6836c2 100644 --- a/gclient/package.json +++ b/gclient/package.json @@ -157,6 +157,12 @@ "type": "string", "required": false, "default": false + }, + "cucumberautocomplete.allowDuplicates": { + "descrioption": "Allow duplicate step definitions for multiple context in same feature.", + "type": "boolean", + "required": false, + "default": false } } } From 0ace148b7e1b4636cdf21a9bb562b9b315d9663d Mon Sep 17 00:00:00 2001 From: Muhammed ikinci Date: Sat, 20 Nov 2021 13:47:07 +0300 Subject: [PATCH 4/4] description syntax fix --- gclient/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gclient/package.json b/gclient/package.json index e6836c2..3be1250 100644 --- a/gclient/package.json +++ b/gclient/package.json @@ -153,13 +153,13 @@ "default": false }, "cucumberautocomplete.stepRegExSymbol": { - "descrioption": "Provide step regex symbol. Ex. it would be \"'\" for When('I do something') definition", + "description": "Provide step regex symbol. Ex. it would be \"'\" for When('I do something') definition", "type": "string", "required": false, "default": false }, "cucumberautocomplete.allowDuplicates": { - "descrioption": "Allow duplicate step definitions for multiple context in same feature.", + "description": "Allow duplicate step definitions for multiple context in same feature.", "type": "boolean", "required": false, "default": false