From 263fc1b62565b0693c9514ed23f34672473e18c2 Mon Sep 17 00:00:00 2001 From: Bart Langelaan Date: Sun, 5 Nov 2023 14:24:51 +0000 Subject: [PATCH] Add multilanguage support to step definitions --- src/language/csharpLanguage.ts | 6 +++--- src/language/helpers.ts | 7 +++++++ src/language/javaLanguage.ts | 3 ++- src/language/phpLanguage.ts | 3 ++- src/language/pythonLanguage.ts | 3 ++- src/language/rubyLanguage.ts | 4 ++-- src/language/rustLanguage.ts | 3 ++- src/language/tsxLanguage.ts | 4 ++-- test/language/testdata/javascript/StepDefinitions.js | 4 +++- 9 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/language/csharpLanguage.ts b/src/language/csharpLanguage.ts index fae14b3d..d094b9e2 100644 --- a/src/language/csharpLanguage.ts +++ b/src/language/csharpLanguage.ts @@ -1,6 +1,6 @@ import { StringOrRegExp } from '@cucumber/cucumber-expressions' -import { childrenToString, NO_QUOTES } from './helpers.js' +import { childrenToString, functionNames, NO_QUOTES } from './helpers.js' import { Language, TreeSitterSyntaxNode } from './types.js' export const csharpLanguage: Language = { @@ -77,7 +77,7 @@ export const csharpLanguage: Language = { ) ) ) - (#match? @annotation-name "Given|When|Then|And|But|StepDefinition") + (#match? @annotation-name "${functionNames}|And|But|StepDefinition") ) @root `, ` @@ -92,7 +92,7 @@ export const csharpLanguage: Language = { ) ) ) - (#match? @annotation-name "Given|When|Then|And|But|StepDefinition") + (#match? @annotation-name "${functionNames}|And|But|StepDefinition") ) @root `, ], diff --git a/src/language/helpers.ts b/src/language/helpers.ts index 69c12bf4..b2035ac8 100644 --- a/src/language/helpers.ts +++ b/src/language/helpers.ts @@ -1,4 +1,5 @@ import { ParameterType, RegExps } from '@cucumber/cucumber-expressions' +import { dialects } from '@cucumber/gherkin' import { DocumentUri, LocationLink, Range } from 'vscode-languageserver-types' import { Link, NodePredicate, TreeSitterQueryMatch, TreeSitterSyntaxNode } from './types' @@ -70,3 +71,9 @@ export function filter( function flatten(node: TreeSitterSyntaxNode): TreeSitterSyntaxNode[] { return node.children.reduce((r, o) => [...r, ...flatten(o)], [node]) } + +export const functionNames = Object.values(dialects) + .flatMap((dialect) => [...dialect.given, ...dialect.when, ...dialect.then]) + .map((keyword) => keyword.trim()) + .filter((keyword) => keyword !== '*') + .join('|') diff --git a/src/language/javaLanguage.ts b/src/language/javaLanguage.ts index 63025817..625881a7 100644 --- a/src/language/javaLanguage.ts +++ b/src/language/javaLanguage.ts @@ -1,3 +1,4 @@ +import { functionNames } from './helpers.js' import { Language, TreeSitterSyntaxNode } from './types.js' export const javaLanguage: Language = { @@ -90,7 +91,7 @@ export const javaLanguage: Language = { ) ) ) - (#match? @annotation-name "Given|When|Then") + (#match? @annotation-name "${functionNames}") ) @root `, ], diff --git a/src/language/phpLanguage.ts b/src/language/phpLanguage.ts index 48cec106..ba3ceec5 100644 --- a/src/language/phpLanguage.ts +++ b/src/language/phpLanguage.ts @@ -1,3 +1,4 @@ +import { functionNames } from './helpers.js' import { Language } from './types.js' export const phpLanguage: Language = { @@ -20,7 +21,7 @@ export const phpLanguage: Language = { ` ( (comment)+ @expression - (#match? @expression "Given|When|Then") + (#match? @expression "${functionNames}") ) @root `, ], diff --git a/src/language/pythonLanguage.ts b/src/language/pythonLanguage.ts index 6ee6ab08..6ce4ba15 100644 --- a/src/language/pythonLanguage.ts +++ b/src/language/pythonLanguage.ts @@ -1,5 +1,6 @@ import { StringOrRegExp } from '@cucumber/cucumber-expressions' +import { functionNames } from './helpers.js' import { Language, TreeSitterSyntaxNode } from './types.js' export const pythonLanguage: Language = { @@ -72,7 +73,7 @@ export const pythonLanguage: Language = { arguments: (argument_list (string) @expression) ) ) - (#match? @method "(given|when|then)") + (#match? @method "(${functionNames.toLowerCase()})") ) @root `, ], diff --git a/src/language/rubyLanguage.ts b/src/language/rubyLanguage.ts index 47eb6356..3acc0e20 100644 --- a/src/language/rubyLanguage.ts +++ b/src/language/rubyLanguage.ts @@ -1,7 +1,7 @@ import { StringOrRegExp } from '@cucumber/cucumber-expressions' import { RegExps } from '@cucumber/cucumber-expressions/dist/cjs/src/ParameterType' -import { childrenToString, filter, NO_QUOTES } from './helpers.js' +import { childrenToString, filter, functionNames, NO_QUOTES } from './helpers.js' import { Language, NodePredicate, TreeSitterSyntaxNode } from './types.js' export const rubyLanguage: Language = { @@ -76,7 +76,7 @@ export const rubyLanguage: Language = { (regex) @expression ] ) - (#match? @method "(Given|When|Then)$") + (#match? @method "(${functionNames})$") ) @root `, ], diff --git a/src/language/rustLanguage.ts b/src/language/rustLanguage.ts index 8dbedd2b..8e5b32a1 100644 --- a/src/language/rustLanguage.ts +++ b/src/language/rustLanguage.ts @@ -1,3 +1,4 @@ +import { functionNames } from './helpers.js' import { Language, TreeSitterSyntaxNode } from './types.js' export const rustLanguage: Language = { @@ -82,7 +83,7 @@ export const rustLanguage: Language = { ) ) ) - (#match? @meta-name "given|when|then") + (#match? @meta-name "${functionNames.toLowerCase()}") ) (function_item) ) @root `, diff --git a/src/language/tsxLanguage.ts b/src/language/tsxLanguage.ts index edd43257..6d648ca4 100644 --- a/src/language/tsxLanguage.ts +++ b/src/language/tsxLanguage.ts @@ -1,7 +1,7 @@ import { StringOrRegExp } from '@cucumber/cucumber-expressions' import { RegExps } from '@cucumber/cucumber-expressions' -import { childrenToString, filter, NO_QUOTES } from './helpers.js' +import { childrenToString, filter, functionNames, NO_QUOTES } from './helpers.js' import { NO_EXPRESSION } from './SourceAnalyzer.js' import { Language, TreeSitterSyntaxNode } from './types.js' @@ -80,7 +80,7 @@ export const tsxLanguage: Language = { (template_string) @expression ] ) - (#match? @function-name "Given|When|Then") + (#match? @function-name "${functionNames}") ) @root `, ], diff --git a/test/language/testdata/javascript/StepDefinitions.js b/test/language/testdata/javascript/StepDefinitions.js index 34dc08bc..825f6b31 100644 --- a/test/language/testdata/javascript/StepDefinitions.js +++ b/test/language/testdata/javascript/StepDefinitions.js @@ -2,6 +2,8 @@ import { Given } from '@cucumber/cucumber' import assert from 'assert' import React from 'react' +const Gegeven = Given; + const dummyJsx = Hello Given('a {uuid}', async function (uuid) { @@ -24,6 +26,6 @@ Given('an {undefined-parameter}', async function (date) { assert(date) }) -Given("the bee's knees", async function () { +Gegeven("the bee's knees", async function () { assert(true) })