Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: 6732d62719
Fetching contributors…

Cannot retrieve contributors at this time

191 lines (167 sloc) 5.442 kB
module RSpec
module Mocks
# @private
class MethodDouble < Hash
# @private
attr_reader :method_name
# @private
def initialize(object, method_name, proxy)
@method_name = method_name
@object = object
@proxy = proxy
@stashed = false
store(:expectations, [])
store(:stubs, [])
end
# @private
def expectations
self[:expectations]
end
# @private
def stubs
self[:stubs]
end
# @private
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
# @private
def object_singleton_class
class << @object; self; end
end
# @private
def obfuscate(method_name)
"obfuscated_by_rspec_mocks__#{method_name}"
end
# @private
def stashed_method_name
obfuscate(method_name)
end
# @private
def object_responds_to?(method_name)
if @proxy.already_proxied_respond_to?
@object.__send__(obfuscate(:respond_to?), method_name)
elsif method_name == :respond_to?
@proxy.already_proxied_respond_to
else
@object.respond_to?(method_name, true)
end
end
# @private
def configure_method
RSpec::Mocks::space.add(@object) if RSpec::Mocks::space
warn_if_nil_class
unless @stashed
stash_original_method
define_proxy_method
end
end
# @private
def stash_original_method
stashed = stashed_method_name
orig = @method_name
object_singleton_class.class_eval do
alias_method(stashed, orig) if method_defined?(orig) || private_method_defined?(orig)
end
@stashed = true
end
# @private
def define_proxy_method
method_name = @method_name
visibility_for_method = "#{visibility} :#{method_name}"
object_singleton_class.class_eval(<<-EOF, __FILE__, __LINE__)
def #{method_name}(*args, &block)
__mock_proxy.message_received :#{method_name}, *args, &block
end
#{visibility_for_method}
EOF
end
# @private
def restore_original_method
if @stashed
method_name = @method_name
stashed_method_name = self.stashed_method_name
object_singleton_class.instance_eval do
remove_method method_name
if method_defined?(stashed_method_name) || private_method_defined?(stashed_method_name)
alias_method method_name, stashed_method_name
remove_method stashed_method_name
end
end
@stashed = false
end
end
# @private
def verify
expectations.each {|e| e.verify_messages_received}
end
# @private
def reset
reset_nil_expectations_warning
restore_original_method
clear
end
# @private
def clear
expectations.clear
stubs.clear
end
# @private
def add_expectation(error_generator, expectation_ordering, expected_from, opts, &implementation)
configure_method
expectation = if existing_stub = stubs.first
existing_stub.build_child(expected_from, 1, opts, &implementation)
else
MessageExpectation.new(error_generator, expectation_ordering, expected_from, @method_name, 1, opts, &implementation)
end
expectations << expectation
expectation
end
# @private
def add_negative_expectation(error_generator, expectation_ordering, expected_from, &implementation)
configure_method
expectation = NegativeMessageExpectation.new(error_generator, expectation_ordering, expected_from, @method_name, &implementation)
expectations.unshift expectation
expectation
end
# @private
def add_stub(error_generator, expectation_ordering, expected_from, opts={}, &implementation)
configure_method
stub = MessageExpectation.new(error_generator, expectation_ordering, expected_from, @method_name, :any, opts, &implementation)
stubs.unshift stub
stub
end
# @private
def remove_stub
raise_method_not_stubbed_error if stubs.empty?
expectations.empty? ? reset : stubs.clear
end
# @private
def proxy_for_nil_class?
@object.nil?
end
# @private
def warn_if_nil_class
if proxy_for_nil_class? & RSpec::Mocks::Proxy.warn_about_expectations_on_nil
Kernel.warn("An expectation of :#{@method_name} was set on nil. Called from #{caller[4]}. Use allow_message_expectations_on_nil to disable warnings.")
end
end
# @private
def raise_method_not_stubbed_error
raise MockExpectationError, "The method `#{method_name}` was not stubbed or was already unstubbed"
end
# @private
def reset_nil_expectations_warning
RSpec::Mocks::Proxy.warn_about_expectations_on_nil = true if proxy_for_nil_class?
end
end
end
end
Jump to Line
Something went wrong with that request. Please try again.