[rspec-users] Evaluating shared example customisation block before shared block

Myron Marston myron.marston at gmail.com
Sat Jul 31 14:06:47 EDT 2010


> You can still get the same outcome, but you have to implement it in the group like this:

> unless defined?(:foo)
>  def foo; "foo"; end
> end

Good point--I hadn't thought of that.  The one issue I see with it is
that the author of the shared example group may not have knowledge of
which helper methods consumers will need to override.  So he/she
either defines all helper methods that way, or guesses about which
ones to define that way (and potentially guesses wrong).

> Maybe a DSL method while I'm working on it?  Maybe:
>
>   default_helper(:foo) do
>     "foo"
>   end
>
> WDYT?

If we go the route of having the customization block evaluated first,
then I like the idea, but I'm generally wary of adding more DSL
methods to RSpec.  I think we should be careful to only add new DSL
methods that many people will find useful.  If you find it useful,
it's very easy to use it in your project without it being part of
RSpec: just define default_helper in a module, and use config.extend
YourModule in the RSpec.configuration block.  (Note that I'm _not_
against adding this to RSpec: I just want to be sure we don't add a
bunch of DSL methods that have limited usefulness.)

Looking back at the initial example that prompted the thread, it looks
to me like the primary use case for evaluating the customization block
first is so that you can parameterize the shared example group's
example descriptions.  (There may be other use cases for defining a
class-level helper methods, but none springs to mind).  I also do this
frequently.  Often times I have something like this:

[:foo, :bar, :baz].each do |method|
  it "does something for #{method}" do
     subject.send(method).should ...
  end
end

In this case I'm using the method parameter at the class level (to
interpolate into the description string) and at the instance level
(within the example itself).

If we evaluated the customization block first, it would allow this,
but you'd have to define both an instance and class helper:

it_should_behave_like "something" do
  def self.method_name; :foo; end
  def method_name; :foo; end
end

I think this is a clunky way to essentially pass a parameter to the
shared example group.  Better would be something like this:

it_should_behave_like "something" do
  providing :method_name, :foo
end

The instance of the shared example group provides :foo as the value of
the method_name parameter.  providing simply defines a class and an
instance helper method with the given value.

I've written up an untested gist with a start for the code that would
implement this:

http://gist.github.com/502409

I think there's value in evaluating the customization block first and
value in evaluating it last.  We can get the best of both worlds if we
limit what's evaluated first to a subset (say, a few DSL methods, and
maybe all class method definitions), extract it, and evaluate that
first, then evaluate the shared block first, then evaluate the
customization block.  The gist demonstrates this as well.  This may
confuse people, but it does give us the best of both worlds, I think.

Myron


On Jul 31, 12:56 am, Ashley Moran <ashley.mo... at patchspace.co.uk>
wrote:
> On 31 Jul 2010, at 1:10 AM, David Chelimsky wrote:
>
> > You can still get the same outcome, but you have to implement it in the group like this:
>
> > unless defined?(:foo)
> >  def foo; "foo"; end
> > end
>
> Maybe a DSL method while I'm working on it?  Maybe:
>
>   default_helper(:foo) do
>     "foo"
>   end
>
> WDYT?
>
> > I think it's a good trade-off to put that burden on the group (and it's author) rather that the consumers of the group.
>
> Agreed, it'd cause a lot of duplication of effort the other way round.
>
> --http://www.patchspace.co.uk/http://www.linkedin.com/in/ashleymoran
>
> _______________________________________________
> rspec-users mailing list
> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users


More information about the rspec-users mailing list