class RSpec::Mocks::AnyInstance::Proxy

@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.

Public Class Methods

new(recorder, target_proxies) click to toggle source
# File lib/rspec/mocks/any_instance/proxy.rb, line 22
def initialize(recorder, target_proxies)
  @recorder       = recorder
  @target_proxies = target_proxies
end

Public Instance Methods

expect_chain(*chain, &block) click to toggle source
# File lib/rspec/mocks/any_instance/proxy.rb, line 55
def expect_chain(*chain, &block)
  perform_proxying(__method__, chain, block) do |proxy|
    Mocks::ExpectChain.expect_chain_on(proxy.object, *chain, &block)
  end
end
klass() click to toggle source
# File lib/rspec/mocks/any_instance/proxy.rb, line 27
def klass
  @recorder.klass
end
should_not_receive(method_name, &block) click to toggle source
# File lib/rspec/mocks/any_instance/proxy.rb, line 71
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
should_receive(method_name, &block) click to toggle source
# File lib/rspec/mocks/any_instance/proxy.rb, line 61
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
stub(method_name_or_method_map, &block) click to toggle source
# File lib/rspec/mocks/any_instance/proxy.rb, line 31
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
stub_chain(*chain, &block) click to toggle source
# File lib/rspec/mocks/any_instance/proxy.rb, line 49
def stub_chain(*chain, &block)
  perform_proxying(__method__, chain, block) do |proxy|
    Mocks::StubChain.stub_chain_on(proxy.object, *chain, &block)
  end
end
unstub(method_name) click to toggle source
# File lib/rspec/mocks/any_instance/proxy.rb, line 43
def unstub(method_name)
  perform_proxying(__method__, [method_name], nil) do |proxy|
    proxy.remove_stub_if_present(method_name)
  end
end

Private Instance Methods

perform_proxying(method_name, args, block, &target_proxy_block) click to toggle source
# File lib/rspec/mocks/any_instance/proxy.rb, line 79
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