Panasonic Youth rob sanheim writes about software, business, ruby, music, stuff and things



Posted
7 August 2007 @ 3pm

Tagged
BDD, Rails, Ruby

Discuss

Add “should.include?” for test/spec

I have done the following one too many times:

collection.should.include?(object)

Only to have it fail because test/spec's should doesn't know about include? (or .not.include?)

However, as Chris points out in the comments, test/spec does allow .should.include (without the "?"), but does not have a should.not version of it. So the following adds a alias with the question mark, and also adds the should.not complement.

module Test::Spec::Rails::ShouldInclude
  def self.included(base)
    base.class_eval { alias_method :include?, :include }
  end
end

module Test::Spec::Rails::ShouldNotInclude
  def self.included(base)
    base.class_eval { alias_method :include?, :include }
  end
 
  def include(value)
    msg = build_message(@message, "<?> expected to not include ?, but it did.",
                        @object, value)
    assert_block(msg) { !@object.include?(value) }
  end
end

Test::Spec::Should.send(:include, Test::Spec::Rails::ShouldInclude)
Test::Spec::ShouldNot.send(:include, Test::Spec::Rails::ShouldNotInclude)

(updated 8/8)


9 Comments

Posted by
Chris
7 August 2007 @ 4pm

@array.should.include 2 works out of the box with test/spec


Posted by
Rob
8 August 2007 @ 8am

Chris: Oops, guess I should’ve RTFM.

I’ve updated the code to just alias to include?, and also to add a should.not version, which I didn’t see in test/spec.


Posted by
Chris
8 August 2007 @ 10am

It actually does not out of the box, too :)


Posted by
Chris
8 August 2007 @ 10am

More appropriately, test/spec works out of the box for any predicate. If you have an ActiveRecord boolean field “public?”, you can do @item.should.be.public and @item.should.be.not.public by default.


Posted by
Chris
8 August 2007 @ 10am

I’m just going to post another comment because I want to make sure this page says “Chris” more than it says “Rob.” We’re taking over this town.


Posted by
Rob
8 August 2007 @ 11am

First I get my original post wrong, and now you’re just making me look bad.

But - I think using the .not.include I have above is better, as it gives the friendlier error message that I copied from the .include implementation. Otherwise you just get a message saying “false expected to be true”. I hate failure mesages like that.

There must be a more meta way to get much better failure messages with test/spec, that deliver more context and don’t just say things like “nil expected to not be nil”

Sounds like the next err plugin?


Posted by
Chris
8 August 2007 @ 11am

I find the error messages in general pretty lacking, so I agree completely. I’ve been building up a bunch of extensions to test/spec and test/spec/rails privately… Not sure what I’m going to do with them yet. Maybe we can chat about some sort of roll-up of these snippets.


Posted by
Rob
10 August 2007 @ 1am

I agree.

I’ll have my people call your people.


Posted by
dsfgfdfg
20 November 2007 @ 4am