diff options
author | francis <francis> | 2008-01-23 01:54:49 +0000 |
---|---|---|
committer | francis <francis> | 2008-01-23 01:54:49 +0000 |
commit | fdaa98e06ba6d6f8b62480a83e9ecffdbcb21402 (patch) | |
tree | 40b8b0d7602a7a17bead44e0fd3a2ea101b18bd6 /vendor/plugins/rspec/lib/spec/mocks | |
parent | 60eaae4f7df1f1dae91defb87d3707451c359cf4 (diff) |
Upgrade to rspec 1.1.2
Diffstat (limited to 'vendor/plugins/rspec/lib/spec/mocks')
-rw-r--r-- | vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb | 2 | ||||
-rw-r--r-- | vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb | 119 | ||||
-rw-r--r-- | vendor/plugins/rspec/lib/spec/mocks/methods.rb | 4 | ||||
-rw-r--r-- | vendor/plugins/rspec/lib/spec/mocks/mock.rb | 27 | ||||
-rw-r--r-- | vendor/plugins/rspec/lib/spec/mocks/proxy.rb | 49 | ||||
-rw-r--r-- | vendor/plugins/rspec/lib/spec/mocks/space.rb | 2 | ||||
-rw-r--r-- | vendor/plugins/rspec/lib/spec/mocks/spec_methods.rb | 32 |
7 files changed, 146 insertions, 89 deletions
diff --git a/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb b/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb index 5da069b87..34a1d4d03 100644 --- a/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb +++ b/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb @@ -138,7 +138,7 @@ module Spec end def warn_deprecated(deprecated_method, instead) - STDERR.puts "The #{deprecated_method} constraint is deprecated. Use #{instead} instead." + Kernel.warn "The #{deprecated_method} constraint is deprecated. Use #{instead} instead." end def convert_constraint(constraint) diff --git a/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb b/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb index 74ade3c58..6bd2f1c32 100644 --- a/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb +++ b/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb @@ -10,8 +10,8 @@ module Spec @expected_from = expected_from @sym = sym @method_block = method_block - @return_block = lambda {} - @received_count = 0 + @return_block = nil + @actual_received_count = 0 @expected_received_count = expected_received_count @args_expectation = ArgumentExpectation.new([AnyArgsConstraint.new]) @consecutive = false @@ -20,7 +20,7 @@ module Spec @order_group = expectation_ordering @at_least = nil @at_most = nil - @args_to_yield = nil + @args_to_yield = [] end def expected_args @@ -29,17 +29,18 @@ module Spec def and_return(*values, &return_block) Kernel::raise AmbiguousReturnError unless @method_block.nil? - if values.size == 0 - value = nil - elsif values.size == 1 - value = values[0] + case values.size + when 0 then value = nil + when 1 then value = values[0] else value = values @consecutive = true - @expected_received_count = values.size if @expected_received_count != :any && + @expected_received_count = values.size if !ignoring_args? && @expected_received_count < values.size end @return_block = block_given? ? return_block : lambda { value } + # Ruby 1.9 - see where this is used below + @ignore_args = !block_given? end # :call-seq: @@ -62,7 +63,8 @@ module Spec end def and_yield(*args) - @args_to_yield = args + @args_to_yield << args + self end def matches(sym, args) @@ -73,25 +75,26 @@ module Spec @order_group.handle_order_constraint self begin - if @exception_to_raise.class == Class - @exception_instance_to_raise = @exception_to_raise.new - else - @exception_instance_to_raise = @exception_to_raise - end Kernel::raise @exception_to_raise unless @exception_to_raise.nil? Kernel::throw @symbol_to_throw unless @symbol_to_throw.nil? - + if !@method_block.nil? - return invoke_method_block(args) - elsif !@args_to_yield.nil? - return invoke_with_yield(block) - elsif @consecutive - return invoke_consecutive_return_block(args, block) + default_return_val = invoke_method_block(args) + elsif @args_to_yield.size > 0 + default_return_val = invoke_with_yield(block) else + default_return_val = nil + end + + if @consecutive + return invoke_consecutive_return_block(args, block) + elsif @return_block return invoke_return_block(args, block) + else + return default_return_val end ensure - @received_count += 1 + @actual_received_count += 1 end end @@ -109,25 +112,32 @@ module Spec if block.nil? @error_generator.raise_missing_block_error @args_to_yield end - if block.arity > -1 && @args_to_yield.length != block.arity - @error_generator.raise_wrong_arity_error @args_to_yield, block.arity + @args_to_yield.each do |args_to_yield_this_time| + if block.arity > -1 && args_to_yield_this_time.length != block.arity + @error_generator.raise_wrong_arity_error args_to_yield_this_time, block.arity + end + block.call(*args_to_yield_this_time) end - block.call(*@args_to_yield) end def invoke_consecutive_return_block(args, block) args << block unless block.nil? value = @return_block.call(*args) - index = [@received_count, value.size-1].min + index = [@actual_received_count, value.size-1].min value[index] end def invoke_return_block(args, block) args << block unless block.nil? - value = @return_block.call(*args) - - value + # Ruby 1.9 - when we set @return_block to return values + # regardless of arguments, any arguments will result in + # a "wrong number of arguments" error + if @ignore_args + @return_block.call() + else + @return_block.call(*args) + end end end @@ -138,17 +148,33 @@ module Spec end def verify_messages_received - return if @expected_received_count == :any - return if (@at_least) && (@received_count >= @expected_received_count) - return if (@at_most) && (@received_count <= @expected_received_count) - return if @expected_received_count == @received_count + return if ignoring_args? || matches_exact_count? || + matches_at_least_count? || matches_at_most_count? - begin - @error_generator.raise_expectation_error(@sym, @expected_received_count, @received_count, *@args_expectation.args) - rescue => error - error.backtrace.insert(0, @expected_from) - Kernel::raise error - end + generate_error + rescue Spec::Mocks::MockExpectationError => error + error.backtrace.insert(0, @expected_from) + Kernel::raise error + end + + def ignoring_args? + @expected_received_count == :any + end + + def matches_at_least_count? + @at_least && @actual_received_count >= @expected_received_count + end + + def matches_at_most_count? + @at_most && @actual_received_count <= @expected_received_count + end + + def matches_exact_count? + @expected_received_count == @actual_received_count + end + + def generate_error + @error_generator.raise_expectation_error(@sym, @expected_received_count, @actual_received_count, *@args_expectation.args) end def with(*args, &block) @@ -215,9 +241,14 @@ module Spec def set_expected_received_count(relativity, n) @at_least = (relativity == :at_least) @at_most = (relativity == :at_most) - @expected_received_count = 1 if n == :once - @expected_received_count = 2 if n == :twice - @expected_received_count = n if n.kind_of? Numeric + @expected_received_count = case n + when Numeric + n + when :once + 1 + when :twice + 2 + end end end @@ -232,11 +263,5 @@ module Spec end end - class MethodStub < BaseExpectation - def initialize(message, expectation_ordering, expected_from, sym, method_block) - super(message, expectation_ordering, expected_from, sym, method_block, 0) - @expected_received_count = :any - end - end end end diff --git a/vendor/plugins/rspec/lib/spec/mocks/methods.rb b/vendor/plugins/rspec/lib/spec/mocks/methods.rb index 3d898cf31..d9fa324d3 100644 --- a/vendor/plugins/rspec/lib/spec/mocks/methods.rb +++ b/vendor/plugins/rspec/lib/spec/mocks/methods.rb @@ -9,8 +9,8 @@ module Spec __mock_proxy.add_negative_message_expectation(caller(1)[0], sym.to_sym, &block) end - def stub!(sym) - __mock_proxy.add_stub(caller(1)[0], sym.to_sym) + def stub!(sym, opts={}) + __mock_proxy.add_stub(caller(1)[0], sym.to_sym, opts) end def received_message?(sym, *args, &block) #:nodoc: diff --git a/vendor/plugins/rspec/lib/spec/mocks/mock.rb b/vendor/plugins/rspec/lib/spec/mocks/mock.rb index aa380e0af..f029b1b8f 100644 --- a/vendor/plugins/rspec/lib/spec/mocks/mock.rb +++ b/vendor/plugins/rspec/lib/spec/mocks/mock.rb @@ -6,9 +6,18 @@ module Spec # Creates a new mock with a +name+ (that will be used in error messages only) # == Options: # * <tt>:null_object</tt> - if true, the mock object acts as a forgiving null object allowing any message to be sent to it. - def initialize(name, options={}) + def initialize(name, stubs_and_options={}) @name = name - @options = options + @options = parse_options(stubs_and_options) + assign_stubs(stubs_and_options) + end + + # This allows for comparing the mock to other objects that proxy + # such as ActiveRecords belongs_to proxy objects + # By making the other object run the comparison, we're sure the call gets delegated to the proxy target + # This is an unfortunate side effect from ActiveRecord, but this should be safe unless the RHS redefines == in a nonsensical manner + def ==(other) + other == __mock_proxy end def method_missing(sym, *args, &block) @@ -16,7 +25,7 @@ module Spec begin return self if __mock_proxy.null_object? super(sym, *args, &block) - rescue NoMethodError + rescue NameError __mock_proxy.raise_unexpected_message_error sym, *args end end @@ -24,6 +33,18 @@ module Spec def inspect "#<#{self.class}:#{sprintf '0x%x', self.object_id} @name=#{@name.inspect}>" end + + private + + def parse_options(options) + options.has_key?(:null_object) ? {:null_object => options.delete(:null_object)} : {} + end + + def assign_stubs(stubs) + stubs.each_pair do |message, response| + stub!(message).and_return(response) + end + end end end end diff --git a/vendor/plugins/rspec/lib/spec/mocks/proxy.rb b/vendor/plugins/rspec/lib/spec/mocks/proxy.rb index 6c79d1068..03db3b113 100644 --- a/vendor/plugins/rspec/lib/spec/mocks/proxy.rb +++ b/vendor/plugins/rspec/lib/spec/mocks/proxy.rb @@ -22,29 +22,27 @@ module Spec end def add_message_expectation(expected_from, sym, opts={}, &block) - __add sym, block + __add sym @expectations << MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil, 1, opts) @expectations.last end def add_negative_message_expectation(expected_from, sym, &block) - __add sym, block + __add sym @expectations << NegativeMessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil) @expectations.last end - def add_stub(expected_from, sym) - __add sym, nil - @stubs.unshift MethodStub.new(@error_generator, @expectation_ordering, expected_from, sym, nil) + def add_stub(expected_from, sym, opts={}) + __add sym + @stubs.unshift MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, nil, :any, opts) @stubs.first end def verify #:nodoc: - begin - verify_expectations - ensure - reset - end + verify_expectations + ensure + reset end def reset @@ -55,8 +53,7 @@ module Spec end def received_message?(sym, *args, &block) - return true if @messages_received.find {|array| array == [sym, args, block]} - return false + @messages_received.any? {|array| array == [sym, args, block]} end def has_negative_expectation?(sym) @@ -66,7 +63,7 @@ module Spec def message_received(sym, *args, &block) if expectation = find_matching_expectation(sym, *args) expectation.invoke(args, block) - elsif stub = find_matching_method_stub(sym) + elsif stub = find_matching_method_stub(sym, *args) stub.invoke([], block) elsif expectation = find_almost_matching_expectation(sym, *args) raise_unexpected_message_args_error(expectation, *args) unless has_negative_expectation?(sym) unless null_object? @@ -85,14 +82,17 @@ module Spec private - def __add(sym, block) + def __add(sym) $rspec_mocks.add(@target) unless $rspec_mocks.nil? define_expected_method(sym) end def define_expected_method(sym) - if target_responds_to?(sym) && !@proxied_methods.include?(sym) - metaclass.__send__(:alias_method, munge(sym), sym) if metaclass.instance_methods.include?(sym.to_s) + if target_responds_to?(sym) && !metaclass.method_defined?(munge(sym)) + munged_sym = munge(sym) + metaclass.instance_eval do + alias_method munged_sym, sym if method_defined?(sym.to_s) + end @proxied_methods << sym end @@ -141,11 +141,14 @@ module Spec def reset_proxied_methods @proxied_methods.each do |sym| - if metaclass.instance_methods.include?(munge(sym).to_s) - metaclass.__send__(:alias_method, sym, munge(sym)) - metaclass.__send__(:undef_method, munge(sym)) - else - metaclass.__send__(:undef_method, sym) + munged_sym = munge(sym) + metaclass.instance_eval do + if method_defined?(munged_sym.to_s) + alias_method sym, munged_sym + undef_method munged_sym + else + undef_method sym + end end end end @@ -158,8 +161,8 @@ module Spec @expectations.find {|expectation| expectation.matches_name_but_not_args(sym, args)} end - def find_matching_method_stub(sym) - @stubs.find {|stub| stub.matches(sym, [])} + def find_matching_method_stub(sym, *args) + @stubs.find {|stub| stub.matches(sym, args)} end end diff --git a/vendor/plugins/rspec/lib/spec/mocks/space.rb b/vendor/plugins/rspec/lib/spec/mocks/space.rb index e04bc5ccb..3e13224c7 100644 --- a/vendor/plugins/rspec/lib/spec/mocks/space.rb +++ b/vendor/plugins/rspec/lib/spec/mocks/space.rb @@ -2,7 +2,7 @@ module Spec module Mocks class Space def add(obj) - mocks << obj unless mocks.include?(obj) + mocks << obj unless mocks.detect {|m| m.equal? obj} end def verify_all diff --git a/vendor/plugins/rspec/lib/spec/mocks/spec_methods.rb b/vendor/plugins/rspec/lib/spec/mocks/spec_methods.rb index fd67fd210..d92a4cedd 100644 --- a/vendor/plugins/rspec/lib/spec/mocks/spec_methods.rb +++ b/vendor/plugins/rspec/lib/spec/mocks/spec_methods.rb @@ -1,30 +1,38 @@ module Spec module Mocks - module SpecMethods + module ExampleMethods include Spec::Mocks::ArgumentConstraintMatchers # Shortcut for creating an instance of Spec::Mocks::Mock. - def mock(name, options={}) - Spec::Mocks::Mock.new(name, options) - end - - # Shortcut for creating an instance of Spec::Mocks::Mock with - # predefined method stubs. + # + # +name+ is used for failure reporting, so you should use the + # role that the mock is playing in the example. + # + # +stubs_and_options+ lets you assign options and stub values + # at the same time. The only option available is :null_object. + # Anything else is treated as a stub value. # # == Examples # - # stub_thing = stub("thing", :a => "A") + # stub_thing = mock("thing", :a => "A") # stub_thing.a == "A" => true # # stub_person = stub("thing", :name => "Joe", :email => "joe@domain.com") # stub_person.name => "Joe" # stub_person.email => "joe@domain.com" - def stub(name, stubs={}) - object_stub = mock(name) - stubs.each { |key, value| object_stub.stub!(key).and_return(value) } - object_stub + def mock(name, stubs_and_options={}) + Spec::Mocks::Mock.new(name, stubs_and_options) end + alias :stub :mock + + # Shortcut for creating a mock object that will return itself in response + # to any message it receives that it hasn't been explicitly instructed + # to respond to. + def stub_everything(name = 'stub') + mock(name, :null_object => true) + end + end end end |