Re: [rspec-users] array order-agnostic matching?

2011-02-01 Thread James OBrien
I agree Vincent

Can people however please use this trail to help me with my original query.

I repeat the private method is declared on the test example group. This is
not inside implemenraton code.

On Feb 1, 2011 9:21 PM, "Wincent Colaiuta"  wrote:

El 02/02/2011, a las 02:28, Julian Leviston escribió:


> Surely as the private methods of a class change, the testing code HAS to
change...
That statement sets off all sorts of alarm bells for me.

In order for your specs to be non-brittle, they should be concerned with the
externally-visible behavior of the code and not with the internal
implementation details. For me, private methods fall under "internal
implementation details".

Being non-brittle and focussed on externally-visible behavior rather than
implementation is a valuable attribute for a spec suite to have, because it
allows us to refactor and improve the code with confidence that the behavior
remains unchanged, but without having to engage in duplicative and
error-prone updating of our specs to match the internal changes in
implementation.

So, if you're feeling the need to spec private methods, its an indication
that you could be doing something better, because you're either:

- specifying internal implementation details (and if that's the case, why
are you specifying it?); or

- you've made something private that shouldn't really be that way (and in
that case, there are various refactorings you can use to restructure the
code in order to make it more amenable to testing)

Cheers,
Wincent


___
rspec-users mailing list
rspec-users@rubyforge.org
...
___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Re: [rspec-users] array order-agnostic matching?

2011-02-01 Thread Julian Leviston

On 02/02/2011, at 3:47 PM, Wincent Colaiuta wrote:

> El 02/02/2011, a las 02:28, Julian Leviston escribió:
> 
>> Surely as the private methods of a class change, the testing code HAS to 
>> change...
> 
> That statement sets off all sorts of alarm bells for me.
> 
> In order for your specs to be non-brittle, they should be concerned with the 
> externally-visible behavior of the code and not with the internal 
> implementation details. For me, private methods fall under "internal 
> implementation details".
> 
> Being non-brittle and focussed on externally-visible behavior rather than 
> implementation is a valuable attribute for a spec suite to have, because it 
> allows us to refactor and improve the code with confidence that the behavior 
> remains unchanged, but without having to engage in duplicative and 
> error-prone updating of our specs to match the internal changes in 
> implementation.
> 
> So, if you're feeling the need to spec private methods, its an indication 
> that you could be doing something better, because you're either:
> 
> - specifying internal implementation details (and if that's the case, why are 
> you specifying it?); or
> 
> - you've made something private that shouldn't really be that way (and in 
> that case, there are various refactorings you can use to restructure the code 
> in order to make it more amenable to testing)
> 
> Cheers,
> Wincent
> 


That's hopefully already fairly obvious. Yes, I agree. Program to an interface. 
The idea is pretty much scope: ie, it depends what you're testing... it's the 
behaviour of the thing you're testing that is important... 

We have application-level scope ("behaviour testing"), class-level scope 
(testing that the class does what it's supposed to) and method-level scope 
dependant on what we're programming, right?

If I'm programming a method, I want to test that it does certain things 
(preferably the things it's supposed to do, right? This is, after all, what a 
spec is).

Binding a set of components together to build an enclosing component, each 
component should have tests... including any enclosing components. 
Encapsulation of tests... :-)

Julian.


___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users


Re: [rspec-users] array order-agnostic matching?

2011-02-01 Thread Wincent Colaiuta
El 02/02/2011, a las 02:28, Julian Leviston escribió:

> Surely as the private methods of a class change, the testing code HAS to 
> change...

That statement sets off all sorts of alarm bells for me.

In order for your specs to be non-brittle, they should be concerned with the 
externally-visible behavior of the code and not with the internal 
implementation details. For me, private methods fall under "internal 
implementation details".

Being non-brittle and focussed on externally-visible behavior rather than 
implementation is a valuable attribute for a spec suite to have, because it 
allows us to refactor and improve the code with confidence that the behavior 
remains unchanged, but without having to engage in duplicative and error-prone 
updating of our specs to match the internal changes in implementation.

So, if you're feeling the need to spec private methods, its an indication that 
you could be doing something better, because you're either:

- specifying internal implementation details (and if that's the case, why are 
you specifying it?); or

- you've made something private that shouldn't really be that way (and in that 
case, there are various refactorings you can use to restructure the code in 
order to make it more amenable to testing)

Cheers,
Wincent

___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users


Re: [rspec-users] array order-agnostic matching?

2011-02-01 Thread James OBrien
Sorry but I disagree.

Specs should define only the external behavior of an object or service -
allowing for confident implementation adjustments against a trusted suite of
tests.

What you're describing would make refactoring very hard. I think what you
say goes against a lot of established theory and best practise.

I would like to draw this back to the original question

Take care

James

On Feb 1, 2011 8:16 PM, "Julian Leviston"  wrote:

