/usr/lib/ruby/vendor_ruby/rspec/mocks/any_instance/proxy.rb is in ruby-rspec-mocks 3.5.0c3e0m0s0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | module RSpec
module Mocks
module AnyInstance
# @private
# The `AnyInstance::Recorder` is responsible for redefining the klass's
# instance method in order to add any stubs/expectations the first time
# the method is called. It's not capable of updating a stub on an instance
# that's already been previously stubbed (either directly, or via
# `any_instance`).
#
# This proxy sits in front of the recorder and delegates both to it
# and to the `RSpec::Mocks::Proxy` for each already mocked or stubbed
# instance of the class, in order to propogates changes to the instances.
#
# Note that unlike `RSpec::Mocks::Proxy`, this proxy class is stateless
# and is not persisted in `RSpec::Mocks.space`.
#
# Proxying for the message expectation fluent interface (typically chained
# off of the return value of one of these methods) is provided by the
# `FluentInterfaceProxy` class below.
class Proxy
def initialize(recorder, target_proxies)
@recorder = recorder
@target_proxies = target_proxies
end
def klass
@recorder.klass
end
def stub(method_name_or_method_map, &block)
if Hash === method_name_or_method_map
method_name_or_method_map.each do |method_name, return_value|
stub(method_name).and_return(return_value)
end
else
perform_proxying(__method__, [method_name_or_method_map], block) do |proxy|
proxy.add_stub(method_name_or_method_map, &block)
end
end
end
def unstub(method_name)
perform_proxying(__method__, [method_name], nil) do |proxy|
proxy.remove_stub_if_present(method_name)
end
end
def stub_chain(*chain, &block)
perform_proxying(__method__, chain, block) do |proxy|
Mocks::StubChain.stub_chain_on(proxy.object, *chain, &block)
end
end
def expect_chain(*chain, &block)
perform_proxying(__method__, chain, block) do |proxy|
Mocks::ExpectChain.expect_chain_on(proxy.object, *chain, &block)
end
end
def should_receive(method_name, &block)
perform_proxying(__method__, [method_name], block) do |proxy|
# Yeah, this is a bit odd...but if we used `add_message_expectation`
# then it would act like `expect_every_instance_of(klass).to receive`.
# The any_instance recorder takes care of validating that an instance
# received the message.
proxy.add_stub(method_name, &block)
end
end
def should_not_receive(method_name, &block)
perform_proxying(__method__, [method_name], block) do |proxy|
proxy.add_message_expectation(method_name, &block).never
end
end
private
def perform_proxying(method_name, args, block, &target_proxy_block)
recorder_value = @recorder.__send__(method_name, *args, &block)
proxy_values = @target_proxies.map(&target_proxy_block)
FluentInterfaceProxy.new([recorder_value] + proxy_values)
end
end
# @private
# Delegates messages to each of the given targets in order to
# provide the fluent interface that is available off of message
# expectations when dealing with `any_instance`.
#
# `targets` will typically contain 1 of the `AnyInstance::Recorder`
# return values and N `MessageExpectation` instances (one per instance
# of the `any_instance` klass).
class FluentInterfaceProxy
def initialize(targets)
@targets = targets
end
if RUBY_VERSION.to_f > 1.8
def respond_to_missing?(method_name, include_private=false)
super || @targets.first.respond_to?(method_name, include_private)
end
else
def respond_to?(method_name, include_private=false)
super || @targets.first.respond_to?(method_name, include_private)
end
end
def method_missing(*args, &block)
return_values = @targets.map { |t| t.__send__(*args, &block) }
FluentInterfaceProxy.new(return_values)
end
end
end
end
end
|