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@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to