On Sat, Dec 26, 2009 at 5:53 PM, Ed Howland [email protected]
wrote:
I hope this isn’t a dumb question, but can a custom matcher be written
for a possibly non-existant predicate? I know that if the object
responds to some predicate? message, RSpec will breate a custom
matcher on the fly for it. Such as be_naughty or be_nice for
sarah.naughty? and jane.nice?
It’s not that RSpec looks at your code and creates predicates for it.
When
you say “jane.should be_nice”, RSpec looks to see if jane has a nice?()
method and uses that if it’s there. Subtle, but important difference.
But what if you want to create your own where this is not the case.
Like sarah.should_not be_on_santas_list:
Spec::Matchers.define :be_on_santas_list do |expected|
matcher do |actual|
$santas_list.include? actual
end
end
The block arguments should align with the arguments you pass to the
matcher.
So if you intend to write this in the example:
sarah.should_not be_on_santas_list
Then the definition should be like this:
Spec::Matchers.define :be_on_santas_list do
matcher do |actual|
$santas_list.include? actual
end
end
… with no block arguments.
Or in the situation where the object has a predicate that returns a
string and not true or false. As is the case with
REXML::Document#stand_alone?:
match do |actual|
actual.stand_alone? == ‘yes’
end
This works, but the value of expected is nil.
That’s because you didn’t pass anything to the matcher, as described
above.
The fact that expected is nil at that point should not matter, since
you’re
not evaluating against expected in the match block. As long as as
“actual.stand_alone? == ‘yes’” returns true or false (which it should
unless
you’ve gone and redefined ==) you should be ok.
Is this Ok?
Yes. Why do you ask? What are your concerns? What problems have you had?
How do others handle this? .
Thanks, and Happy Holidays.
And to you.
Cheers,
David