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

3.0.0.pre.2 - regexp no longer matching correct amount of capture groups #1191

Closed
JeanMertz opened this issue Aug 31, 2017 · 5 comments
Closed
Assignees
Milestone

Comments

@JeanMertz
Copy link

This step definition:

Given(/^I have a( trial)? subscription( with (\d+) days left)?$/) do |trial, with_days_left, days_left|
end

worked in Cucumber pre 3.0. In the latest 3.0 release, it returns:

Your block takes 3 arguments, but the Regexp matched 2 arguments. (Cucumber::Glue::ArityMismatchError)

Even though there are clearly three capture groups (does it trip up because of the nested capture?)

@mattwynne
Copy link
Member

@JeanMertz did you want to capture three groups, or are you just noting a change in behaviour?

cc @aslakhellesoy - FYI it looks like the introduction of #1156 might not be fully backward compatible - is that a likely analysis do you think?

@JeanMertz
Copy link
Author

@mattwynne correct, I want to capture three groups. We solved this for now by splitting up the one step into two, so we don't need the nested regex anymore.

@aslakhellesoy aslakhellesoy self-assigned this Sep 5, 2017
@aslakhellesoy
Copy link
Contributor

Looks like a regression. I'll look into this one.

@aslakhellesoy aslakhellesoy modified the milestone: 3.0 Sep 7, 2017
@aslakhellesoy
Copy link
Contributor

Ok, this is a backwards-incompatible for sure, but it's by design. Only top level capture groups are counted.

This is a consequence of parameter type transforms being able to handle capture groups. I'll try to explain with a couple of examples.

Both Cucumber Expressions and Regular Expressions are now managed by the cucumber-expressions library. One of the things this library lets you do is to define transformer functions, for example:

ParameterType(
  name: 'colour',
  regexp: /red|blue|yellow/,
  transformer: -> (colour) { Colour.new(colour) }
)

You can also use capture groups in the regexp:

ParameterType(
  name: 'flight',
  regexp: /(\w+)-(\w+)/,
  transformer: -> (from, to) { Flight.new(from, to) }
)

The Cucumber Expression a {flight} gets translated to /^ a ((\w+)-(\w+))/. This regexp has 3 capture groups, but the library will group them into a tree representing the nesting of the groups. In this case, a tree with 1 child, which has 2 children. Only the top-level groups become arguments to the step definition. If a top-level group has children, they all get passed to the transformer.

Your step definition could be translated to:

Given('I have a {subscription}') do |subscription|
end

ParameterType(
  name: 'subscription',
  regexp: /(trial )?subscription(?: with (\d+) days left)?/,
  transformer: -> (trial, days_left) { Subscription.new(!!trial, days_left.nil? ? nil : days_left.to_i) }
)

@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
None yet
Projects
None yet
Development

No branches or pull requests

3 participants