On Jul 26, 2010, at 8:55 am, Wincent Colaiuta wrote: > Seems to me that including the same shared example group twice in the same > "describe" block is a bit of an abuse, to be honest. I don't think it was > ever really intended to be used in that way.
You're right, it clearly wasn't intended for this. I'm trying to find the best way to express the behaviour I want without bending the current syntax of RSpec too much. This is indeed a toy example, so let me explain the real situation in more detail. I'm doing a small side project to make a checklist app. As part of that, I'm trying to extract out a library similar to Naked Objects[1]. One of the things that can be factored out is collections inside entities. So I currently have, as examples: class User extend DomainLib::Entity::ClassExtensions include DomainLib::Entity::InstanceExtensions collection :checklist_templates, of: :checklist_template, class_name: "ChecklistTemplate" end and class ChecklistTemplate extend DomainLib::Entity::ClassExtensions include DomainLib::Entity::InstanceExtensions collection :items, of: :item, class_name: "ChecklistTemplateItem" end Now one of the thing that bugs me about using ORM (eg ActiveRecord, DataMapper) features for this is you're then faced with the dilemma of do you do an integration test of the collection functionality, which duplicates a lot of the testing effort put into the ORM, or do you mock this out, and risk having false positives because the ORM behaves differently than your test setup assumes? The solution I'm playing with is to extract shared contract (ie shared example groups) that you can mix into a spec for a host class (eg User, Checklist) above to prove the feature (here collections) works, without reference to the implementation. (The specs inside DomainLib prove the general case.) With the help of this spec_helper incantation: module SpecHelperObjectExtensions def contract(name, &block) shared_examples_for(name, &block) end end include SpecHelperObjectExtensions RSpec.configure do |c| c.alias_it_should_behave_like_to(:it_satisfies_contract, 'satisfies contract:') end I've already been able to extracted contract, which is for Representation (basically, a view object that isn't much more than a Struct): # Params: # * representation_class # * properties contract "Representation" do # ... # Setup and other examples omitted # ... describe "#==" do it "is true for Representations with the equal attributes" do representation_class.new(default_attributes).should eq representation_class.new(default_attributes) end it "is false if any property is different" do properties.each do |property| representation_class.new(default_attributes).should_not eq( representation_class.new(default_attributes_with_different_value_for(property)) ) end end end end This is fine for a class, but the behaviour I want to prove with a Collection needs to be mixed in once per collection, eg (the last two are made up): describe User do it_satisfies_contract "Entity Collection", for: "checklist_templates" it_satisfies_contract "Entity Collection", for: "groups" it_satisfies_contract "Entity Collection", for: "delegated_actions" end > describe Integer do > [1, 2].each do |i| > describe i do > it_should_behave_like 'Comparable' > end > end > end > > ... > > I know you probably have some real example in mind hiding behind that toy > example, but I believe anything you want to test can be written in the same > way (ie. without needing to inject the "<i>" into your shared examples). So as you can see, in the real (non-toy) example there's no object to be described: it's an aspect of behaviour of the test subject, and one than can occur N times. I'm aware that I'm twisting RSpec quite a bit to try to achieve this. If you (or anyone) have any thoughts though, I'd love to hear them. This one is messing with my head a bit :) Cheers Ash [1] http://www.nakedobjects.org/ -- http://www.patchspace.co.uk/ http://www.linkedin.com/in/ashleymoran _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users