Sorry it was a knee-jerk reaction that was prompted by what you wrote, but
not necessarily even connected to it.

Essentially, I've been wondering/thinking about this for a very long time
(since about 15 years ago when I started writing smalltalk code).

I think a general principle of code is that it should be specced from the
inside out and simultaneously from the outside in.

We have things like cucumber to generally spec from the outside in (ie
define an interface according to the "user" what or whoever that may be),
and we have things like rspec to spec from the inside out

...however inside-out specs should be built inline with the code they spec,
surely? I mean, just like you *should* have comments and documentation built
in, the spec should almost build a bridge from the documentation to the
code...

It seems rspec is incredibly close to this, much closer than cucumber is to
be a very useable outside-in spec system.

Essentially I'd stipulate a flow of development that went something like
this:

1. Plan
2. Put Plan and Documentation in source code with placeholders
3. Build Spec
4. Build Code

An architecture that, when bootstrapped, tests itself to make sure it's not
borked before the code runs. (ie it does self-check on startup,
essentially).

Julian.



On 02/02/2011, at 2:36 PM, James OBrien wrote:

> I don't fully understand this response..
>
> The...

___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Re: [rspec-users] array order-agnostic matching?

2011-02-01 Thread Julian Leviston
Sorry it was a knee-jerk reaction that was prompted by what you wrote, but not 
necessarily even connected to it.

Essentially, I've been wondering/thinking about this for a very long time 
(since about 15 years ago when I started writing smalltalk code).

I think a general principle of code is that it should be specced from the 
inside out and simultaneously from the outside in.

We have things like cucumber to generally spec from the outside in (ie define 
an interface according to the "user" what or whoever that may be), and we have 
things like rspec to spec from the inside out

...however inside-out specs should be built inline with the code they spec, 
surely? I mean, just like you *should* have comments and documentation built 
in, the spec should almost build a bridge from the documentation to the code...

It seems rspec is incredibly close to this, much closer than cucumber is to be 
a very useable outside-in spec system.

Essentially I'd stipulate a flow of development that went something like this:

1. Plan
2. Put Plan and Documentation in source code with placeholders
3. Build Spec
4. Build Code

An architecture that, when bootstrapped, tests itself to make sure it's not 
borked before the code runs. (ie it does self-check on startup, essentially). 

Julian.

On 02/02/2011, at 2:36 PM, James OBrien wrote:

> I don't fully understand this response..
> 
> The private method I mentioned was a helper created by me in test code on the 
> example group.
> 
> Still very interested
> 
> 
>> On Feb 1, 2011 7:28 PM, "Julian Leviston"  wrote:
>> 
>> Does this strike anyone else as odd?
>> 
>> Don't you think the test should actually be written IN to the code itself?
>> 
>> I guess I'm soft of stipulating a new language here, but perhaps Ruby is 
>> flexible enough to enable this.
>> 
>> Surely as the private methods of a class change, the testing code HAS to 
>> change... therefore isn't it best to actually write the rspec-level tests 
>> into the classes themselves as context-sensitive-optionally loaded or not 
>> depending on whether you're in testing mode or not
>> 
>> Julian
>> 
>> 
>> 
>> On 02/02/2011, at 4:01 AM, James OBrien wrote:
>> 
>> > additionally,
>> >
>> > since my
>> >
>> > foo.should_recei...
>> 
>> 
>> ___
>> rspec-users mailing list
>> rspec-users@rubyforge.org
>> http://rubyforge.org/mailman/listinfo/rspec-users
> 
> ___
> rspec-users mailing list
> rspec-users@rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Re: [rspec-users] array order-agnostic matching?

2011-02-01 Thread James OBrien
I don't fully understand this response..

The private method I mentioned was a helper created by me in test code on
the example group.

Still very interested

On Feb 1, 2011 7:28 PM, "Julian Leviston"  wrote:

Does this strike anyone else as odd?

Don't you think the test should actually be written IN to the code itself?

I guess I'm soft of stipulating a new language here, but perhaps Ruby is
flexible enough to enable this.

Surely as the private methods of a class change, the testing code HAS to
change... therefore isn't it best to actually write the rspec-level tests
into the classes themselves as context-sensitive-optionally loaded or not
depending on whether you're in testing mode or not

Julian




On 02/02/2011, at 4:01 AM, James OBrien wrote:

> additionally,
>
> since my
>
> foo.should_recei...

___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Re: [rspec-users] array order-agnostic matching?

2011-02-01 Thread Julian Leviston
Does this strike anyone else as odd?

Don't you think the test should actually be written IN to the code itself?

I guess I'm soft of stipulating a new language here, but perhaps Ruby is 
flexible enough to enable this.

