module Mock

Public Class Methods

cleanup() click to toggle source
# File lib/mspec/mocks/mock.rb, line 178
def self.cleanup
  objects.each do |key, obj|
    if obj.kind_of? MockIntObject
      clear_replaced key
      next
    end

    replaced = key.first
    sym = key.last
    meta = obj.singleton_class

    if mock_respond_to? obj, replaced, true
      meta.__send__ :alias_method, sym, replaced
      meta.__send__ :remove_method, replaced
    else
      meta.__send__ :remove_method, sym
    end

    clear_replaced key
  end
ensure
  reset
end
clear_replaced(key) click to toggle source
# File lib/mspec/mocks/mock.rb, line 41
def self.clear_replaced(key)
  mocks.delete key
  stubs.delete key
end
has_key?(keys, sym) click to toggle source
# File lib/mspec/mocks/mock.rb, line 33
def self.has_key?(keys, sym)
  !!keys.find { |k| k.first == sym }
end
install_method(obj, sym, type=nil) click to toggle source
# File lib/mspec/mocks/mock.rb, line 55
def self.install_method(obj, sym, type=nil)
  meta = obj.singleton_class

  key = replaced_key obj, sym
  sym = sym.to_sym

  if (sym == :respond_to? or mock_respond_to?(obj, sym, true)) and !replaced?(key.first)
    meta.__send__ :alias_method, key.first, sym
  end

  meta.class_eval <<-END
    def #{sym}(*args, &block)
      Mock.verify_call self, :#{sym}, *args, &block
    end
  END

  proxy = MockProxy.new type

  if proxy.mock?
    MSpec.expectation
    MSpec.actions :expectation, MSpec.current.state
  end

  if proxy.stub?
    stubs[key].unshift proxy
  else
    mocks[key] << proxy
  end
  objects[key] = obj

  proxy
end
mock_respond_to?(obj, sym, include_private = false) click to toggle source
# File lib/mspec/mocks/mock.rb, line 46
def self.mock_respond_to?(obj, sym, include_private = false)
  name = replaced_name(obj, :respond_to?)
  if replaced? name
    obj.__send__ name, sym, include_private
  else
    obj.respond_to? sym, include_private
  end
end
mocks() click to toggle source
# File lib/mspec/mocks/mock.rb, line 17
def self.mocks
  @mocks ||= Hash.new { |h,k| h[k] = [] }
end
name_or_inspect(obj) click to toggle source
# File lib/mspec/mocks/mock.rb, line 88
def self.name_or_inspect(obj)
  obj.instance_variable_get(:@name) || obj.inspect
end
objects() click to toggle source
# File lib/mspec/mocks/mock.rb, line 13
def self.objects
  @objects ||= {}
end
replaced?(sym) click to toggle source
# File lib/mspec/mocks/mock.rb, line 37
def self.replaced?(sym)
  has_key?(mocks.keys, sym) or has_key?(stubs.keys, sym)
end
replaced_key(obj, sym) click to toggle source
# File lib/mspec/mocks/mock.rb, line 29
def self.replaced_key(obj, sym)
  [replaced_name(obj, sym), sym]
end
replaced_name(obj, sym) click to toggle source
# File lib/mspec/mocks/mock.rb, line 25
def self.replaced_name(obj, sym)
  :"__mspec_#{obj.__mspec_object_id__}_#{sym}__"
end
reset() click to toggle source
# File lib/mspec/mocks/mock.rb, line 9
def self.reset
  @mocks = @stubs = @objects = nil
end
stubs() click to toggle source
# File lib/mspec/mocks/mock.rb, line 21
def self.stubs
  @stubs ||= Hash.new { |h,k| h[k] = [] }
end
verify_call(obj, sym, *args, &block) click to toggle source
# File lib/mspec/mocks/mock.rb, line 119
def self.verify_call(obj, sym, *args, &block)
  compare = *args
  behaves_like_ruby_1_9 = *[]
  if (behaves_like_ruby_1_9)
    compare = compare.first if compare.length <= 1
  end

  key = replaced_key obj, sym
  [mocks, stubs].each do |proxies|
    proxies[key].each do |proxy|
      pass = case proxy.arguments
      when :any_args
        true
      when :no_args
        compare.nil?
      else
        proxy.arguments == compare
      end

      if proxy.yielding?
        if block
          proxy.yielding.each do |args_to_yield|
            if block.arity == -1 || block.arity == args_to_yield.size
              block.call(*args_to_yield)
            else
              SpecExpectation.fail_with(
                "Mock '#{name_or_inspect obj}' asked to yield "                    "|#{proxy.yielding.join(', ')}| on #{sym}\n",
                "but a block with arity #{block.arity} was passed")
            end
          end
        else
          SpecExpectation.fail_with(
            "Mock '#{name_or_inspect obj}' asked to yield "                "|[#{proxy.yielding.join('], [')}]| on #{sym}\n",
            "but no block was passed")
        end
      end

      if pass
        proxy.called

        if proxy.raising?
          raise proxy.raising
        else
          return proxy.returning
        end
      end
    end
  end

  if sym.to_sym == :respond_to?
    mock_respond_to? obj, compare
  else
    SpecExpectation.fail_with("Mock '#{name_or_inspect obj}': method #{sym}\n",
                          "called with unexpected arguments (#{Array(compare).join(' ')})")
  end
end
verify_count() click to toggle source
# File lib/mspec/mocks/mock.rb, line 92
def self.verify_count
  mocks.each do |key, proxies|
    obj = objects[key]
    proxies.each do |proxy|
      qualifier, count = proxy.count
      pass = case qualifier
      when :at_least
        proxy.calls >= count
      when :at_most
        proxy.calls <= count
      when :exactly
        proxy.calls == count
      when :any_number_of_times
        true
      else
        false
      end
      unless pass
        SpecExpectation.fail_with(
          "Mock '#{name_or_inspect obj}' expected to receive '#{key.last}' "              "#{qualifier.to_s.sub('_', ' ')} #{count} times",
          "but received it #{proxy.calls} times")
      end
    end
  end
end