class Facon::Proxy

A proxy for mock objects. Stubs and expectations are set on this proxy.

Public Class Methods

new(target, name) click to toggle source
# File lib/facon/proxy.rb, line 9
def initialize(target, name)
  @target, @name = target, name
  @expectations = []
  @stubs = []
  @proxied_methods = []
  @error_generator = ErrorGenerator.new(target, name)
  @expectation_ordering = nil unless defined?(@expectation_ordering)
end

Public Instance Methods

add_expectation(expected_from, method, &block) click to toggle source
# File lib/facon/proxy.rb, line 26
def add_expectation(expected_from, method, &block)
  add_method(method)

  @expectations << Expectation.new(@error_generator, @expectation_ordering, expected_from, method, (block_given? ? block : nil), 1)
  @expectations.last
end
add_negative_expectation(expected_from, method, &block) click to toggle source
# File lib/facon/proxy.rb, line 33
def add_negative_expectation(expected_from, method, &block)
  add_method(method)

  @expectations << NegativeExpectation.new(@error_generator, @expectation_ordering, expected_from, method, (block_given? ? block : nil))
  @expectations.last
end
add_stub(expected_from, method) click to toggle source
# File lib/facon/proxy.rb, line 18
def add_stub(expected_from, method)
  add_method(method)

  # A stub is really an expectation that can be called any number of times.
  @stubs.unshift(Expectation.new(@error_generator, @expectation_ordering, expected_from, method, nil, :any))
  @stubs.first
end
message_received(method, *args, &block) click to toggle source
# File lib/facon/proxy.rb, line 40
def message_received(method, *args, &block)
  if expectation = find_matching_expectation(method, *args)
    expectation.invoke(args, block)
  elsif stub = find_matching_method_stub(method, *args)
    stub.invoke([], block)
  elsif expectation = find_almost_matching_expectation(method, *args)
    raise_unexpected_message_args_error(expectation, *args) unless has_negative_expectation?(method)
  else
    @target.send(:method_missing, method, *args, &block)
  end
end
reset() click to toggle source
# File lib/facon/proxy.rb, line 58
def reset
  @expectations.clear
  @stubs.clear
  reset_proxied_methods
  @proxied_methods.clear
end
verify() click to toggle source
# File lib/facon/proxy.rb, line 52
def verify
  @expectations.each { |expectation| expectation.met? }
ensure
  reset
end

Private Instance Methods

add_method(method) click to toggle source
# File lib/facon/proxy.rb, line 66
def add_method(method)
  $facon_mocks << @target unless $facon_mocks.nil? || $facon_mocks.detect { |m| m.equal?(@target) }
  define_expected_method(method)
end
define_expected_method(method) click to toggle source

Defines an expected method that simply calls the message_received method.

# File lib/facon/proxy.rb, line 73
      def define_expected_method(method)
        if @target.respond_to?(method) && !metaclass.method_defined?(munge(method))
          munged_method = munge(method)
          metaclass.instance_eval do
            alias_method munged_method, method if method_defined?(method.to_s)
          end
          @proxied_methods << method
        end

        metaclass_eval(<<-EOF, __FILE__, __LINE__)
          def #{method}(*args, &block)
            mock_proxy.message_received(:#{method}, *args, &block)
          end
        EOF
      end
find_almost_matching_expectation(method, *args) click to toggle source
# File lib/facon/proxy.rb, line 119
def find_almost_matching_expectation(method, *args)
  @expectations.find { |expectation| expectation.matches_name_but_not_args(method, args) }
end
find_matching_expectation(method, *args) click to toggle source
# File lib/facon/proxy.rb, line 115
def find_matching_expectation(method, *args)
  @expectations.find { |expectation| expectation.matches(method, args) }
end
find_matching_method_stub(method, *args) click to toggle source
# File lib/facon/proxy.rb, line 123
def find_matching_method_stub(method, *args)
  @stubs.find { |stub| stub.matches(method, args) }
end
has_negative_expectation?(method) click to toggle source
# File lib/facon/proxy.rb, line 127
def has_negative_expectation?(method)
  @expectations.find { |expectation| expectation.negative_expectation_for?(method) }
end
metaclass() click to toggle source
# File lib/facon/proxy.rb, line 107
def metaclass
  (class << @target; self; end)
end
metaclass_eval(str, filename, lineno) click to toggle source
# File lib/facon/proxy.rb, line 111
def metaclass_eval(str, filename, lineno)
  metaclass.class_eval(str, filename, lineno)
end
munge(method) click to toggle source
# File lib/facon/proxy.rb, line 89
def munge(method)
  "proxied_by_facon__#{method.to_s}".to_sym
end
reset_proxied_methods() click to toggle source
# File lib/facon/proxy.rb, line 93
def reset_proxied_methods
  @proxied_methods.each do |method|
    munged_method = munge(method)
    metaclass.instance_eval do
      if method_defined?(munged_method.to_s)
        alias_method method, munged_method
        undef_method munged_method
      else
        undef_method method
      end
    end
  end
end