Surely as the private methods of a class change, the testing code HAS to 
change... therefore isn't it best to actually write the rspec-level tests into 
the classes themselves as context-sensitive-optionally loaded or not depending 
on whether you're in testing mode or not

Julian


On 02/02/2011, at 4:01 AM, James OBrien wrote:

> additionally,
> 
> since my
> 
> foo.should_receive(...
> 
> expectation
> 
> is actually in a private helper method ('expect_call') on the example group I 
> will need to pull this code up into a block, since not all callers pass a 
> hash with :some_key set
> 
> viz:
> 
> #helper_method
> def expect_call
>   foo.should_receiver(:bar) do |hash|
> yield hash
>   end
> end
> 
> then those examples which dont care about my array ordering problem (or 
> rather care that it is in order!) can just do:
> 
> expect_call do |actual_hash|
>   actual_hash.should == {:some => 'expected_value', :other => [4,5,6]}
> end
> 
> and the one case that does care can do:
> 
> expect_call do |actual_hash|
> actual = actual_hash[:some_key]
> actual_hash[:some_key] = nil
> actual_hash.should == {
>   :my => 'expected'
>   :other => 1
>   :ields => :in_the_hash
> }
> actual.should =~ [1,2,3]
> end
> 
> does this sound sensible?
> 
> Thanks so much again - I have your book :) and although I'm new to it I 
> really enjoy rspec!
> 
> On Tue, Feb 1, 2011 at 8:51 AM, James OBrien  wrote:
> ooops, that sent itself early...
> 
> . . . 
> 
> there are other entries in the hash so presumably I will need something like 
> this
> 
> foo.should_receive(:bar) do |hash|
> actual = hash[:some_key]
> hash[:some_key] = nil
> hash.should == {
>   :my => 'expected'
>   :other => 1
>   :ields => :in_the_hash
> }
> actual.should =~ [1,2,3]
> 
>   end
> 
> i.e. I assert :some_key and 'the rest' separately.
> 
> There isn't a way to do this simpler is there?
> 
> Thanks again David!
> 
> 
> On Tue, Feb 1, 2011 at 8:46 AM, James OBrien  wrote:
> 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  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)
> 

Re: [rspec-users] array order-agnostic matching?

2011-02-01 Thread James OBrien
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 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@rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Re: [rspec-users] array order-agnostic matching?

2011-02-01 Thread James OBrien
ooops, that sent itself early...

. . .

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

foo.should_receive(:bar) do |hash|
actual = hash[:some_key]
*hash[:some_key] = nil*
hash.should == {
  :my => 'expected'
  :other => 1
  :ields => :in_the_hash
}
actual.should =~ [1,2,3]

  end

i.e. I assert :some_key and 'the rest' separately.

There isn't a way to do this simpler is there?

Thanks again David!


On Tue, Feb 1, 2011 at 8:46 AM, James OBrien  wrote:

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

Re: [rspec-users] array order-agnostic matching?

2011-02-01 Thread James OBrien
additionally,

since my

*foo.should_receive(...

*expectation
*
*is actually in a private helper method ('expect_call') on the example group
I will need to pull this code up into a block, since not all callers pass a
hash with :some_key set

viz:

#helper_method
*def expect_call
  foo.should_receiver(:bar) do |hash|
yield hash
  end
end*

then those examples which dont care about my array ordering problem (or
rather care that it is in order!) can just do:

*expect_call do |actual_hash|
  actual_hash.should == {:some => 'expected_value', :other => [4,5,6]}
end*

and the one case that does care can do:

*expect_call do |actual_hash|
actual = **actual_hash[:some_key]
**actual_hash**[:some_key] = nil
**actual_hash.should == {
  :my => 'expected'
  :other => 1
  :ields => :in_the_hash
}
actual.should =~ [1,2,3]
** end*

does this sound sensible?

Thanks so much again - I have your book :) and although I'm new to it I
really enjoy rspec!

On Tue, Feb 1, 2011 at 8:51 AM, James OBrien  wrote:

> ooops, that sent itself early...
>
> . . .
>
> there are other entries in the hash so presumably I will need something
> like this
>
> foo.should_receive(:bar) do |hash|
> actual = hash[:some_key]
> *hash[:some_key] = nil*
> hash.should == {
>   :my => 'expected'
>   :other => 1
>   :ields => :in_the_hash
> }
> actual.should =~ [1,2,3]
>
>   end
>
> i.e. I assert :some_key and 'the rest' separately.
>
> There isn't a way to do this simpler is there?
>
> Thanks again David!
>
>
> On Tue, Feb 1, 2011 at 8:46 AM, James OBrien  wrote:
>
>> 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 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_k

Re: [rspec-users] array order-agnostic matching?

2011-02-01 Thread David Chelimsky

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

[rspec-users] array order-agnostic matching?

2011-02-01 Thread James OBrien
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.

Hope someone can solve this for me - MUCH appreciation.

James
___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users