Skip to content

Commit

Permalink
Allow a as_null_object to be passed to with. Closes rspec#98
Browse files Browse the repository at this point in the history
  • Loading branch information
justinko committed Jan 26, 2012
1 parent ea8cc1f commit de283b3
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 19 deletions.
10 changes: 8 additions & 2 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
### dev

Bug fixes

* Allow a `as_null_object` to be passed to `with`

### 2.8.0 / 2012-01-04

[full changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0.rc2...v2.8.0)
Expand All @@ -24,7 +30,7 @@ Enhancements

Enhancements

* Use `__send__` rather than `send` (alextk)
* Use `__send__` rather than `send` (alextk)
* Add support for `any_instance.stub_chain` (Sidu Ponnappa)
* Add support for `any_instance` argument matching based on `with` (Sidu
Ponnappa and Andy Lindeman)
Expand Down Expand Up @@ -77,7 +83,7 @@ rspec-core-2.4.0 release.

[full changelog](http://github.com/rspec/rspec-mocks/compare/v2.2.0...v2.3.0)

Bug fixes
Bug fixes

* Fix our Marshal extension so that it does not interfere with objects that
have their own `@mock_proxy` instance variable. (Myron Marston)
Expand Down
21 changes: 9 additions & 12 deletions lib/rspec/mocks/argument_expectation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ module Mocks
# @api private
class ArgumentExpectation
attr_reader :args

def initialize(*args, &block)
@args = args
@block = args.empty? ? block : nil
@match_any_args = false
@matchers = nil

case args.first
when ArgumentMatchers::AnyArgsMatcher
@match_any_args = true
Expand All @@ -19,34 +19,31 @@ def initialize(*args, &block)
@matchers = args.collect {|arg| matcher_for(arg)}
end
end

def matcher_for(arg)
return ArgumentMatchers::MatcherMatcher.new(arg) if is_matcher?(arg)
return ArgumentMatchers::RegexpMatcher.new(arg) if arg.is_a?(Regexp)
return ArgumentMatchers::EqualityProxy.new(arg)
end

def is_matcher?(obj)
!null_object?(obj) & obj.respond_to?(:matches?) & [:failure_message_for_should, :failure_message].any? { |m| obj.respond_to?(m) }
!obj.null_object? & obj.respond_to?(:matches?) & [:failure_message_for_should, :failure_message].any? { |m| obj.respond_to?(m) }
end

def args_match?(*args)
match_any_args? || block_passes?(*args) || matchers_match?(*args)
end

private
def null_object?(obj)
obj.respond_to?(:__rspec_double_acting_as_null_object?) && obj.__rspec_double_acting_as_null_object?
end


def block_passes?(*args)
@block.call(*args) if @block
end

def matchers_match?(*args)
@matchers == args
end

def match_any_args?
@match_any_args
end
Expand Down
2 changes: 2 additions & 0 deletions lib/rspec/mocks/serialization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ module Serialization
# @private
def self.fix_for(object)
object.extend(YAML) if defined?(::YAML)
rescue TypeError
# Can't extend Fixnums, Symbols, true, false, or nil
end

# @private
Expand Down
7 changes: 2 additions & 5 deletions spec/rspec/mocks/argument_expectation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,18 @@
module RSpec
module Mocks
describe ArgumentExpectation do

it "considers an object that responds to #matches? and #failure_message_for_should to be a matcher" do
argument_expecatation = RSpec::Mocks::ArgumentExpectation.new
obj = double("matcher")
obj.stub(:respond_to?).with(:__rspec_double_acting_as_null_object?).and_return(false)
obj.stub(:respond_to?).with(:matches?).and_return(true)
obj.stub(:respond_to?).with(:failure_message_for_should).and_return(true)
argument_expecatation.is_matcher?(obj).should be_true
end

it "considers an object that responds to #matches? and #failure_message to be a matcher for backward compatibility" do
argument_expecatation = RSpec::Mocks::ArgumentExpectation.new
obj = double("matcher")
obj.stub(:respond_to?).with(:__rspec_double_acting_as_null_object?).and_return(false)
obj.stub(:respond_to?).with(:matches?).and_return(true)
obj.stub(:respond_to?).with(:failure_message_for_should).and_return(false)
obj.stub(:respond_to?).with(:failure_message).and_return(true)
Expand All @@ -26,7 +24,6 @@ module Mocks
it "does NOT consider an object that only responds to #matches? to be a matcher" do
argument_expecatation = RSpec::Mocks::ArgumentExpectation.new
obj = double("matcher")
obj.stub(:respond_to?).with(:__rspec_double_acting_as_null_object?).and_return(false)
obj.stub(:respond_to?).with(:matches?).and_return(true)
obj.stub(:respond_to?).with(:failure_message_for_should).and_return(false)
obj.stub(:respond_to?).with(:failure_message).and_return(false)
Expand Down

0 comments on commit de283b3

Please sign in to comment.