On Aug 1, 2010, at 5:12 PM, Ashley Moran wrote:

> 
> On 1 Aug 2010, at 3:43 PM, David Chelimsky wrote:
> 
>> shared_examples_for "blah" do |a,b|
>> ...
>> end
>> 
>> it_should_behave_like "blah", 1, 2
>> 
>> That wouldn't have worked with the old implementation, but it would work 
>> perfectly well now. This would also "just work" with hash-as-keyword-args:
>> 
>> shared_examples_for "blah" do |options|
>> it "blah #{options[:a]}" do
>>   ..
>> end
>> end
>> 
>> it_should_behave_like "blah", :a => 1
>> 
>> Now you can do this:
>> 
>> [1,2,3].each do |n|
>> it_should_behave_like "blah", :a => n
>> end
>> 
>> And we can still use the customization block to define methods, hooks 
>> (before/after) and let(). Now it just feels like the rest of RSpec.
>> 
>> Thoughts?
> 
> One thought: me.facepalm :)
> 
> The only thing it lacks is a DSL to define the requirements.  Would it still 
> be desirable to be able to write:
> 
>  shared_examples_for "blah" do |options|
>    require_argument options[:a]
>    it "blah #{options[:a]}" do
>      ..
>    end
>  end
> 
> Or some such?
> 
> Also, after staring at this for a while, I'm puzzled by something.  In this 
> code:
> 
>  it_should_behave_like "blah", :a => 1
> 
> how does :a => 1 get passed to the "options" block, as `shared_block` in the 
> code is never called with arguments?  Would this need another code change?  
> (Apologies if I'm being thick, it's late and I should probably go to bed, but 
> I wanted to review this first...)

Actually, I just discovered that ruby 1.8.7 actually added module_exec. What 
does this mean? It means this:

      def self.define_shared_group_method(new_name, report_label=nil)
        module_eval(<<-END_RUBY, __FILE__, __LINE__)
          def self.#{new_name}(name, *args, &customization_block)
            shared_block = world.shared_example_groups[name]
            raise "Could not find shared example group named \#{name.inspect}" 
unless shared_block

            describe("#{report_label || "it should behave like"} \#{name}") do
              module_exec *args, &shared_block
              module_exec *args, &customization_block if customization_block
            end
          end
        END_RUBY
      end

What does that mean? It means this:

shared_examples_for "foo" do |a,b,c|
  it "#{a} #{b} #{c}s" do
    a.should do_something_with(b, c)
  end
end

describe "something" do
  it_behaves_like "foo", 1, 2, 3
end

Ta da!!!!!!

Two problems to solve at this point:

1. order of evaluation of blocks
2. what to do about ruby 1.8.6

re: order of evaluation of blocks, I think I'm inclined to go one way one 
minute, and another the next. Somebody convince me of one or the other.

re: 1.8.6, we've got a home-grown implementation of instance_exec that runs in 
1.8.6 (although I just discovered that it's broken - fix coming shortly). I 
could

a) add such a thing for module_exec as well, though I haven't quite figured out 
how that works yet. 
b) only support parameterized shared groups in ruby 1.8.7 or better
c). the most drastic option, would be to drop support for 1.8.6 entirely, but I 
don't think that's really feasible yet.

Thoughts?

David

> Cheers
> Ash

_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to