[rspec-devel] rspec.should embrace_change

David Chelimsky dchelimsky at gmail.com
Tue Jan 9 23:11:33 EST 2007


All,

I just committed a small change to rspec that could have far-reaching
implications:

context "a dog" do
  specify "should say hi" do
    dog = Dog.new
    dog.should say_hi("woof")
  end
end

The thing to pay attention to there is this line:

    dog.should say_hi("woof")

What's happening is that #should is accepting the result of
say_hi("woof"), which is a method that returns an object that responds
to #met_by?(target) and #failure_message:

class SayHi
  def initialize(greeting)
    @expected = greeting
  end

  def met_by?(target)
    @actual = target.say_hi
    @actual == @expected
  end

  def failure_message
    "expected say_hi to return #{@expected} but got {@actual}"
  end
end

This allows us to do a couple of things. One, we can move towards
having only one method on Object and NO SUGAR! We can do this by
converting all of the current should_xyz methods into xyz methods that
return XyzExpectation instances. These methods would need to be made
available to all specs.

We can deprecate the existing should_xyz methods and, when the time
comes to remove them, modifying specs is just a matter of replacing
should_xyz with should xyz. Simple!

Second, it opens the door for custom expectations:

module MyCustomExpectations
  class SayHi
  ...
  end
end

context "visiting day at the zoo" do
  include MyCustomExpectations
  specify "a dog should say hi" do
    Dog.new.should say_hi('arf')
  end
  specify "a cow should say hi" do
    Cow.new.should say_hi('moo')
  end
end

I'm really excited about the implications of this and I'm curious to
hear your feedback.

David


More information about the rspec-devel mailing list