[rspec-devel] [ rspec-Patches-6417 ] [PATCH] Support @object.some_method_should_be_changed_by {block}

noreply at rubyforge.org noreply at rubyforge.org
Wed Nov 15 06:30:13 EST 2006

Patches item #6417, was opened at 2006-10-31 21:36
You can respond by visiting: 

Category: None
Group: None
Status: Open
Resolution: None
Priority: 3
Submitted By: Wilson Bilkovich (wilson)
Assigned to: Nobody (None)
Summary: [PATCH] Support @object.some_method_should_be_changed_by {block}

Initial Comment:
I was toying with how to implement the RSpec equivalent of "assert_difference" from test/unit.
In case you haven't used it, it looks something like this:
assert_difference some_object, :some_method { some code here }

It calls some_object.some_method before and after the block, and fails if there is no difference.

This patch implements something similarly generic:

@some_object.some_method_should_be_changed_by {|obj| code here}
..and its inverse:
@some_object.some_method_should_not_be_changed_by {|obj| code here}

some_method is stripped from the beginning of the message, and passed forward for use inside the Should module.

Has specs, and all other existing specs still pass.

A real 'use case' example:

User.count_should_be_changed_by do
  User.create :login => 'quentin', :email => 'blah at example.com'...

User.count will be different before and after, so this expectation will be met.


>Comment By: David Chelimsky (dchelimsky)
Date: 2006-11-15 11:30

Brandon - re: inclusion as a core feature:

I think it is too non-deterministic as/is. In the example, one could override (accidentally, of course) User.create to delete something and the spec would pass.

We *could* make it more deterministic:

User.count.should_be_changed_by('+ 1') do {...}


User.count.should_be_changed_from(3).to(4) do {...}

One thing that concerns me is that we lose the separation between context and outcome that is essential to BDD. 

Although it is very behavioral in nature. I'm on the fence.



Comment By: David Chelimsky (dchelimsky)
Date: 2006-11-15 11:22

Wilson - re: your question about plugins and sugar:

sugar.rb now only intercepts the :should_ part of a :should_do_something message. What you want to extend is the Should class itself (in this case with a 'changed_by' method that takes a block), and the Not class if you want a negative counterpart.

Be forewarned that we're not committing to the current structure at this point, so you'd be incurring some risk that a future version of RSpec might break your plugin because you're patching something internal. We will, however, at some point soon (within a month or two I think), publish (and thereby commit to) an entry point to extending expectations.


Comment By: Brandon Keepers (brandon)
Date: 2006-11-15 01:00

What is the reasoning for not including this as a core feature?  This is a very helpful expectation.


Comment By: Aslak Hellesøy (aslak_hellesoy)
Date: 2006-11-06 18:11

I don't think anyone has thought much about how a plugin mechanism will actually be implemented. We'll try as hard as we can to make something forward compatible and easy to use.

Your patch here would be a good case to verify a plugin mechanism against. 

I actually implemented this very feature a couple of months ago (rel 0.5.14). We decided to remove the day after. The thread about it starts here:



Comment By: Wilson Bilkovich (wilson)
Date: 2006-11-06 17:51

Hrm. Are plugins going to be able to modify sugar.rb in a
forward-compatible way?
I'm not sure how to implement this without stepping in that
early in the chain.


Comment By: Aslak Hellesøy (aslak_hellesoy)
Date: 2006-11-06 17:45

I think this is the kind of stuff we'd encourage people to bundle as an RSpec plugin. We don't have a plugin mechanism yet, but we'll hopefully have one soon.


You can respond by visiting: 

More information about the rspec-devel mailing list