Reputation: 238777
I'm new to Ruby. I'm trying to figure out how to write a nested case statement. Here is an example of what I am trying to do:
# cucumber, webrat paths.rb
def path_to(page_name)
case page_name
when /the "?(.*)"? event registration homepage/ then
case $1
when '2011 CIO GL Global' then '/event/index/id/236'
when '2011 CIO IS Chicago' then '/event/index/id/275'
when '2011 CIO ES Denver' then '/event/index/id/217'
when '2011 CIO ES Vancouver, BC' then '/event/index/id/234'
else
raise "Can't find mapping for \"#{$1}\" to a path.\n" +
"Now, go and add a mapping in #{__FILE__}"
end
when /the contact match verification page/
'/attendee/user-verification'
end
end
In my feature file it says:
When I go to the "2011 CIO IS Chicago" event registration homepage
It's failing on this step because its raising the exception mentioned above, even though I have it defined in my case statement above. What am I doing wrong?
Upvotes: 4
Views: 4660
Reputation: 12574
I would approach this a little differently. In your cucumber feature, I suggest changing the wording like so:
When I go to the registration homepage for the event named "2011 CIO IS Chicago"
And in your paths.rb
file I would handle all events with a single regexp, like so:
when /the registration homepage for the event named "?(.*)"?/ then
event = Event.find_by_name($1)
raise "could not find an event with name: #{$1}" if event.blank?
event_path(event)
# or create the route manually like so:
# "event/index/id/#{event.id}"
This relies on your Event
model having a method that can find an event given its name (in this case I assumed find_by_name
), and a resourceful route set up for :events
.
Upvotes: 0
Reputation: 778
The problem is in your regex. Try removing the last ?
as it's causing the "
to be optional and the greedy search up front (.*)
is putting it in the match $1
.
Observe:
> s = 'the "2011 CIO IS Chicago" event registration homepage'
> /the "?(.*)"? event registration homepage/.match s #=> <MatchData "the \"2011 CIO IS Chicago\" event registration homepage" 1:"2011 CIO IS Chicago\"">
> $1 #=> "2011 CIO IS Chicago\""
> /the "?(.*)" event registration homepage/.match s #=> #<MatchData "the \"2011 CIO IS Chicago\" event registration homepage" 1:"2011 CIO IS Chicago">
> $1 #=> "2011 CIO IS Chicago"
Edit: if you want the "
to be optional you'll probably need to do something like: (?:"(.*)"|(.*))
. And then you'll need to use a nil guard to find out which reference is returned. $1 || $2
.
Upvotes: 0
Reputation: 1597
Yeah, the second question mark is confusing the regular expression.
The expression:
.*b?
can match the string "axb" in two ways, either with .* matching the entire thing, or with .* matching the 'ax' and 'b?' matching the 'b'. The regular expression algorithm is "greedy" - it prefers to match as much as it can as early as it can.
I'd rewrite the regular expression as:
when /the "?([^"]*)"? event registration homepage/ then
to make sure that that $1 doesn't end up with any double quotes in it...
Upvotes: 4
Reputation: 146093
It works for me. How are you testing it?
Update: Aha, it's because your regular expression is matching the trailing quote, so $1 ends in a quotation mark which is not present in your inner case.
There are a few ways to fix this.
"?[^"]*"?
..."?'
"?(.*?)"?
.Upvotes: 1
Reputation: 498
Change
when /the "?(.*)"? event registration homepage/ then
to
when /the "?(.*)" event registration homepage/ then
Upvotes: 1