cucumber expressions; capture optional text or alternation

563 views
Skip to first unread message

r.gro...@gmail.com

unread,
Dec 12, 2017, 11:15:52 AM12/12/17
to Cukes
hello group,

after getting some deprecation messages from cucumber because of still using Transform, I am trying to modify my code to make use of the new style parameter types.
In trying to do so, I get some problems I have to resolve.

One is that cucumber expression syntax does not mix with regexp syntax.

I started with

Then /^the string has (not )?(#{DQSRE})$/ do |not, inh|
   
if not.nil?
        expect
( @string).to match /#{inh}/
   
else
        expect
( @string).not_to match /#{inh}/
   
end
end



DQSRE being a transform.

With help of the help Aslak's blog 'Upgrading to Cucumber-Ruby 3.0.0' I changed this to a
ParameterType with name dqs and


Then 'the string has (not ){dqs}' do |not, dqs|


But now the string is matched, but it appears that the optional 'not' string is not captured anymore, resulting in a message
Your block takes 2 arguments, but the Regexp matched 1 argument. (Cucumber::Glue::ArityMismatchError)

Changing back to a regular expression
 Then /the string has (not )?{dqs}/ do |not, dqs|

does not work because the {dqs} syntax is not a valid regular expression replacement for using the parametertype.

When I want to have a optional text captured, do I have to create a parametertype for that too (I guess the same goes for alternation, which is not captured either)?
Or am I overlooking something?

thanks in advance, Ruud

Chuck van der Linden

unread,
Dec 13, 2017, 1:15:58 PM12/13/17
to Cukes
I've used optional capture groups as you are doing above,  (Picked it up from this great blog posting from Cory Schires) and I have to agree that it would be dissapointing to have to discontinue doing that when using the new alternatives to transforms.  

Although I think there is also an argument to be made that in this particular instance, doing this as two separate steps results in easier to read code, and in this case even one fewer line of code

Then 'the string has {dqs}' do |dqs|

    expect
( @string).to match /#{inh}/
end


Then 'the string does not have {dqs}' do |dqs|

    expect
( @string).not_to match /#{inh}/
end

which might be your best workaround until we see if someone has a better way to do optional capture groups in cucumber expression syntax.  (I'd also like to do non-capture groups as well,. Good uses for which are also documented in the blog posting referenced above. )

aslak hellesoy

unread,
Dec 13, 2017, 4:00:43 PM12/13/17
to Cucumber Users
See replies inline

You *could* use the following cucumber expression: ''the string has {neg}{dqs}"

And a parameter type for {neg} with:

  name: 'neg',
  regexp: /(not )?/,
  transformer: -> (s) { s == 'not '}

However, I wouldn't do that. The added complexity isn't worth it, and I always try to only define parameter types that represent something from my problem domain.
I'd do this instead:

Then 'the string has {dqs}' do |inh|
  expect(@string).to match /#{inh}/
end

Then 'the string has not {dqs}' do |inh|
  expect(@string).not_to match /#{inh}/
end

"Duplication! Heresy!" I hear some people cry. I don't care. Clarity and simplicity trumps DRY.

Aslak

thanks in advance, Ruud

--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

aslak hellesoy

unread,
Dec 13, 2017, 4:02:46 PM12/13/17
to Cucumber Users
Haha, I just read your response after replying myself, and saw that you beat me to it!

--

r.gro...@gmail.com

unread,
Dec 14, 2017, 7:48:40 AM12/14/17
to Cukes
hi Chuck and  Aslak,
thanks for your explanation.
In de meantime, rewrote the step using plain regular expression and not using a transform at al. But you convinced me that it is better to have readable code and to use TWO definition to do the same.
And it is good to get some experience with Cucumber expressions as well.

Ruud

Chuck van der Linden

unread,
Dec 14, 2017, 1:21:12 PM12/14/17
to Cukes


On Wednesday, December 13, 2017 at 1:02:46 PM UTC-8, Aslak Hellesøy wrote:
Haha, I just read your response after replying myself, and saw that you beat me to it!

HAH   "ninja a cucumber dev with the correct answer"  Achievement Unlocked!  HAR!

so'kay, validates my answer to see it also coming from you...

and... it's NOT the same code inside each definition, so it is not violating DRY if you ask me.
and I agree about simplicity and clarity being paramount.

So what about the second aspect to this I raised in my answer?  how do we express non capture groups in the new expression syntax?  

aslak hellesoy

unread,
Dec 14, 2017, 2:58:01 PM12/14/17
to cu...@googlegroups.com
Can you give (me )an example of a regexp?
I’ll translate it for you.

Chuck van der Linden

unread,
Dec 15, 2017, 1:15:56 PM12/15/17
to Cukes


On Thursday, December 14, 2017 at 11:58:01 AM UTC-8, Aslak Hellesøy wrote:


On Thursday, December 14, 2017, Chuck van der Linden <sqa...@gmail.com> wrote:


On Wednesday, December 13, 2017 at 1:02:46 PM UTC-8, Aslak Hellesøy wrote:
Haha, I just read your response after replying myself, and saw that you beat me to it!

HAH   "ninja a cucumber dev with the correct answer"  Achievement Unlocked!  HAR!

so'kay, validates my answer to see it also coming from you...

and... it's NOT the same code inside each definition, so it is not violating DRY if you ask me.
and I agree about simplicity and clarity being paramount.

So what about the second aspect to this I raised in my answer?  how do we express non capture groups in the new expression syntax?  



Can you give (me )an example of a regexp?
I’ll translate it for you.

Sure thing... So here's an example both of non-capturing groups combined with alternation, also with a single character that may or may not occur

And /^once the files? (?:have|has) finished processing$/ do

That would match both of the following
  • And once the file has finished processing
  • And once the files have finished processing

Another example of one I use a lot 

I (?:have |)(?:log|logged) in as: (\w+)

That's a step I use both as a Given or a When, hence the change in tense.. so that capture would match both
  • Given I have logged in as: fizz
  • When I log in as: buzz
(If we have nothing in the docs showing how to do those sorts of step definitions via the new expression, I think it would be good to include them.. 

--Chuck

--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+un...@googlegroups.com.

aslak hellesoy

unread,
Dec 18, 2017, 8:18:20 AM12/18/17
to Cucumber Users
See replies inline

On Fri, Dec 15, 2017 at 6:15 PM, Chuck van der Linden <sqa...@gmail.com> wrote:


On Thursday, December 14, 2017 at 11:58:01 AM UTC-8, Aslak Hellesøy wrote:


On Thursday, December 14, 2017, Chuck van der Linden <sqa...@gmail.com> wrote:


On Wednesday, December 13, 2017 at 1:02:46 PM UTC-8, Aslak Hellesøy wrote:
Haha, I just read your response after replying myself, and saw that you beat me to it!

HAH   "ninja a cucumber dev with the correct answer"  Achievement Unlocked!  HAR!

so'kay, validates my answer to see it also coming from you...

and... it's NOT the same code inside each definition, so it is not violating DRY if you ask me.
and I agree about simplicity and clarity being paramount.

So what about the second aspect to this I raised in my answer?  how do we express non capture groups in the new expression syntax?  



Can you give (me )an example of a regexp?
I’ll translate it for you.

Sure thing... So here's an example both of non-capturing groups combined with alternation, also with a single character that may or may not occur

And /^once the files? (?:have|has) finished processing$/ do


Corresponding Cucumber Expression:

"once the file(s) have/has finished processing"
 
That would match both of the following
  • And once the file has finished processing
  • And once the files have finished processing

Another example of one I use a lot 

I (?:have |)(?:log|logged) in as: (\w+)


Corresponding Cucumber Expression:

"I (have )log/logged in as: {word}"
 
That's a step I use both as a Given or a When, hence the change in tense.. so that capture would match both
  • Given I have logged in as: fizz
  • When I log in as: buzz
(If we have nothing in the docs showing how to do those sorts of step definitions via the new expression, I think it would be good to include them.. 


--Chuck

--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
Posting rules: http://cukes.info/posting-rules.html
---
You received this message because you are subscribed to the Google Groups "Cukes" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cukes+unsubscribe@googlegroups.com.

Chuck van der Linden

unread,
Dec 18, 2017, 1:00:12 PM12/18/17
to Cukes


On Monday, December 18, 2017 at 5:18:20 AM UTC-8, Aslak Hellesøy wrote:
See replies inline

Thank you very much, I'm starting to be a convert to this new syntax
Reply all
Reply to author
Forward
0 new messages