diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cfa5313..a10b78f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed +- (Java) Detect step definition patterns with concatenated strings ([#202](https://github.com/cucumber/language-service/pull/202)) +- (Java) Support `@And` and `@But` step definition annotations ([#202](https://github.com/cucumber/language-service/pull/202)) ## [1.5.0] - 2024-04-08 ### Added diff --git a/src/language/javaLanguage.ts b/src/language/javaLanguage.ts index 63025817..dc76aab3 100644 --- a/src/language/javaLanguage.ts +++ b/src/language/javaLanguage.ts @@ -18,9 +18,12 @@ export const javaLanguage: Language = { return stringLiteral(node) }, toStepDefinitionExpression(node) { - const text = stringLiteral(node) - const hasRegExpAnchors = text[0] == '^' || text[text.length - 1] == '$' - return hasRegExpAnchors ? new RegExp(text) : text + if (node.type === 'string_literal') { + const text = stringLiteral(node) + const hasRegExpAnchors = text[0] == '^' || text[text.length - 1] == '$' + return hasRegExpAnchors ? new RegExp(text) : text + } + return collectStringFragments(node).join('') }, defineParameterTypeQueries: [ @@ -78,23 +81,33 @@ export const javaLanguage: Language = { `, ], defineStepDefinitionQueries: [ - ` -(method_declaration - (modifiers - (annotation - name: (identifier) @annotation-name - arguments: (annotation_argument_list - [ - (string_literal) @expression - ] + `(method_declaration + (modifiers + (annotation + name: (identifier) @annotation-name + arguments: (annotation_argument_list + [ + (string_literal) @expression + ] + ) + ) ) - ) - ) - (#match? @annotation-name "Given|When|Then") -) @root -`, + (#match? @annotation-name "Given|When|Then|And|But") + ) @root`, + `(method_declaration + (modifiers + (annotation + name: (identifier) @annotation-name + arguments: (annotation_argument_list + [ + (binary_expression) @expression + ] + ) + ) + ) + (#match? @annotation-name "Given|When|Then|And|But") + ) @root`, ], - snippetParameters: { int: { type: 'int', name: 'i' }, float: { type: 'float', name: 'f' }, @@ -126,3 +139,12 @@ export function stringLiteral(node: TreeSitterSyntaxNode | null): string { function unescapeString(s: string): string { return s.replace(/\\\\/g, '\\') } +function collectStringFragments(node: TreeSitterSyntaxNode): string[] { + if (node.type === 'string_fragment') { + return [unescapeString(node.text.replace('(?i)', ''))] + } + if (node.type === 'binary_expression' || node.type === 'string_literal') { + return node.children.flatMap(collectStringFragments) + } + return [] +} diff --git a/test/language/testdata/java/StepDefinitions.java b/test/language/testdata/java/StepDefinitions.java index 4a183e23..9270d01a 100644 --- a/test/language/testdata/java/StepDefinitions.java +++ b/test/language/testdata/java/StepDefinitions.java @@ -1,27 +1,33 @@ +import io.cucumber.java.en.And; +import io.cucumber.java.en.But; import io.cucumber.java.en.Given; +import io.cucumber.java.en.When; +import io.cucumber.java.en.Then; public class StepDefinitions { - @Given("a {uuid}" ) - void a_uuid(String uuid) { + @Given("a {uuid}") + void a_uuid(String uuid) { } - @Given("a {date}" ) - void a_date(Date date) { + @When("a {date}") + void a_date(Date date) { } - @Given("a {planet}" ) - void a_date(Date date) { + @Then("a {planet}") + void a_date(Date date) { } - @Given("^a regexp$" ) - void a_regexp() { + @And("^a regexp$") + void a_regexp() { } - @Given("an {undefined-parameter}" ) - void an_undefined_parameter(Date date) { + @But("an {undefined-parameter}") + void an_undefined_parameter(Date date) { } - @Given("the bee's knees" ) - void the_bees_knees(Date date) { + @Given( + "the " + "bee's " + + "knees") + void the_bees_knees(Date date) { } } diff --git a/test/language/testdata/python/StepDefinitions.py b/test/language/testdata/python/StepDefinitions.py index 75d66ea8..cc61457f 100644 --- a/test/language/testdata/python/StepDefinitions.py +++ b/test/language/testdata/python/StepDefinitions.py @@ -1,4 +1,5 @@ """Port of givens for testdata.""" + from behave import step, given, when, then