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? 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 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. Is this Ok? How do others handle this? . Thanks, and Happy Holidays. Ed -- Ed Howland http://greenprogrammer.wordpress.com http://twitter.com/ed_howland
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.> 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/b2eb0569/attachment.html>
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>
On Sat, Dec 26, 2009 at 7:56 PM, David Chelimsky <dchelimsky at gmail.com> wrote:> 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, > DavidThanks, David. That helps my understanding a lot. Happy Boxing day, or what''s left of it Ed>-- Ed Howland http://greenprogrammer.wordpress.com http://twitter.com/ed_howland