cucumber / cucumber/language-service

Cucumber Expressions with optionals interpreted as Regular Expressions

Open
#191 3 comments 0 reactions 0 assignees View on GitHub
:bug: bug python
Dominant language
TypeScript
Stars
29
Forks
44
PR merge metrics
No merged PRs in 30d

Description

### 👓 What did you see?

- Cucumber Expressions written in Python containing optionals are considered 'undefined' by the Language Service
- However, the step successfully matches and executes when using the Python implementation of Cucumber Expressions directly

No matches with optionals

### ✅ What did you expect to see?

- The step text is considered 'defined'

### 📦 Which tool/library version are you using?

- Node - v18.16.0
- Cucumber Language Service - v1.4.1

### 🔬 How could we reproduce it?

Steps to reproduce the behavior:

1. Open Visual Studio Code
2. Install the official Cucumber extension
3. Create a feature file inside the `features` directory` containing

```gherkin
Feature: Colour selection

Scenario:
Given I select the theme colour "red"
```

4. Create a step definition inside the `features/steps` directory containing

```python
from behave import given

@given('I select the theme colo(u)r "{color}"')
def step_when(context):
...
```

5. Observe the step in the feature file is highlighted as 'undefined'

### 📚 Any additional context?

The Language Service Python implementation prioritises Regular Expressions (checks first) over Cucumber Expressions.

A criteria for determining whether a pattern is a Regular Expression is whether it contains brackets `()` through `specialCharsMatch`.

https://github.com/cucumber/language-service/blob/6a35176c10828812e6fc86b0a5ab3dc774852906/src/language/pythonLanguage.ts#L135-L142

As a result, any Cucumber Expression containing an optional will be treated as a Regular Expression and the optional will instead be considered a capture group.

```console
0: r {expression: 'I am on the profile customisation/settings page', parameterTypeRegistry: Aa, parameterTypes: Array(0), ast: ti, treeRegexp: r}
1: Us {regexp: /I select the theme colo(u)r "{color}"/, parameterTypeRegistry: Aa, treeRegexp: r}
```

A challenge is that in some languages a Regular Expression can be denoted by special prefix and suffix characters, whereas in Python, strings are similar in either case. See Java implementation:

https://github.com/cucumber/language-service/blob/6a35176c10828812e6fc86b0a5ab3dc774852906/src/language/javaLanguage.ts#L20-L24

#### Brackets usage in Regular Expressions with Python

[Official Python documentation on regular expressions](https://docs.python.org/3/library/re.html) outline the use of brackets as follows:

`(...)`

Matches whatever regular expression is inside the parentheses, and indicates the start and end of a group; the contents of a group can be retrieved after a match has been performed, and can be matched later in the string with the \number special sequence, described below. To match the literals '(' or ')', use \( or \), or enclose them inside a character class: [(], [)].

`(?...)`

This is an extension notation (a '?' following a '(' is not meaningful otherwise). The first character after the '?' determines what the meaning and further syntax of the construct is. Extensions usually do not create a new group; (?P...) is the only exception to this rule. Following are the currently supported extensions.

#### Further References

- [Using Regular Expressions with Behave](https://jenisys.github.io/behave.example/step_matcher/re_matcher.html)
- [Behave Regular Expressions syntax](https://behave.readthedocs.io/en/stable/regular_expressions.html)

Contributor guide

Open the contributing guide

Research direction

Start in src/language/pythonLanguage.ts around specialCharsMatch, then compare the language-detection approach in src/language/javaLanguage.ts. Trace how Python step patterns containing parentheses are classified, and identify the relevant language-service tests to run. Done means a Cucumber Expression with an optional is defined while supported Python regular expressions still work.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, typescript, vscode
Domain
developer-experience, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.