rspec/rspec-mocks — pull request #243 by myronmarston (2013-03-17 15:30:40+00:00)
Title: Fix for #230

Clarify relationship between different method stub actions.

In 2.13.0 only `and_yield` and `and_return` could be combined, since
that was the only combination case that was specified by an example.
This was a regression, as reported by a user in #230.

I tried here to fully specify all of the various combinations of stub
actions. Notes:

* `and_return`, `and_raise` and `and_throw` are "terminal" actions
in the sense that they terminate the method. They _must_ happen last
and it is impossible to support more than one of these. Hence, we allow
only one of these, and allow them to be overridden. We also return `nil`
from these methods to discourage further stub configuration.
* `and_call_original` is a special case that doesn't make sense to be
combined with any of the others. Once you've set it up, this causes
any further instructions to raise an error.
* `and_yield` is treated as an "initial" action. Yielding doesn't exit
a method the way the terminal actions do. It is the only initial action.
Calling it multiple times sets up multiple yields.
* Setting a block implementation (possible by passing a block to almost
any method on the fluent interface) sets the block as the "inner" action.
It runs between the configured yields (if there are any) and the configured
terminal action (if there is one). My thinking here is that in many cases,
users use a block implementation to specify a return value, essentially
making it like a terminal action (so it should come after the `and_yield`
actions), but in other cases, the user may just use a block for a side
effect, and may configure an terminal action as well. Only one block
implementation is supported and it can be overridden.

@lsegal -- want to try this to see if it solves the problem you reported in #230 (I believe it will). If you have any feedback about the PR I'd love to hear.

@dchelimsky / @alindeman -- it'd be great to get a code review from one of you before I merge this.