-
-
Notifications
You must be signed in to change notification settings - Fork 57
Description
π What did you see?
When creating a custom param definition, the transformer funcion does not received nested capturing groups.
β What did you expect to see?
As javascript developer, I expect regex capturing groups to conform Regex Ecamscript standard and capture nested groups
π¦ Which tool/library version are you using?
https://www.npmjs.com/package/@cucumber/cucumber-expressions/v/16.1.2
π¬ How could we reproduce it?
Create a new npm package with your prefered typescript setup (the bug is also recreated with plain javascript).
In the package.json, install @cucumber/[email protected]
dependency
Define a custom parameter with nested captured groups:
import { defineParameterType } from '@cucumber/cucumber';
defineParameterType({
name: 'foo',
regexp: /((foo))/,
transformer: function (
firstGroup: string,
secondGroup: string
): string[] {
return [firstGroup, secondGroup]
},
});
Then, write any step definition and feature involving this custom definition
import { Given, Then, When } from '@cucumber/cucumber';
Given('{foo}', function(foo: string[]): void { console.log(foo) });
When('bar', function(): void {});
Then('baz', function(): void {});
Given foo
When bar
Then baz
Then, create a minimal config testing the feature processing the custom parameter and the step definitions and have a look at the console. Instead of ['foo', 'foo']
, ['foo', undefined]
is printed instead.
π Any additional context?
It seems the capturing groups are internally represented as a tree. Cucumber relies on TreeRegexp
to create a GroupBuilder
for the purpose of capturing regex groups. These groups are represented as a tree and only the root ones are passed to the custom definition transformer, ignoring any children groups.
Having a look at the Argument
class:
public getValue<T>(thisObj: unknown): T | null {
const groupValues = this.group ? this.group.values : null
return this.parameterType.transform(thisObj, groupValues)
}
group.values
are passed to the transformer:
export default class Group {
constructor(
public readonly value: string,
public readonly start: number | undefined,
public readonly end: number | undefined,
public readonly children: readonly Group[]
) {}
get values(): string[] | null {
return (this.children.length === 0 ? [this] : this.children).map((g) => g.value)
}
}
As you can see granchildren groups are never included. I would expect nested groups to be included as Ecmascript Regex spec states
This text was originally generated from a template, then edited by hand. You can modify the template here.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status