On Jan 22, 2008 10:26 PM, David Chelimsky <[EMAIL PROTECTED]> wrote: > On Jan 23, 2008 12:04 AM, Scott Taylor <[EMAIL PROTECTED]> wrote: > > > > On Jan 23, 2008, at 12:02 AM, David Chelimsky wrote: > > > > > On Jan 22, 2008 10:49 PM, Jonathan Linowes > > > <[EMAIL PROTECTED]> wrote: > > >> Hi > > >> > > >> I've spec'd a class and they pass. > > >> > > >> Now I'd like to assure that any subclass of this class also passes > > >> the same specs. > > >> Any suggestions for a clever way to handle this? > > >> I'd prefer to keep the existing specs as is (eg instead of moving > > >> everything into shared behaviors, or doing something to all the > > >> 'describe' lines) > > > > > > How about: > > > > > > [Subclass1, Subclass2, BaseClass].each do |klass| > > > describe klass do > > > ... > > > end > > > end > > > > That's sort of funny, being that I posted this solution on Courtney's > > blog yesterday. > > I saw that. I've also done this before :) > > > Is this what you actually use in this sort of situations? Are there > > other (better, or worse) alternatives? > > I usually stick w/ shared example groups, but I sometimes use an > iterator like this. Not sure why. I'll think about it.
I think using an iterator here is weird, and muddles the intent of the specs. Think of what it means to define a class and a subclass. class Foo ... some behavior ... end class Bar < Foo ... all of Foo's behavior ... ... some specialized behavior ... end You don't define all the behavior in Bar - you get a bunch of it from Foo for free, and then specialize whatever you need. Your specs should be similar in spirit. shared_examples_for("the foo role") do it "should have some behavior" ... end describe Bar do it_should_behave_like "the foo role" it "should have some specialized behavior" ... end That is far more clear to me. The downside is that you also end up with On Jan 22, 2008 10:26 PM, David Chelimsky <[EMAIL PROTECTED]> wrote: > On Jan 23, 2008 12:04 AM, Scott Taylor <[EMAIL PROTECTED]> wrote: > > > > On Jan 23, 2008, at 12:02 AM, David Chelimsky wrote: > > > > > On Jan 22, 2008 10:49 PM, Jonathan Linowes > > > <[EMAIL PROTECTED]> wrote: > > >> Hi > > >> > > >> I've spec'd a class and they pass. > > >> > > >> Now I'd like to assure that any subclass of this class also passes > > >> the same specs. > > >> Any suggestions for a clever way to handle this? > > >> I'd prefer to keep the existing specs as is (eg instead of moving > > >> everything into shared behaviors, or doing something to all the > > >> 'describe' lines) > > > > > > How about: > > > > > > [Subclass1, Subclass2, BaseClass].each do |klass| > > > describe klass do > > > ... > > > end > > > end > > > > That's sort of funny, being that I posted this solution on Courtney's > > blog yesterday. > > I saw that. I've also done this before :) > > > Is this what you actually use in this sort of situations? Are there > > other (better, or worse) alternatives? > > I usually stick w/ shared example groups, but I sometimes use an > iterator like this. Not sure why. I'll think about it. I think using an iterator here is weird, and muddles the intent of the specs. Think of what it means to define a class and a subclass. class Foo ... some behavior ... end class Bar < Foo ... all of Foo's behavior ... ... some specialized behavior ... end You don't define all the behavior in Bar - you get a bunch of it from Foo for free, and then specialize whatever you need. Your specs should be similar in spirit. shared_examples_for("the foo role") do it "should have some behavior" ... end The downside is you end up with describe Foo do it_should_behave_like "the foo role" end to specify the behavior, which feels pretty weak to me. Though I assume you feel somewhat similarly, so I'd be interested to know when you use an iterator for full example groups. Actually one example I remember is when I wrote a macro that added a bunch of methods to a class...I wrote the initial example group for just one attribute name. Then when I extracted the macro, I just iterated through a bunch of names over the example group. So it can be useful. Although a whole class feels too coarse grained for that approach, to me. I do use iterators a bunch for stuff like [:name, :email, :phone, :address].each do |field| it "should require a #{field}" do u = build_user(field => nil) u.should_not be_valid u.should have(1).error_on(field) end end Also, since I'm close to the subject, here's a little tip. I've seen people write specs like: it "should require valid attributes" do [:name, :email, :phone, :address].each do |field| u = build_user(field => nil) u.should_not be_valid u.should have(1).error_on(field) end end but that sucks, because if the example fails, you don't have any clue why. Cause it'll just say that user is invalid, but doesn't tell you which field is blank. That was a bit of a tangent. It's late, I'm loopy :) Pat _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users