Hi all, I noticed that if I have a method named has_somthing? and I do: object.should_not have_somthing and it failed (as expected) when the method returns nil. But if the method is something? and I do: object.should_not be_something, and it succeeded (not what I expected) when something? returns nil Is this intended behavior or something I did was wrong? Thanks Yi
Sorry for the spam, but I was wrong: the *should_not have_something* also passed when the method returned nil. On Sep 18, 2009, at 10:42 AM, Yi Wen wrote:> Hi all, > > I noticed that if I have a method named has_somthing? and I do: > object.should_not have_somthing and it failed (as expected) when the > method returns nil. > > But if the method is something? and I do: > object.should_not be_something, and it succeeded (not what I > expected) when something? returns nil > > Is this intended behavior or something I did was wrong? Thanks > > Yi
On Fri, Sep 18, 2009 at 10:42 AM, Yi Wen <hayafirst at gmail.com> wrote:> Hi all, > > I noticed that if I have a method named has_somthing? and I do: > object.should_not have_somthing and it failed (as expected) when the method > returns nil.Actually, this should pass. The have_xxx and be_xxx matchers should pass/fail based on truthiness, not true/false explicitly. For example:>> require ''ostruct''=> true>> require ''spec/expectations''=> true>> include Spec::Matchers=> Object>> obj = OpenStruct.new(:has_foo? => nil)=> #<OpenStruct has_foo?=nil>>> obj.has_foo?=> nil>> obj.should_not have_foo=> nil>> obj.should have_fooSpec::Expectations::ExpectationNotMetError: expected #has_foo?(nil) to return true, got false The message is admittedly wrong (should say "got nil" at the end, or something else entirely), but the pass/fail is correct. So it sounds like you''re experiencing a bug of some kind on the has_xxx matcher, not the be_xxx matcher, which is appears to be behaving correctly based on what you wrote below. Please file a bug if you can provide an example that I can run that I can see behaving incorrectly. HTH, David> > But if the method is something? and I do: > object.should_not be_something, and it succeeded (not what I expected) when > something? returns nil > > Is this intended behavior or something I did was wrong? Thanks> > Yi > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Ok, I guess in reality it will never make a difference if a predicate returns a nil or a false. The behavior annoys me a little bit when I write a test that passes when the method itself does nothing (so that it returns nil). Any thoughts? Thanks Yi On Sep 18, 2009, at 11:06 AM, David Chelimsky wrote:> On Fri, Sep 18, 2009 at 10:42 AM, Yi Wen <hayafirst at gmail.com> wrote: >> Hi all, >> >> I noticed that if I have a method named has_somthing? and I do: >> object.should_not have_somthing and it failed (as expected) when >> the method >> returns nil. > > Actually, this should pass. The have_xxx and be_xxx matchers should > pass/fail based on truthiness, not true/false explicitly. For example: > >>> require ''ostruct'' > => true >>> require ''spec/expectations'' > => true >>> include Spec::Matchers > => Object >>> obj = OpenStruct.new(:has_foo? => nil) > => #<OpenStruct has_foo?=nil> >>> obj.has_foo? > => nil >>> obj.should_not have_foo > => nil >>> obj.should have_foo > Spec::Expectations::ExpectationNotMetError: expected #has_foo?(nil) to > return true, got false > > The message is admittedly wrong (should say "got nil" at the end, or > something else entirely), but the pass/fail is correct. > > So it sounds like you''re experiencing a bug of some kind on the > has_xxx matcher, not the be_xxx matcher, which is appears to be > behaving correctly based on what you wrote below. Please file a bug if > you can provide an example that I can run that I can see behaving > incorrectly. > > HTH, > David > > > > >> >> But if the method is something? and I do: >> object.should_not be_something, and it succeeded (not what I >> expected) when >> something? returns nil >> >> Is this intended behavior or something I did was wrong? Thanks > > > > >> >> Yi >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users >> > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
On Fri, Sep 18, 2009 at 11:31 AM, Yi Wen <hayafirst at gmail.com> wrote:> Ok, I guess in reality it will never make a difference if a predicate > returns a nil or a false. > > The behavior annoys me a little bit when I write a test that passes when the > method itself does nothing (so that it returns nil). Any thoughts?Remember that each example runs _in a context_. Any one example need not tell the whole story, but a mere part of it. If an example says "thing.should_not have_foo" and thing#has_foo? doesn''t do anything, then that''s all the implementation that is necessary for _that example_ to pass. But that shouldn''t be the only example. Consider: describe Thing do context "without foo" do it "says it does not have foo" do thing = Thing.new thing.should_not have_foo end end context "with foo" do it "says it has foo" do thing = Thing.new.with_foo thing.should have_foo end end end The first example will pass with an empty #has_foo? method, but the second one won''t. Together they tell a more complete story. If, considering the above, this continues to bother you, then write an explicit example: thing.has_xxx?.should_not == nil HTH, David> > Thanks > > Yi > > > On Sep 18, 2009, at 11:06 AM, David Chelimsky wrote: > >> On Fri, Sep 18, 2009 at 10:42 AM, Yi Wen <hayafirst at gmail.com> wrote: >>> >>> Hi all, >>> >>> I noticed that if I have a method named has_somthing? and I do: >>> object.should_not have_somthing and it failed (as expected) when the >>> method >>> returns nil. >> >> Actually, this should pass. The have_xxx and be_xxx matchers should >> pass/fail based on truthiness, not true/false explicitly. For example: >> >>>> require ''ostruct'' >> >> => true >>>> >>>> require ''spec/expectations'' >> >> => true >>>> >>>> include Spec::Matchers >> >> => Object >>>> >>>> obj = OpenStruct.new(:has_foo? => nil) >> >> => #<OpenStruct has_foo?=nil> >>>> >>>> obj.has_foo? >> >> => nil >>>> >>>> obj.should_not have_foo >> >> => nil >>>> >>>> obj.should have_foo >> >> Spec::Expectations::ExpectationNotMetError: expected #has_foo?(nil) to >> return true, got false >> >> The message is admittedly wrong (should say "got nil" at the end, or >> something else entirely), but the pass/fail is correct. >> >> So it sounds like you''re experiencing a bug of some kind on the >> has_xxx matcher, not the be_xxx matcher, which is appears to be >> behaving correctly based on what you wrote below. Please file a bug if >> you can provide an example that I can run that I can see behaving >> incorrectly. >> >> HTH, >> David >> >> >> >> >>> >>> But if the method is something? and I do: >>> object.should_not be_something, and it succeeded (not what I expected) >>> when >>> something? returns nil >>> >>> Is this intended behavior or something I did was wrong? Thanks >> >> >> >> >>> >>> Yi >>> _______________________________________________ >>> rspec-users mailing list >>> rspec-users at rubyforge.org >>> http://rubyforge.org/mailman/listinfo/rspec-users >>> >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >