[rspec-users] Step matchers

Pat Maddox pergesu at gmail.com
Sun Oct 14 20:18:52 EDT 2007


On 10/14/07, Pat Maddox <pergesu at gmail.com> wrote:
> On 10/14/07, David Chelimsky <dchelimsky at gmail.com> wrote:
> > On 10/14/07, David Chelimsky <dchelimsky at gmail.com> wrote:
> > > On 10/14/07, Pat Maddox <pergesu at gmail.com> wrote:
> > > > I think we all know that the readability of steps isn't great right
> > > > now, and in fact there's a very recent thread that discusses just
> > > > that.  It was that recent thread that prompted me to explore this a
> > > > bit.
> > > >
> > > > The basic idea is that you define step matchers, which have a regex,
> > > > and then you match step names against that regex.  Kind of tough for
> > > > me to explain so I'll just link to some code :)
> > > >
> > > > spec: http://pastie.caboo.se/107116
> > > > impl: http://pastie.caboo.se/107117
> > > >
> > > > Instead of writing
> > > > Given "a user named __ who is __ years old", "Pat Maddox", 22
> > > >
> > > > it allows you to write
> > > > Given "a user named Pat Maddox who is 22 years old"
> > > >
> > > > I wrote it out as a separate matcher because it was just easiest to do
> > > > it that way while I explored this approach, no messing around with
> > > > RSpec internals to get it to really work.  However if we went this
> > > > route the structure would certainly be different.
> > > >
> > > > Hopefully you can get the idea from the example code.  Ideally what I
> > > > would like is to write step libraries that are external to the stories
> > > > themselves.  The stories would be much clearer because the
> > > > implementation would not be embedded, and the step names themselves
> > > > would make a lot more sense.
> > > >
> > > > wdyt?
> > >
> > > LOL - I just suggested something like this in the other thread you
> > > cite. Though your idea strikes me as far more flexible and usable.
> > > Well done!!!!
> >
> > This just occurs to me. If we do away with the need for special
> > characters/positioning, blocks, etc, we should be able to do just
> > this, no?
> >
> > Given a savings account with 100 dollars
> > When the account owner asks for 101 dollars
> > Then the account owner should receive 0 dollars
> > Then the account should have 100 dollars
> >
> > Look mom - no quotes!
>
> How would you plan to implement this?  Read in a text file, strip the
> leading Given/When/Then and match each line?
>
> The one catch I see is that because stories are structured, you still
> need something to demarcate steps within a scenario and scenarios
> within a story.
>
> In general, I prefer your syntax, making it look like a plain-text
> spec instead of Ruby code.  I question whether it's a big enough win
> to justify writing a parser instead of simply writing valid Ruby.  At
> this point, personally I'd say no, but I can see how it would be nice
> for customers and spec readers/maintainers.
>
> Actually, would you mind showing an example of a full spec with this
> syntax?  Maybe something like:
>
> Story: Creating a post
>   As a user
>   I want post to my blog
>   So that I can share information with my fellow Rubyists
>
>   Scenario: anonymous user
>     Given no blog posts in the system
>
>     When I POST to /posts with title=Post Title, body=Post body
>
>     Then the page should show Post title
>     And the page should show Post body
>     And the page should show Posted by: 'anonymous'
>
>   Scenario: logged in user
>     Given no blog posts in the system
>     And a user named Pat
>     And logged in as Pat
>
>     When I POST to /posts with title=Custom Title, body=Custom body
>     And the page should show Custom Title
>     And the page should show Custom body
>     And the page should show Posted by: 'Pat'
>
> Actually a parser for this would be quite simple, and I definitely
> prefer it to the Ruby version.  It makes sense to use the interpreter
> when you're defining step implementations inline, but if you're not
> then it doesn't really add any value and looks/feels weird.
>
> One other thing I thought of is that we can combine spec matchers with
> your ? syntax idea.  Basically, regexps don't really get you anything
> in this type of situation, since you're going to be matching the whole
> string, and regexp doesn't convert data types for you.  You could
> define a step like
>
> Step "I like to eat, eat, eat ? and ?" do |food1, food2|
>   @fav_foods ||= [food1, food2]
> end
>
> and then when it gets used in the spec, it's simply
> Given I like to eat, eat, eat apples and bananas
>
> Under the hood, the ? get converted to (.*), which again works fine
> since you're matching the entire string exactly anyway.  It's a lot
> more readable than full-blown regexps.
>
> Pat
>

Also, a 100% plain text spec makes it easier to implement something like
Uses accounting vocabulary

for importing step libraries without it looking or feeling like real
code.  That's another feature I want out of this, but I probably won't
be needing it this week.  Still it'll be nice to have at some point.

Pat


More information about the rspec-users mailing list