[rspec-users] Custom matcher for predicates

David Chelimsky dchelimsky at gmail.com
Sat Dec 26 19:56:47 EST 2009


On Sat, Dec 26, 2009 at 6:55 PM, David Chelimsky <dchelimsky at gmail.com>wrote:

> On Sat, Dec 26, 2009 at 5:53 PM, Ed Howland <ed.howland at gmail.com> 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.
>

I should add here, that if you've already defined a be_nice method, it will
be called. RSpec only checks for a predicate when it gets method_missing,
which it wouldn't if you've defined a method already.

HTH,
David


>
>
>> 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
>
>
>> Ed
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20091226/ab750a8a/attachment.html>


More information about the rspec-users mailing list