First cut at blockless given/when/then

Hi all,

I committed a first cut at blockless Givens/Whens/Thens to RSpec’s
trunk:

cd /path/to/rspec/project
svn up
cd rspec
bin/spec examples/story/calculator.rb

Take a look at examples/story/calculator.rb to see what’s going on.

Needs docs!!!

Thoughts welcome.

I’ve also got a cut at the plain text parser checked in, but it’s not
hooked up to anything yet. However, now that we can do blockless GWT,
hooking the parser up to the rest is just a matter of a simple adapter
and logistics. Look for it in the next few days.

Cheers,
David

On 10/18/07, Wincent C. [email protected] wrote:

step_matcher(:given, “an addend of $addend”) do |addend|
end
end

then_matcher(“the sum should be $sum”) do |sum|
@sum.should == sum.to_i
end

I’d find that a little bit easier to type; what do you think?

Easier to type, sure. I’m not in love w/ the names yet though because
they sound like verb phrases - “given matcher”, “when matcher”, “then
matcher”.

How about something like match_given, match_when, match_then?

El 18/10/2007, a las 10:33, “David C.” [email protected]
escribió:

Take a look at examples/story/calculator.rb to see what’s going on.

Needs docs!!!

Thoughts welcome.

Could this:

step_matcher(:given, “an addend of $addend”) do |addend|
@adder ||= Adder.new
@adder << addend.to_i
end

step_matcher(:when, “they are added”) do
@sum = @adder.sum
end

step_matcher(:then, “the sum should be $sum”) do |sum|
@sum.should == sum.to_i
end

Be refactored to this?

given_matcher(“an addend of $addend”) do |addend|
@adder ||= Adder.new
@adder << addend.to_i
end

when_matcher(“they are added”) do
@sum = @adder.sum
end

then_matcher(“the sum should be $sum”) do |sum|
@sum.should == sum.to_i
end

I’d find that a little bit easier to type; what do you think?

Cheers,
Wincent

On 10/18/07, David C. [email protected] wrote:

 @sum.should == sum.to_i
 @sum = @adder.sum

matcher".

How about something like match_given, match_when, match_then?

I see what you’re saying. However I think it’s helpful to put the
g/w/t right at the beginning of the method name, it’s easier to
distinguish between them. You can look at the first character and
know what’s going on. With step_matcher(:given…) you have to skip
the first 12 characters. That feels noisy and dirty to me, and I
think the readability overcomes the verb phrase problem.

Though I agree with you and I’m not in love with given_matcher. hrm,
needs more thought.

Pat

On 10/18/07, Pat M. [email protected] wrote:

Could this:
step_matcher(:then, “the sum should be $sum”) do |sum|
when_matcher(“they are added”) do
they sound like verb phrases - “given matcher”, “when matcher”, "then

Though I agree with you and I’m not in love with given_matcher. hrm,
needs more thought.

What if it were wrapped in something like this:

step_matchers do
given_matcher(“an addend of $addend”) do |addend|
@adder ||= Adder.new
@adder << addend.to_i
end

when_matcher(“they are added”) do
@sum = @adder.sum
end

then_matcher(“the sum should be $sum”) do |sum|
@sum.should == sum.to_i
end
end

step_matchers provides context for the [given|when|then]_matcher
methods. WDYT?

On 10/18/07, Pat M. [email protected] wrote:

then_matcher(“the sum should be $sum”) do |sum|

or something along those lines.

I like the idea of mapping a story to a vocabulary. I just don’t like
doing it in the story text itself - seems more dev-facing than
customer-facing. But perhaps the notion of vocabulary is a good thing
to have front and center to help the customer understand the
constraints of what can be written. Need to think about that some
more.

Cheers,
David

On 10/18/07, David C. [email protected] wrote:

Easier to type, sure. I’m not in love w/ the names yet though because
think the readability overcomes the verb phrase problem.
end
step_matchers provides context for the [given|when|then]_matcher methods. WDYT?
I like that more. It also provides a natural insertion point for
naming libraries.

step_matchers(“arithmetic”) do
given_matcher(“an addend of $addend”) do |addend|
@adder ||= Adder.new
@adder << addend.to_i
end

when_matcher(“they are added”) do
@sum = @adder.sum
end

then_matcher(“the sum should be $sum”) do |sum|
@sum.should == sum.to_i
end
end

That allows you to do something like

Story: Adding numbers
uses arithmetic vocabulary

or something along those lines.

Pat

El 18/10/2007, a las 18:42, “David C.” [email protected]
escribió:

Easier to type, sure. I’m not in love w/ the names yet though because
they sound like verb phrases - “given matcher”, “when matcher”, “then
matcher”.

How about something like match_given, match_when, match_then?

That would be fine too. I mainly just wanted to avoid having to
manually pass the symbol in.

Another alternative combining your suggestion with what Pat mentioned:

step_matchers do |match|
match.given …
match.when …
match.then …
end

Which has the nice side-effect of the user being able to say
“matcher” or “m” or “foo” if he or she wants.

Cheers,
Wincent

On 10/18/07, Wincent C. [email protected] wrote:

Another alternative combining your suggestion with what Pat mentioned:

step_matchers do |match|
match.given …
match.when …
match.then …
end

That’s nice, except we don’t want methods named when and then as they
are keywords :frowning:

We could do match.given, match.event and match.outcome, but that adds
a mental mapping that we might want to avoid.

On 10/18/07, David C. [email protected] wrote:

manually pass the symbol in.
are keywords :frowning:

We could do match.given, match.event and match.outcome, but that adds
a mental mapping that we might want to avoid.

I had thought about putting the match method on string, so it becomes
“an addend of $addend”.matcher(:given) do {blah blah}

or something similar. But I don’t really like that because I want
“given” to be the first thing on the line.

Pat

On 10/18/07, David C. [email protected] wrote:

or something along those lines.

I like the idea of mapping a story to a vocabulary. I just don’t like
doing it in the story text itself - seems more dev-facing than
customer-facing. But perhaps the notion of vocabulary is a good thing
to have front and center to help the customer understand the
constraints of what can be written. Need to think about that some
more.

I know what you mean. It comes across too much as “import some_lib”
to me. Not quite sure what to do about that.

One other idea I had was sticking similar stories in subdirs, each of
which has a helper.rb file. That helper file would load up whatever
step libraries you would want to apply to each story in that dir.

Pat

El 19/10/2007, a las 0:41, “David C.” [email protected]
escribió:

end

That’s nice, except we don’t want methods named when and then as they
are keywords :frowning:

Even so, it still works. Ruby is smart enough to figure out that when
“when” and “then” appear after a period, then they’re actually
message sends:

irb> class Foo
irb> def when
irb> puts “hello world”
irb> end
irb> end
=> nil
irb> Foo.new.when
hello world
=> nil

Or is there some other complication that I’m not aware of?

Cheers,
Wincent

On 10/19/07, Wincent C. [email protected] wrote:

are keywords :frowning:
=> nil
irb> Foo.new.when
hello world
=> nil

Or is there some other complication that I’m not aware of?

You won’t be able to use a case statement in the match object. That
might be OK, but it’s a bit weird.