After a discussion today on rspec-users, I confirmed that it would be nice if you could structure specs like this, to break your behaviour descriptions down into related groups:

1
2
3
4
5
6
7
8
9
10
11
describe MyClass do
  facet "my_method" do
    it "should do this" 
    
    facet "some stuff" do
      it "should do that"
    end
  end
  
  it "should do the other"
end

It's especially beneficial for long Rails controller specs, where there may be several related ActiveRecord calls, view assignments, etc. It's also good for speccing objects where a load of method calls share the same context (ie constructor call).

Veteran RSpec users may recognise this as similar to Yurii Rashkovskii's "aspects" patch, previously available in the rspec-ext gem, and submitted as RSpec ticket #8654. Why, that's because I that's where I got the code from :D The RSpec trunk has changed a lot and broke both Yurii's aspects and my older version of the following code, so I updated it. (Note - this will not work with RSpec 1.0.8).

Here is the monkey-patch in all its simian ugliness, just waiting to be dropped in your spec_helper.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
module Spec
  module DSL

    module Behaviour
      @@facets = []
      def self.facets
        @@facets
      end
      def self.facets=(new_facet)
        @@facets = new_facet
      end
      
      def facet(name,&block)
        Behaviour.facets << name.to_s
        yield
        Behaviour.facets.pop
      end
      
      alias_method :original_create_example_definition,
                   :create_example_definition
      def create_example_definition(description, options={}, &block)
        unless Behaviour.facets.empty?
          description = Behaviour.facets.join(" > ") + " > " + description
        end
        
        original_create_example_definition(description, options, &block)
      end
    end

  end
end

Note that this won't resemble the finished version, as there is a lot of work to do on the output formatting. But it's useable enough in the mean time.

Don't be surprised if future revisions of the RSpec trunk break this though.

2 Responses to “Quick and dirty facets in RSpec trunk”

  1. David Chelimsky Says:

    As of RSpec-1.0 we have nested ExampleGroups, so you can say:

    describe Foo do
      describe Bar do
        ..
      end
    end
    
  2. Ash Says:

    Thanks David - I haven't had chance to try out the nested example groups yet, but I'm looking forward to using them.

Leave a Reply