On Jul 19, 2010, at 3:58 AM, Matt Wynne wrote: > > 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.
Agreed this would be a potential pitfall of this approach. I'm also not convinced this is the right tool for this sort of thing. Seems like something best expressed in a table: data do author do new { ... } known { ... } end subject do new { ... } known { ... } end outcome do success { ... } end end scenarios <<-SCENARIOS | author | subject | outcome | | new | new | success | | known | new | success | | new | known | success | | known | known | success | SCENARIOS Something like this might work, but maybe it's better suited for Cucumber, or FIT. > 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
_______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users