[rspec-users] array order-agnostic matching?

James OBrien james at rapleaf.com
Tue Feb 1 11:46:42 EST 2011


Awesome, thanks David!

there are other entries in the hash so presumably I will need something like
this

i.e.

  foo.should_receive(:bar) do |hash|
    actual = hash[:some_key]

    hash[:some_key].should =~ [1,2,3]
    hash.shoul
  end




On Tue, Feb 1, 2011 at 4:43 AM, David Chelimsky <dchelimsky at gmail.com>wrote:

>
> On Feb 1, 2011, at 3:40 AM, James OBrien wrote:
>
> hey, thanks for reading:
>
> I have a problem which can be reduced to this,
>
> from within an example of mine I call the helper 'expect_call' which is
> defined thus:
>
> def expect_call(*hash*)*
>   *obj.should_receive(:some_
> method).with(*hash*)*
> *end
>
> and in one of my examples the 'expected' hash is strictly defined as
> follows
>
> expect_call(*{
>    :some_key => [1,2,3]
> }*)
>
> however my spec fails because it is actually called with
>
> *{
>    :some_key => [1,3,2]
> }
>
> *or maybe
>
> *{
>    :some_key => [2,3,1]
> }
>
> *or
>
> *{
>    :some_key => [2,1,3]
> }
>
> *i.e. the array part is not in the order i 'expect' BUT i don't actually
> care about the order. So I would like to be able to change my one example to
> something like this:
>
> expect_call(*{
>    *:some_key => [1,2,3]*.ignoring_order
> }*)
>
> does such a concept exist or do I have to change the implementation of
> expect_call to use some sort of custom matcher - I am reluctant to do this
> since this method is called in other cases where maybe (for arguments sake)
> I DO care about array ordering within the hash.
>
>
> rspec-expectations lets you do this:
>
>   foo.bar.should =~ [1,2,3]
>
> This passes as long as the array contains exactly those three elements in
> any order. You can use this now in conjunction with rspec-mocks, like this:
>
>   foo.should_receive(:bar) do |hash|
>     hash[:some_key].should =~ [1,2,3]
>   end
>
> It's a bit more verbose than what you're looking for, but it can get you
> there with rspec as/is today.
>
> Going forward, we might want to consider an array_including argument
> matcher for rspec-mocks. We already have a hash_including matcher that works
> like this:
>
>   foo.should_receive(:bar).with(hash_including(:a => 'b'))
>
> Similarly we could have:
>
>   foo.should_receive(:bar).with(array_including(1,2,3))
>
> The only problem with this is the name: array_including could mean
> different things (ordered/unordered, only these elements or subset, etc).
> The hash_including matcher is specifically about a subset of a hash. But
> perhaps we could extend this with something like you proposed above:
>
>   foo.should_receive(:bar).with(array_including(1,2,3))
>   foo.should_receive(:bar).with(array_including(1,2,3).ingoring_order)
>   foo.should_receive(:bar).with(array_including(1,2,3).only.ingoring_order)
>
> The thing is, I'm not sure this is any better than the example I gave
> above, which is very precise and works today. Thoughts/opinions welcome.
>
> Hope someone can solve this for me - MUCH appreciation.
>
>
> As an aside, when passing a hash as an argument you don't need to use curly
> braces, as long as the hash is the last argument to the method. These two
> are equivalent:
>
>   expect_call(1, :a, {:some_key => 'some value'})
>   expect_call(1, :a, :some_key => 'some value')
>
> HTH,
> David
>
>
>
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110201/aa550fd9/attachment.html>


More information about the rspec-users mailing list