Browse files

preventing negative usage of receive_messages

  • Loading branch information...
1 parent 35cce72 commit 8752218ca79022d79acac8474904b4ffceecf302 @JonRowe JonRowe committed Aug 19, 2013
View
7 lib/rspec/mocks/matchers/receive_messages.rb
@@ -19,6 +19,13 @@ def setup_expectation(subject, &block)
end
alias matches? setup_expectation
+ def setup_negative_expectation(subject, &block)
+ raise NegationUnsupportedError,
+ "`expect(...).to_not receive_messages` is not supported since it " +
+ "doesn't really make sense. What would it even mean?"
+ end
+ alias does_not_match? setup_negative_expectation
+
def setup_allowance(subject)
each_message_on( proxy_on(subject) ) do |host, message, return_value|
host.add_simple_stub(message, return_value)
View
30 lib/rspec/mocks/targets.rb
@@ -8,14 +8,24 @@ def initialize(target)
@target = target
end
- def self.delegate_to(matcher_method, options = {})
- method_name = options.fetch(:from) { :to }
- define_method(method_name) do |matcher, &block|
+ def self.delegate_to(matcher_method)
+ define_method(:to) do |matcher, &block|
unless Matchers::Receive === matcher || Matchers::ReceiveMessages === matcher
raise_unsupported_matcher(:to, matcher)
end
+ define_matcher(matcher, matcher_method, &block)
+ end
+ end
- matcher.__send__(matcher_method, @target, &block)
+ def self.delegate_not_to(matcher_method, options = {})
+ method_name = options.fetch(:from)
+ define_method(method_name) do |matcher, &block|
+ case matcher
+ when Matchers::Receive then define_matcher(matcher, matcher_method, &block)
+ when Matchers::ReceiveMessages then raise_negation_unsupported(method_name, matcher)
+ else
+ raise_unsupported_matcher(method_name, matcher)
+ end
end
end
@@ -27,6 +37,10 @@ def self.disallow_negation(method_name)
private
+ def define_matcher(matcher, name, &block)
+ matcher.__send__(name, @target, &block)
+ end
+
def raise_unsupported_matcher(method_name, matcher)
raise UnsupportedMatcherError,
"only the `receive` or `receive_messages` matchers are supported " +
@@ -54,8 +68,8 @@ class AllowanceTarget < TargetBase
class ExpectationTarget < TargetBase
EXPRESSION = :expect
delegate_to :setup_expectation
- delegate_to :setup_negative_expectation, :from => :not_to
- delegate_to :setup_negative_expectation, :from => :to_not
+ delegate_not_to :setup_negative_expectation, :from => :not_to
+ delegate_not_to :setup_negative_expectation, :from => :to_not
end
class AnyInstanceAllowanceTarget < TargetBase
@@ -68,8 +82,8 @@ class AnyInstanceAllowanceTarget < TargetBase
class AnyInstanceExpectationTarget < TargetBase
EXPRESSION = :expect_any_instance_of
delegate_to :setup_any_instance_expectation
- delegate_to :setup_any_instance_negative_expectation, :from => :not_to
- delegate_to :setup_any_instance_negative_expectation, :from => :to_not
+ delegate_not_to :setup_any_instance_negative_expectation, :from => :not_to
+ delegate_not_to :setup_any_instance_negative_expectation, :from => :to_not
end
end
end
View
29 spec/rspec/mocks/matchers/receive_messages_spec.rb
@@ -87,5 +87,34 @@ module Mocks
}.to raise_error "Implementation blocks aren't supported with `receive_messages`"
end
end
+
+ describe "negative expectation failure" do
+ let(:obj) { Object.new }
+
+ specify "allow(...).to_not receive_messages(:a => 1, :b => 2)" do
+ expect { allow(obj).to_not receive_messages(:a => 1, :b => 2) }.to(
+ raise_error "`allow(...).to_not receive_messages` is not supported "+
+ "since it doesn't really make sense. What would it even mean?"
+ )
+ end
+ specify "allow_any_instance_of(...).to_not receive_messages(:a => 1, :b => 2)" do
+ expect { allow_any_instance_of(obj).to_not receive_messages(:a => 1, :b => 2) }.to(
+ raise_error "`allow_any_instance_of(...).to_not receive_messages` is not supported "+
+ "since it doesn't really make sense. What would it even mean?"
+ )
+ end
+ specify "expect(...).to_not receive_messages(:a => 1, :b => 2)" do
+ expect { expect(obj).to_not receive_messages(:a => 1, :b => 2) }.to(
+ raise_error "`expect(...).to_not receive_messages` is not supported "+
+ "since it doesn't really make sense. What would it even mean?"
+ )
+ end
+ specify "expect_any_instance_of(...).to_not receive_messages(:a => 1, :b => 2)" do
+ expect { expect_any_instance_of(obj).to_not receive_messages(:a => 1, :b => 2) }.to(
+ raise_error "`expect_any_instance_of(...).to_not receive_messages` is not supported "+
+ "since it doesn't really make sense. What would it even mean?"
+ )
+ end
+ end
end
end

0 comments on commit 8752218

Please sign in to comment.