[mocha-developer] multiyield

James Mead jamesmead44 at gmail.com
Fri Oct 6 05:28:46 EDT 2006


On 29/09/06, Jay <jay at jayfields.com> wrote:
>
> I lied, I don't actually need different responses each time I call
> the method.  So the last email of mine is probably worthless.
>
> Instead, I need yield to yield 3 values when I call it once:
> (behavior that mimics Find.find)
>    def test_generate(documentation = '/test_documentation/',
> destination = '/destination/')
>      Find.expects(:find).with(documentation).multiyield
> ('filename.yaml', 'blah.xml')
>      File.expects(:directory?).with('filename.yaml')
>      File.expects(:directory?).with('blah.xml')
>      ....
>    end
>
> So, I wrote multiyield....
> Index: test/mocha/expectation_test.rb
> ===================================================================
> --- test/mocha/expectation_test.rb      (revision 62)
> +++ test/mocha/expectation_test.rb      (working copy)
> @@ -91,6 +91,13 @@
>       assert_equal parameters_for_yield, yielded_parameters
>     end
> +  def test_should_yield_multiple_times_with_multiyield
> +    expectation = new_expectation.multiyield(:foo, 1, 'bar')
> +    actual = []
> +    expectation.invoke() { |parameter| actual << parameter }
> +    assert_equal [:foo, 1, 'bar'], actual
> +  end
> +
>     def test_should_return_specified_value
>       expectation = new_expectation.returns(99)
>       assert_equal 99, expectation.invoke
> Index: lib/mocha/expectation.rb
> ===================================================================
> --- lib/mocha/expectation.rb    (revision 62)
> +++ lib/mocha/expectation.rb    (working copy)
> @@ -26,6 +26,10 @@
>         @yield = nil
>       end
>
> +    def multiyield?
> +      @multiyield
> +    end
> +
>       def yield?
>         @yield
>       end
> @@ -178,6 +182,12 @@
>         @parameters_to_yield = parameters
>         self
>       end
> +
> +    def multiyield(*parameters)
> +      @multiyield = true
> +      @parameters_to_yield = parameters
> +      self
> +    end
>       # :call-seq: returns(value) -> expectation
>       # :call-seq: returns(*values) -> expectation
> @@ -218,6 +228,7 @@
>       def invoke
>         @invoked += 1
>         yield(*@parameters_to_yield) if yield? and block_given?
> +      @parameters_to_yield.each { |element| yield(element) } if
> multiyield? and block_given?
>         @return_value.is_a?(Proc) ? @return_value.call : @return_value
>       end
>
> Is this already in the framework and I missed it?


No it's not in the framework already. Thanks for the patch. Am I correct in
thinking this patch only deals with simulating a method that yields multiple
times with a single parameter each time, like this...

def my_method
  yield(1)
  yield(2)
end

I'm wondering if we should also deal with the more generic case where
different numbers of parameters could be yielded each time, like this...

def my_method
  yield(1)
  yield(2,3)
end

I like the way yields() currently mirrors the behaviour of returns(), but
it's becoming clear that yields() has to deal with more multiplicity - you
can only return once from a method with a single value; whereas you can
yield multiple values multiple times from a single method. It would be good
to deal with all this multiplicity at once with a single simple syntax.

Thoughts?
-- 
James.
http://blog.floehopper.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/mocha-developer/attachments/20061006/7004e49c/attachment.html 


More information about the mocha-developer mailing list