Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RegularExpression constructor is not filtering non-capturing groups #211

Closed
aslakhellesoy opened this issue May 23, 2017 · 6 comments · Fixed by #220
Closed

RegularExpression constructor is not filtering non-capturing groups #211

aslakhellesoy opened this issue May 23, 2017 · 6 comments · Fixed by #220
Labels
🐛 bug Defect / Bug

Comments

@aslakhellesoy
Copy link
Contributor

From @Jordyderuijter on May 23, 2017 11:4

Hi there,

It seems like there is a bug in the RegularExpression class in the cucumber-expressions dependency.
The regex in this constructor looks for capturing groups when processing steps using the regex:

/\(([^(]+)\)/g

This regex finds everything between braces (a.k.a. capturing groups), but it also accepts non-capturing groups. This causes the constructor to generate parameter types for the non capturing groups (instead of the capturing groups only).

These parameter types are used in the buildArguments function, but are only applied to capturing groups, since the given step regex filters out the non-capturing groups correctly.

I would expect the RegularExpression constructor to filter out these capturing groups correctly.

The step and step definitions I used to reproduce the issue are:

Step:
I can cancel the 1st slide upload

Step definition:
(\S+) ?(can|cannot)? (?:delete|cancel) the (\d+)(?:st|nd|rd|th) (attachment|slide) ?(?:upload)?

In this case 7 parameter types are being generated by the constructor, while it should only create 4, since 3 of them are non-capturing groups. As a result, the parameter type that belongs to (\d+) is being applied to (attachment|slide), treating it as an integer. This results into a NaN value that is being passed to my step definition.

Version info:

  • Cucumberjs: 2.1.0
  • Node: v6.9.1
  • Npm: 3.10.8

Copied from original issue: cucumber/cucumber-js#837

@aslakhellesoy
Copy link
Contributor Author

Dupe of #131

@aslakhellesoy
Copy link
Contributor Author

My bad - this is not a dupe of #131 so I'm reopening it.

We now have 3 proposed fixes for this issue:

I'm going to improve #220 with the technique from #216 and merge that.

I realise this implementation doesn't handle nested groups, as explained in comments in #216, but we'll handle that in a different issue.

@aslakhellesoy
Copy link
Contributor Author

Fixed by #220

@aslakhellesoy
Copy link
Contributor Author

I'm about to make a change that would disallow optional capture groups such as (can|cannot)?. Groups will have to be non-capturing ((?:can|cannot)?) or required/non-optional ((can|cannot)).

So the example above would have to be one of the following:

(\S+) ?(can|cannot) (?:delete|cancel) the (\d+)(?:st|nd|rd|th) (attachment|slide) ?(?:upload)?

or:

(\S+) ?(?:can|cannot)? (?:delete|cancel) the (\d+)(?:st|nd|rd|th) (attachment|slide) ?(?:upload)?

Can you see any issues with this @Jordyderuijter?

@Jordyderuijter
Copy link

This would be a breaking change, but I think it can easily be solved by using a format like this:
(can|cannot|)

In this case you can still use a capturing group without making it optional.

@lock
Copy link

lock bot commented Oct 24, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Oct 24, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🐛 bug Defect / Bug
Projects
None yet
2 participants