Skip to content

Commit

Permalink
Raise an error if a yield matcher is used w/ an expect block that acc…
Browse files Browse the repository at this point in the history
…epts no args.

The expect block must accept an arg, and pass it on to the method-under-test as a block, in order for these yield matchers to work properly.  Since this is atypical for an expect block, this error will help guide people when they use these matchers incorrectly.
  • Loading branch information
myronmarston committed Mar 31, 2012
1 parent 0e79594 commit 66a2f01
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
21 changes: 21 additions & 0 deletions lib/rspec/matchers/built_in/yield.rb
@@ -1,8 +1,20 @@
module RSpec
module Matchers
module BuiltIn
module YieldMatcherHelpers
private
def assert_valid_expect_block(block)
return if block.arity == 1
raise "Your expect block must accept an argument to be used with this " +
"matcher. Pass the argument as a block on to the method you are testing."
end
end

class YieldControl
include YieldMatcherHelpers

def matches?(block)
assert_valid_expect_block block
yielded = false
block.call(lambda { |*| yielded = true })
yielded
Expand All @@ -18,7 +30,10 @@ def failure_message_for_should_not
end

class YieldWithNoArgs
include YieldMatcherHelpers

def matches?(block)
assert_valid_expect_block block
yielded, args = false, nil
block.call(lambda { |*a| yielded = true; args = a })
@yielded, @args = yielded, args
Expand All @@ -45,11 +60,14 @@ def failure_reason
end

class YieldWithArgs
include YieldMatcherHelpers

def initialize(*args)
@expected = args
end

def matches?(block)
assert_valid_expect_block block
yielded, actual = false, nil
block.call(lambda { |*a| yielded = true; actual = a })
@yielded, @actual = yielded, actual
Expand Down Expand Up @@ -109,11 +127,14 @@ def all_args_match?
end

class YieldSuccessiveArgs
include YieldMatcherHelpers

def initialize(*args)
@expected = args
end

def matches?(block)
assert_valid_expect_block block
actual = []
block.call(lambda { |a| actual << a })
@actual = actual
Expand Down
24 changes: 24 additions & 0 deletions spec/rspec/matchers/yield_spec.rb
Expand Up @@ -63,6 +63,12 @@ def each_arg(*args, &block)
expect { |b| _yield_with_no_args(&b) }.not_to yield_control
}.to fail_with(/expected given block not to yield control/)
end

it 'fails if the expect block does not accept an argument' do
expect {
expect { }.not_to yield_control
}.to raise_error(/expect block must accept an argument/)
end
end
end

Expand Down Expand Up @@ -105,6 +111,12 @@ def each_arg(*args, &block)
expect { |b| _yield_with_no_args(&b) }.not_to yield_with_no_args
}.to fail_with(/expected given block not to yield with no arguments, but did/)
end

it 'fails if the expect block does not accept an argument' do
expect {
expect { }.not_to yield_with_no_args
}.to raise_error(/expect block must accept an argument/)
end
end
end

Expand Down Expand Up @@ -143,6 +155,12 @@ def each_arg(*args, &block)
it 'passes if the block yields with no arguments' do
expect { |b| _yield_with_no_args(&b) }.not_to yield_with_args
end

it 'fails if the expect block does not accept an argument' do
expect {
expect { }.not_to yield_with_args
}.to raise_error(/expect block must accept an argument/)
end
end

describe "expect {...}.to yield_with_args(3, 17)" do
Expand Down Expand Up @@ -269,6 +287,12 @@ def each_arg(*args, &block)
expect { |b| [1, 2, 3].each(&b) }.not_to yield_successive_args(1, 2, 3)
}.to fail_with(/expected given block not to yield successively/)
end

it 'fails if the expect block does not accept an argument' do
expect {
expect { }.not_to yield_successive_args(1, 2, 3)
}.to raise_error(/expect block must accept an argument/)
end
end

describe "expect {...}.to yield_successive_args(String, Fixnum)" do
Expand Down

0 comments on commit 66a2f01

Please sign in to comment.