On 18 Jul 2010, at 00:10, David Chelimsky wrote:

> On Jul 17, 2010, at 1:18 PM, Costa Shapiro wrote:
> 
>> Hello,
>> 
>> I've been thinking of how to express my idea in code, but since I've never 
>> been involved in RSpec development, I'd better have some feedback here first.
>> The feature suggestion below applies to any controller-like code under spec, 
>> i.e. a stateless module producing output or just altering its data store (it 
>> doesn't necessarily have to be a C of the MVC, but I suppose merb/rails 
>> developers will particularly appreciate it).
>> 
>> Here is a skimmed sample to illustrate the pain:
>> 
>>     describe BookController do
>>     
>>       context "registering a book" do
>>     
>>         specify "from a new author on a new subject" do
>>           auth = mock(:name => 'John Doe')
>>           Author.should_receive(:find_
>> by_name).and_return(nil)
>>           Author.should_receive(:new).and_return(auth)
>>           auth.should_receive(:save).and_return(true)
>>     
>>           subj = mock(:short => 'Mockery')
>>           Subject.should_receive(:find_by_short).and_return(nil)
>>           Subject.should_receive(:new).and_return(subj)
>>           subj.should_receive(:save).and_return(true)
>>     
>>           title = 'Specs on Steroids'
>>     
>>           book = mock
>>           Book.should_receive(:new).and_return(book)
>>           book.should_receive(:save).and_return(true)
>>     
>>           post :register :author => auth.name, :title => title, :subject => 
>> subj.short
>>           response.should be_success
>>         end
>>     
>>         specify "from a known author on a new subject" do
>>           auth = mock(:name => 'Joe Dohn')
>>           Author.should_receive(:find_by_name).and_return(auth)
>>     
>>           subj = mock(:short => 'Mockery')
>>           Subject.should_receive(:find_by_short).and_return(nil)
>>           Subject.should_receive(:new).and_return(subj)
>>           subj.should_receive(:save).and_return(true)
>>     
>>           title = 'Specs on Steroids II'
>>     
>>           book = mock
>>           Book.should_receive(:new).and_return(book)
>>           book.should_receive(:save).and_return(true)
>>     
>>           post :register :author => auth.name, :title => title, :subject => 
>> subj.short
>>           response.should be_success
>>         end
>>     
>>         specify "from a known author on a known subject" do
>>           auth = mock(:name => 'Joe Dohn')
>>           Author.should_receive(:find_by_name).and_return(auth)
>>     
>>           subj = mock(:short => 'Forgery')
>>           Subject.should_receive(:find_by_short).and_return(subj)
>>     
>>           #...
>>         end
>>     
>>         specify "from a new author on a known subject" do
>>           #...
>>         end
>>       end
>>     end
>> 
>> 
>> And this is what I have in mind for doing exactly the same job:
>> 
>>     describe BookController do
>>     
>>       context "registering a book" do
>>     
>>         before :any, "from a new author", :author do
>>           @auth = mock(:name => 'John Doe')
>>           Author.should_receive(:find_by_name).and_return(nil)
>>           Author.should_receive(:new).and_return(@auth)
>>           @auth.should_receive(:save).and_return(true)
>>         end
>>     
>>         before :any, "from a known author", :author do
>>           @auth = mock(:name => 'Joe Dohn')
>>           Author.should_receive(:find_by_name).and_return(@auth)
>>         end
>>     
>>         before :any, "on a new subject", :subject do
>>           @subj = mock(:short => 'Mockery')
>>           Subject.should_receive(:find_by_short).and_return(nil)
>>           Subject.should_receive(:new).and_return(@subj)
>>           @subj.should_receive(:save).and_return(true)
>>         end
>>     
>>         before :any, "on a known subject", :subject do
>>             @subj = mock(:name => 'Joe Dohn')
>>             Subject.should_receive(:find_by_name).and_return(@subj)
>>         end
>>     
>>         it "should succeed", :with => [:author, :subject] do
>>           title = 'Specs on Steroids X'
>>     
>>           post :register :author => @auth.name, :title => title, :subject => 
>> @subj.short
>>           response.should be_success
>>         end
>>       end
>>     end
>> 
>> A run of such specs will effectively multiply the tests — automatically — 
>> choosing before and after blocks as specified.
>> I'm sorry, I haven't thought the DSL through, but I hope the main idea can 
>> be seen: contexts do not have to be hierarchical.
>> In my opinion, adding some sort of context selection+combination 
>> capabilities (AOP-style) will contribute greatly to the expressiveness of 
>> the spec language.
> 
> I think the idea of mixing/matching sub-contexts is very interesting, but it 
> definitely needs from fleshing out. It would have to be easy to 
> read/understand in the spec file as well as the output.
> 
> Also, this only works if every combination should behave the same way. I 
> think we'd need a means of saying "given these combinations of data, expect 
> these outcomes".
> 
> Anybody else have thoughts on this?

It's a nice idea.

I'm not sure whether I'd use it though. I think this idea comes from the desire 
to write specs that are *complete*, which I can perfectly understand but I 
don't think I subscribe to anymore. I prefer to really craft the examples so 
there's 'just enough' tests but no more than that. I'd be worried this might 
offer a temptation to think less about why you're writing each example, and I'd 
be worried how that would help me to do TDD.

It should be possible to do something like this using macros now, right? Can I 
suggest that the OP has a go at refactoring his code using macros and we can 
see how it looks?

> 
> Cheers,
> David
> 
> 
>> Thank you for your attention,
>> Costa.
> 
> _______________________________________________
> rspec-users mailing list
> rspec-users@rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

cheers,
Matt

http://blog.mattwynne.net
+44(0)7974 430184

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

Reply via email to