A Small Bug in RSpec 0.5.13

I’m doing a recreational Rails project in my infrequent spare time and using RSpec as well. After generating a controller for the

1
Game

class I noticed it failed on a very simple specification.

controller.should_be_an_instance_of GameController

The failure message was:

undefined method 'an_instance_of?' for #<GameController:0x222df78>

That looked pretty wrong. Why was it trying to call

1
an_instance_of?

. It turns out

1
a

and

1
an

are just syntactic sugar methods that just return

1
self

. So just for fun I changed to the dot notation without the underscore sugar.

controller.should.be.an.instance.of GameController

That passed with flying colors. OK, so now I know it’s just an issue with the underscores. Writing a spec to show the issue was fairly simple:

context "Underscore Example Error" do
  specify "should_be_an_instance_of fails with underscore notation" do
    lambda { "example".should_be_an_instance_of String }.should_raise NoMethodError
  end
  specify "should.be.an.instance.of fails with underscore notation" do
    lambda { "example".should_not_be_an_instance_of Fixnum }.should_raise NoMethodError
  end
  specify "should_be_a_kind_of should fails underscore notation" do
    lambda { "example".should_be_a_kind_of Object }.should_raise NoMethodError
  end
  specify "should.not_be_a_kind_of fails with underscore notation" do
    lambda { "example".should_not_be_a_kind_of Fixnum }.should_raise NoMethodError
  end   
end

The bug appears to be with the following method in

def method_missing(sym, *args, &block)
        if __is_sweetened? sym
          object = self
          calls = sym.to_s.split("_")
          while calls.length > 1
            call = calls.shift
            object = object.__send__(call)
            break if call == "be"
          end
          return object.__send__(calls.join("_"), *args, &block)
        end
        __orig_method_missing(sym, *args, &block)
      end

Hopefully tonight I’ll have time to code up a quick suggested patch and submit it. First I have to download a few gems and run the tests specs for RSpec to see if I might have broken something else with my fix.

I’m enjoying forcing myself to really think about contexts, specifications, and should statements instead of tests. I think I could probably accomplish about the same thing with good old

1
Test::Unit

, but forcing your brain to think down a different path can sometimes change your perspective.