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
>> [email protected]
>> http://rubyforge.org/mailman/listinfo/rspec-users
>
> cheers,
> Matt
>
> http://blog.mattwynne.net
> +44(0)7974 430184
>
> _______________________________________________
> rspec-users mailing list
> [email protected]
> http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users