[rspec-users] questions about meta-programming in a shared_examples group

David Chelimsky dchelimsky at gmail.com
Tue May 11 01:47:44 EDT 2010


Hi Stephen,

On May 10, 2010, at 8:48 PM, Stephen Bannasch wrote:

> I've created a shared_examples group that helps me dry up the testing of a large set of similar rails controllers.
> 
> These controllers have an html interface but mostly what I am testing with the shared_examples group is the rendering of four different forms of xml that relate to running a dynamically created Java Web Start jnlp.
> 
> The html reports when running one of the controller specs looks like this:
> 
>  Embeddable::DataCollectorsController GET show with mime type of otml
>  renders the requested data_collector as otml without error
> 
> Here's an example of what one of the controller specs looks like:
> 
> http://github.com/stepheneb/rigse/blob/master/spec/controllers/embeddable/data_collectors_controller_spec.rb
> 
>  require 'spec_helper'
> 
>  describe Embeddable::DataCollectorsController do
> 
>    it_should_behave_like 'an embeddable controller'
> 
>    def with_tags_like_an_otml_data_collector
>      with_tag('OTDataCollector') do
>        with_tag('source') do
>          with_tag('OTDataGraphable') do
>            with_tag('dataProducer')
>          end
>        end
>        with_tag('xDataAxis') do
>          with_tag('OTDataAxis')
>        end
>        with_tag('yDataAxis') do
>          with_tag('OTDataAxis')
>        end
>      end
>    end
> 
>  end
> 
> I love how clearly each controller spec reads now and how the part that is different in the otml rendering stands out.
> 
> But I wondered if the way I am using lambdas in the shared_examples helper is fragile and might break if internals in rspec change. The meta-programming I did to get some of this to work seemed a bit messy and I was wondering if there was a simpler way.

The most obvious problem is that "have_tag" and "with_tag" will not be supported in rspec-rails-2.

I haven't looked at it in a while, but you may want to take a look at the assert2 gem. It's mostly focused on test/unit assertions, but there is an rspec matcher named be_html_with that offers a nice dsl for something close to what you're trying to do. Check the bottom of http://groups.google.com/group/merb/browse_thread/thread/3588d3f75fa0e65c.

> The describe statement in the shared_examples_for 'an embeddable controller' for that example looks like this:
> 
>  describe "with mime type of otml" do
>    it "renders the requested #{model_ivar_name_lambda.call} as otml without error" do
> 
> The beginning of the shared_examples group looks like this:
> 
>  http://github.com/stepheneb/rigse/blob/master/spec/support/embeddable_controller_helper.rb
> 
>  shared_examples_for 'an embeddable controller' do
>    integrate_views
> 
>    controller_class_lambda = lambda {
>      self.send(:described_class)
>    }
>    model_class_lambda      = lambda {
>      controller_class_lambda.call.name[/(.*)Controller/, 1].singularize.constantize
>    }
>    model_ivar_name_lambda  = lambda {
>      model_class_lambda.call.name.delete_module.underscore_module
>    }
> 
>    def with_tags_like_an_otml(model_name)
>      self.send("with_tags_like_an_otml_#{model_name}".to_sym)
>    end
> 
>    before(:each) do
>      @model_class = model_class_lambda.call
>      @model_ivar_name = model_ivar_name_lambda.call
>      unless instance_variable_defined?("@#{@model_ivar_name}".to_sym)
>        @model_ivar = instance_variable_set("@#{@model_ivar_name}",
>          Factory.create(@model_ivar_name))
>      end
>    end
> 
> 
> The method in the controller spec: with_tags_like_an_otml_data_collector is used in the shared_examples group later like this:
> 
>  with_tag('library') do
>    with_tags_like_an_otml(@model_ivar_name)
>  end
> 
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users



More information about the rspec-users mailing list