#410 √ wontfix
MatthewRudy

adding an "either.or" Matcher

Reported by MatthewRudy | May 25th, 2008 @ 04:56 PM | in No-Milestone-Assigned

I came across the problem that there is no way of saying;

blockquote "this SHOULD either BE AN INSTANCE OF array OR BE NIL"

my syntax solution is;

  result.should either(be_an_instance_of(Array)).or(be_nil)

attached is a .diff for a new;

Spec::Matchers::Either class which;

  • takes an argument of a matcher
  • allows chaining with an "or" method
  • defers "matches?(actual)" to each of its contained matchers
  • produces a nice failure message

The diff was produced off the old svn repository

(as I didn't find the GIT until just now, but I can easily redo the testing, documentation, and implementation, against the GIT repo, if anyone things its a good idea)

note:

this can quickly be replicated for a "neither.nor.nor" Matcher

Comments and changes to this ticket

  • Pat Maddox

    Pat Maddox May 25th, 2008 @ 07:09 PM

    hrm. Could you show an example that drove you to write this?

    The patch looks nice. However, I'm concerned that it provides a feature we don't really want. Wouldn't it be better to write one spec that verifies the expected result is nil under one condition, and verify that it's an array under another?

  • MatthewRudy

    MatthewRudy May 25th, 2008 @ 08:37 PM

    this is the test I have

    require File.dirname(__FILE__) + '/../spec_helper'
    
    describe Result do
      
      describe "Result.for" do
        it "should return a Result or nil" do
          -10.upto(10) do |score|
            [Result, NilClass].should include(Result.for(score).class)
          end
        end
        
        it "should not return :upper_is_lower" do
          Result.find_by_lower_and_upper(700,400).should_not be_nil
          [400, 456, 567, 699, 700].each do |score|
            (400..700).should include(score)
            Result.for(score).should be_nil
          end
        end
        
        it "should return one Result in the case of an overlap" do
          one = results(:one_to_five)
          two = results(:three_to_six)
          
          3.upto(5) do |score|
            
            Result.find(:all, :conditions => ["upper >= ? AND lower <= ?", score, score]).length.should be(2)
            
            result = Result.for(score)
            result.class.should be(Result)
            [one.id, two.id].should include(result.id)
          end
        end
          
      end
    end
    

    So my use of it would be in the first statement,

    which is a higher level;

    "if I stick in some reasonable values, I expect it to work, and pass me either a single Result or a nil"

    [NilClass, Result].should include(Result.for(blah).class)
    

    which I'd prefer to write;

    Result.for(blah).should either(be_an_instance_of(Result)).or(be_nil)
    

    I then go on to have specific examples, where I check the result is exactly as expected.

    I have a particular fondness of tests which say;

    "I've set up a whole load of fixtures, now try shoving them into this function in all combinations, and ensure that we get what we expect... in some higher-level sense"

    maybe it's unnecessary.

    but it's a syntax I like.

  • David Chelimsky

    David Chelimsky May 27th, 2008 @ 07:33 AM

    This strikes me as a great way to introduce bugs that are really difficult to track down because all the examples pass.

    If you and I were working on a team, I'd be questioning you about when I should expect nil and when I should expect a Result object and why. The examples should tell me that.

    I appreciate that you're suggesting that this would be a higher level example, with lower level examples answering my questions, but I doubt that most users would feel encouraged to do both.

    My instinct is to not include this - but I'm willing to hear some other opinions first.

  • MatthewRudy

    MatthewRudy May 27th, 2008 @ 11:52 PM

    fair enough.

    hope you have a good time at RailsConf.

  • David Chelimsky

    David Chelimsky May 28th, 2008 @ 06:57 AM

    • → Assigned user changed from “” to “David Chelimsky”

    You too - thanks.

    Anybody else have any opinions about this?

  • Pat Maddox

    Pat Maddox May 28th, 2008 @ 07:20 AM

    I hinted at my opinion earlier... anyway, after seeing the concrete examples, I think several of those tests are unnecessary. So I don't find them to be compelling reasons to introduce this either.or matcher.

    I don't think it should go into rspec core.

  • David Chelimsky

    David Chelimsky July 12th, 2008 @ 04:59 AM

    • → State changed from “new” to “wontfix”
    • → Tag changed from “” to “matchers”

Please Login or create a free account to add a new comment.

You can update this ticket by sending an email to from your email client. (help)

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

Behaviour Driven Development for Ruby.

Shared Ticket Bins

People watching this ticket

Attachments

Tags