> One other way to write `[1,2,3].should_not be_any { |x| x < 0 }` that
> results in more descriptive output:
> [1,2,3].each do |number|
> it "#{number} should not be less than 0" do
> (number < 0).should be_false
> end
> end
> Now my test output looks like:
> 1 should not be less than 0
> 2 should not be less than 0
> 3 should not be less than 0
More verbose, perhaps, but not really more descriptive. In the failure
case (which is when you really want the error message to make sense) you
will see something like this:
-1 should not be less than 0
which is patently absurd. -1 certainly should be less than zero, or
much of conventional mathematics shears off and slides into the sea.
The problem is, the original test was trying to make a statement about
the array, not about its elements.
> I'm suspecting that they may not be included in rspec by default since
> it's very hard to write good failure messages for these.
Eh. They allow
[1,2,3].any? { |x| x < 0 }.should be_false
Which is no easier to write a good descriptive test for.
>
>
http://gist.github.com/248868
>
Yeah. I wound up doing a custom matcher that was more task specific.
The general case on yours could be tweaked to make it a little more
descriptive:
def all_be(desc='something') &block
simple_matcher "all be" do |given, matcher|
matcher.failure_message =
"expected #{given.inspect} to all be #{desc}"
matcher.negative_failure_message =
"expected #{given.inspect} to not all be #{desc}"
given.all? &block
end
end
Letting us write:
[1,2,3].should all_be('positive') {|x| x > 0 }
Still though, the real problem is a framework that has edge cases like
this in the first place. If the be_xxx matchers are going to ignore the
blocks they should raise an exception if given a block. Otherwise, it
is yet another way in which your tests can look like they are proving
something when in fact they are doing nothing of the sort.
-- Markus