On 29/09/06, <b class="gmail_sendername">Jay</b> <<a href="mailto:jay@jayfields.com">jay@jayfields.com</a>> wrote:<div><span class="gmail_quote"></span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I lied, I don't actually need different responses each time I call<br>the method. So the last email of mine is probably worthless.<br><br>Instead, I need yield to yield 3 values when I call it once:<br>(behavior that mimics
Find.find)<br> def test_generate(documentation = '/test_documentation/',<br>destination = '/destination/')<br> Find.expects(:find).with(documentation).multiyield<br>('filename.yaml', 'blah.xml')<br> File.expects
(:directory?).with('filename.yaml')<br> File.expects(:directory?).with('blah.xml')<br> ....<br> end<br><br>So, I wrote multiyield....<br>Index: test/mocha/expectation_test.rb<br>===================================================================
<br>--- test/mocha/expectation_test.rb (revision 62)<br>+++ test/mocha/expectation_test.rb (working copy)<br>@@ -91,6 +91,13 @@<br> assert_equal parameters_for_yield, yielded_parameters<br> end<br>+ def test_should_yield_multiple_times_with_multiyield
<br>+ expectation = new_expectation.multiyield(:foo, 1, 'bar')<br>+ actual = []<br>+ expectation.invoke() { |parameter| actual << parameter }<br>+ assert_equal [:foo, 1, 'bar'], actual<br>+ end<br>+<br>
def test_should_return_specified_value<br> expectation = new_expectation.returns(99)<br> assert_equal 99, expectation.invoke<br>Index: lib/mocha/expectation.rb<br>===================================================================
<br>--- lib/mocha/expectation.rb (revision 62)<br>+++ lib/mocha/expectation.rb (working copy)<br>@@ -26,6 +26,10 @@<br> @yield = nil<br> end<br><br>+ def multiyield?<br>+ @multiyield<br>+ end<br>
+<br> def yield?<br> @yield<br> end<br>@@ -178,6 +182,12 @@<br> @parameters_to_yield = parameters<br> self<br> end<br>+<br>+ def multiyield(*parameters)<br>+ @multiyield = true<br>
+ @parameters_to_yield = parameters<br>+ self<br>+ end<br> # :call-seq: returns(value) -> expectation<br> # :call-seq: returns(*values) -> expectation<br>@@ -218,6 +228,7 @@<br> def invoke
<br> @invoked += 1<br> yield(*@parameters_to_yield) if yield? and block_given?<br>+ @parameters_to_yield.each { |element| yield(element) } if<br>multiyield? and block_given?<br> @return_value.is_a?(Proc) ? @return_value.call : @return_value
<br> end<br><br>Is this already in the framework and I missed it?</blockquote><div><br>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...
<br><br><span style="font-family: courier new,monospace;">
def my_method</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> yield(1)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
yield(2)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">end</span><br></div><br>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...
<br><br><span style="font-family: courier new,monospace;">def my_method</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> yield(1)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> yield(2,3)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">end</span><br style="font-family: courier new,monospace;">
<br></div>I like the way <span style="font-family: courier new,monospace;">yields()</span> currently mirrors the behaviour of <span style="font-family: courier new,monospace;">returns()</span>, but it's becoming clear that
<span style="font-family: courier new,monospace;">yields()</span> 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.
<br><br>Thoughts?<br>-- <br>James.<br><a href="http://blog.floehopper.org">http://blog.floehopper.org</a>