class RSpec::Mocks::MethodDouble
@private
Constants
- IGNORED_BACKTRACE_LINE
@private
Attributes
method_name[R]
@private
object[R]
@private
Public Class Methods
new(object, method_name, proxy)
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 9 def initialize(object, method_name, proxy) @method_name = method_name @object = object @proxy = proxy @method_stasher = InstanceMethodStasher.new(object_singleton_class, @method_name) @method_is_proxied = false store(:expectations, []) store(:stubs, []) end
Public Instance Methods
add_default_stub(*args, &implementation)
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 245 def add_default_stub(*args, &implementation) return if stubs.any? add_stub(*args, &implementation) end
add_expectation(error_generator, expectation_ordering, expected_from, opts, &implementation)
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 221 def add_expectation(error_generator, expectation_ordering, expected_from, opts, &implementation) configure_method expectation = MessageExpectation.new(error_generator, expectation_ordering, expected_from, self, 1, opts, &implementation) expectations << expectation expectation end
add_stub(error_generator, expectation_ordering, expected_from, opts={}, &implementation)
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 236 def add_stub(error_generator, expectation_ordering, expected_from, opts={}, &implementation) configure_method stub = MessageExpectation.new(error_generator, expectation_ordering, expected_from, self, :any, opts, &implementation) stubs.unshift stub stub end
any_instance_class_recorder_observing_method?(klass)
click to toggle source
# File lib/rspec/mocks/method_double.rb, line 83 def any_instance_class_recorder_observing_method?(klass) return true if ::RSpec::Mocks.any_instance_recorder_for(klass).already_observing?(@method_name) superklass = klass.superclass return false if superklass.nil? any_instance_class_recorder_observing_method?(superklass) end
build_expectation(error_generator, expectation_ordering)
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 230 def build_expectation(error_generator, expectation_ordering) expected_from = IGNORED_BACKTRACE_LINE MessageExpectation.new(error_generator, expectation_ordering, expected_from, self) end
clear()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 215 def clear expectations.clear stubs.clear end
configure_method()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 162 def configure_method @original_visibility = visibility_for_method @method_stasher.stash unless @method_is_proxied define_proxy_method end
define_proxy_method()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 169 def define_proxy_method return if @method_is_proxied object_singleton_class.class_eval <<-EOF, __FILE__, __LINE__ + 1 def #{@method_name}(*args, &block) ::RSpec::Mocks.proxy_for(self).message_received :#{@method_name}, *args, &block end #{visibility_for_method} EOF @method_is_proxied = true end
expectations()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 21 def expectations self[:expectations] end
object_singleton_class()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 157 def object_singleton_class class << @object; self; end end
original_method()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 52 def original_method if @method_stasher.method_is_stashed? # Example: a singleton method defined on @object ::RSpec::Mocks.method_handle_for(@object, @method_stasher.stashed_method_name) elsif meth = original_unrecorded_any_instance_method # Example: a method that has been mocked through # klass.any_instance.should_receive(:msg).and_call_original # any_instance.should_receive(:msg) causes the method to be # replaced with a proxy method, and then `and_call_original` # is recorded and played back on the object instance. We need # special handling here to get a handle on the original method # object rather than the proxy method. meth else # Example: an instance method defined on one of @object's ancestors. original_method_from_ancestry end rescue NameError # We have no way of knowing if the object's method_missing # will handle this message or not...but we can at least try. # If it's not handled, a `NoMethodError` will be raised, just # like normally. ProcWithBlock.new(@object,@method_name) end
original_method_from_ancestor(ancestors)
click to toggle source
# File lib/rspec/mocks/method_double.rb, line 118 def original_method_from_ancestor(ancestors) klass, *rest = ancestors klass.instance_method(@method_name).bind(@object) rescue NameError raise if rest.empty? original_method_from_ancestor(rest) end
original_method_from_ancestry()
click to toggle source
In Ruby 2.1, ancestors include the correct ancestors, including the singleton classes
# File lib/rspec/mocks/method_double.rb, line 93 def original_method_from_ancestry # Lookup in the ancestry, skipping over the singleton class itself original_method_from_ancestor(object_singleton_class.ancestors.drop(1)) end
original_method_from_superclass()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 128 def original_method_from_superclass @object.superclass. singleton_class. instance_method(@method_name). bind(@object) end
original_unrecorded_any_instance_method()
click to toggle source
# File lib/rspec/mocks/method_double.rb, line 77 def original_unrecorded_any_instance_method return nil unless any_instance_class_recorder_observing_method?(@object.class) alias_name = ::RSpec::Mocks.any_instance_recorder_for(@object.class).build_alias_method_name(@method_name) @object.method(alias_name) end
raise_method_not_stubbed_error()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 263 def raise_method_not_stubbed_error raise MockExpectationError, "The method `#{method_name}` was not stubbed or was already unstubbed" end
remove_single_stub(stub)
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 257 def remove_single_stub(stub) stubs.delete(stub) restore_original_method if stubs.empty? && expectations.empty? end
remove_stub()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 251 def remove_stub raise_method_not_stubbed_error if stubs.empty? expectations.empty? ? reset : stubs.clear end
reset()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 209 def reset restore_original_method clear end
restore_original_method()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 187 def restore_original_method return unless @method_is_proxied object_singleton_class.__send__(:remove_method, @method_name) @method_stasher.restore restore_original_visibility @method_is_proxied = false end
restore_original_visibility()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 198 def restore_original_visibility return unless object_singleton_class.method_defined?(@method_name) || object_singleton_class.private_method_defined?(@method_name) object_singleton_class.class_eval(@original_visibility, __FILE__, __LINE__) end
stubs()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 26 def stubs self[:stubs] end
verify()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 204 def verify expectations.each {|e| e.verify_messages_received} end
visibility()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 31 def visibility if TestDouble === @object 'public' elsif object_singleton_class.private_method_defined?(@method_name) 'private' elsif object_singleton_class.protected_method_defined?(@method_name) 'protected' else 'public' end end
visibility_for_method()
click to toggle source
@private
# File lib/rspec/mocks/method_double.rb, line 182 def visibility_for_method "#{visibility} :#{method_name}" end