Permalink
Browse files

Raise an error if a single-yield matcher is used with a multi-yield m…

…ethod.

Only the yield_successive_args matcher is designed for the multi-yield case.
  • Loading branch information...
1 parent 7a0e4bb commit f8c3c01fd403a9affba6faa9615bcbfd0bf0481e @myronmarston myronmarston committed Apr 10, 2012
Showing with 32 additions and 3 deletions.
  1. +14 −3 lib/rspec/matchers/built_in/yield.rb
  2. +18 −0 spec/rspec/matchers/yield_spec.rb
@@ -31,6 +31,17 @@ def single_yield_args
yielded_args.first
end
+ def yielded_once?(matcher_name)
+ case num_yields
+ when 1 then true
+ when 0 then false
+ else
+ raise "The #{matcher_name} matcher is not designed to be used with a " +
+ "method that yields multiple times. Use the yield_successive_args " +
+ "matcher for that case."
+ end
+ end
+
def successive_yield_args
yielded_args.map do |arg_array|
arg_array.size == 1 ? arg_array.first : arg_array
@@ -58,7 +69,7 @@ class YieldControl
def matches?(block)
probe = YieldProbe.probe(block)
- probe.num_yields > 0
+ probe.yielded_once?(:yield_control)
end
def failure_message_for_should
@@ -75,7 +86,7 @@ class YieldWithNoArgs
def matches?(block)
@probe = YieldProbe.probe(block)
- @probe.num_yields > 0 && @probe.single_yield_args.none?
+ @probe.yielded_once?(:yield_with_no_args) && @probe.single_yield_args.none?
end
def failure_message_for_should
@@ -105,7 +116,7 @@ def initialize(*args)
def matches?(block)
@probe = YieldProbe.probe(block)
@actual = @probe.single_yield_args
- @probe.num_yields > 0 && args_match?
+ @probe.yielded_once?(:yield_with_args) && args_match?
end
def failure_message_for_should
@@ -55,6 +55,12 @@ def each_arg(*args, &block)
expect { |b| _dont_yield(&b) }.to yield_control
}.to fail_with(/expected given block to yield control/)
end
+
+ it 'raises an error if it yields multiple times' do
+ expect {
+ expect { |b| [1, 2].each(&b) }.to yield_control
+ }.to raise_error(/not designed.*yields multiple times/)
+ end
end
describe "expect {...}.not_to yield_control" do
@@ -109,6 +115,12 @@ def each_arg(*args, &block)
expect { |b| _yield_with_args(1, &b) }.to yield_with_no_args
}.to fail_with(/expected given block to yield with no arguments, but yielded with arguments/)
end
+
+ it 'raises an error if it yields multiple times' do
+ expect {
+ expect { |b| [1, 2].each(&b) }.to yield_with_no_args
+ }.to raise_error(/not designed.*yields multiple times/)
+ end
end
describe "expect {...}.not_to yield_with_no_args" do
@@ -164,6 +176,12 @@ def each_arg(*args, &block)
expect { |b| _yield_with_no_args(&b) }.to yield_with_args
}.to fail_with(/expected given block to yield with arguments, but yielded with no arguments/)
end
+
+ it 'raises an error if it yields multiple times' do
+ expect {
+ expect { |b| [1, 2].each(&b) }.to yield_with_args
+ }.to raise_error(/not designed.*yields multiple times/)
+ end
end
describe "expect {...}.not_to yield_with_args" do

0 comments on commit f8c3c01

Please sign in to comment.