From 2c43b9664b29f76c73ac8bae5400b79d0a5313e0 Mon Sep 17 00:00:00 2001 From: ryan Date: Tue, 23 Aug 2011 21:47:25 +0000 Subject: Imported minitest 2.5.0 (r6557) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33036 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/minitest/mock.rb | 59 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 10 deletions(-) (limited to 'lib/minitest/mock.rb') diff --git a/lib/minitest/mock.rb b/lib/minitest/mock.rb index 1cbf18b19f..c342c04995 100644 --- a/lib/minitest/mock.rb +++ b/lib/minitest/mock.rb @@ -15,20 +15,39 @@ module MiniTest # All mock objects are an instance of Mock class Mock + alias :__respond_to? :respond_to? + + skip_methods = %w(object_id respond_to_missing? inspect === to_s) + + instance_methods.each do |m| + undef_method m unless skip_methods.include?(m.to_s) || m =~ /^__/ + end + def initialize # :nodoc: @expected_calls = {} @actual_calls = Hash.new {|h,k| h[k] = [] } end ## - # Expect that method +name+ is called, optionally with +args+, and - # returns +retval+. + # Expect that method +name+ is called, optionally with +args+, and returns + # +retval+. # # @mock.expect(:meaning_of_life, 42) # @mock.meaning_of_life # => 42 # # @mock.expect(:do_something_with, true, [some_obj, true]) # @mock.do_something_with(some_obj, true) # => true + # + # +args+ is compared to the expected args using case equality (ie, the + # '===' operator), allowing for less specific expectations. + # + # @mock.expect(:uses_any_string, true, [String]) + # @mock.uses_any_string("foo") # => true + # @mock.verify # => true + # + # @mock.expect(:uses_one_string, true, ["foo"] + # @mock.uses_one_string("bar") # => true + # @mock.verify # => raises MockExpectationError def expect(name, retval, args=[]) @expected_calls[name] = { :retval => retval, :args => args } @@ -43,25 +62,45 @@ module MiniTest def verify @expected_calls.each_key do |name| expected = @expected_calls[name] - msg = "expected #{name}, #{expected.inspect}" - raise MockExpectationError, msg unless + msg1 = "expected #{name}, #{expected.inspect}" + msg2 = "#{msg1}, got #{@actual_calls[name].inspect}" + + raise MockExpectationError, msg2 if + @actual_calls.has_key? name and + not @actual_calls[name].include?(expected) + + raise MockExpectationError, msg1 unless @actual_calls.has_key? name and @actual_calls[name].include?(expected) end true end def method_missing(sym, *args) # :nodoc: - raise NoMethodError unless @expected_calls.has_key?(sym) - raise ArgumentError unless @expected_calls[sym][:args].size == args.size - retval = @expected_calls[sym][:retval] - @actual_calls[sym] << { :retval => retval, :args => args } + expected = @expected_calls[sym] + + unless expected then + raise NoMethodError, "unmocked method %p, expected one of %p" % + [sym, @expected_calls.keys.sort_by(&:to_s)] + end + + expected_args, retval = expected[:args], expected[:retval] + + unless expected_args.size == args.size + raise ArgumentError, "mocked method %p expects %d arguments, got %d" % + [sym, expected[:args].size, args.size] + end + + @actual_calls[sym] << { + :retval => retval, + :args => expected_args.zip(args).map { |mod, a| mod if mod === a } + } + retval end - alias :original_respond_to? :respond_to? def respond_to?(sym) # :nodoc: return true if @expected_calls.has_key?(sym) - return original_respond_to?(sym) + return __respond_to?(sym) end end end -- cgit v1.2.3