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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
#!/usr/bin/env ruby
#---
# Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#+++
require 'flexmock/noop'
require 'flexmock/mock_container'
class FlexMock
class << self
attr_reader :framework_adapter
# Class method to make sure that verify is called at the end of a
# test. One mock object will be created for each name given to
# the use method. The mocks will be passed to the block as
# arguments. If no names are given, then a single anonymous mock
# object will be created.
#
# At the end of the use block, each mock object will be verified
# to make sure the proper number of calls have been made.
#
# Usage:
#
# FlexMock.use("name") do |mock| # Creates a mock named "name"
# mock.should_receive(:meth).
# returns(0).once
# end # mock is verified here
#
# NOTE: If you include FlexMock::TestCase into your test case
# file, you can create mocks that will be automatically verified in
# the test teardown by using the +flexmock+ method.
#
def use(*names)
names = ["unknown"] if names.empty?
container = UseContainer.new
mocks = names.collect { |n| container.flexmock(n) }
yield(*mocks)
rescue Exception => _
container.got_exception = true
raise
ensure
container.flexmock_teardown
end
FORBID_MOCKING = :__flexmock_forbid_mocking
# Forbid mock calls to happen while the block is being evaluated
#
# @param [Object] mocking_forbidden_return the return value that should be
# used if a mocking call has happened. If no mocking calls happened,
# returns the return value of the block
def forbid_mocking(mocking_forbidden_return = nil)
current, Thread.current[FORBID_MOCKING] =
Thread.current[FORBID_MOCKING], true
catch(FORBID_MOCKING) do
return yield
end
mocking_forbidden_return
ensure
Thread.current[FORBID_MOCKING] = current
end
# Verify that mocking is allowed in the current context. Throws if it is
# not.
def verify_mocking_allowed!
if Thread.current[FORBID_MOCKING]
throw FORBID_MOCKING
end
end
# Class method to format a method name and argument list as a nice
# looking string.
def format_call(sym, args, kw) # :nodoc:
"#{sym}(#{format_args(args, kw)})"
end
# Class method to format a list of args (the part between the
# parenthesis).
def format_args(args, kw)
args =
if args
args = args.map do |a|
FlexMock.forbid_mocking("<recursive call to mocked method in #inspect>") do
a.inspect
end
end
args.join(', ')
else
"*args"
end
kw =
if kw.kind_of? HashMatcher
kw.inspect
elsif kw && !kw.empty?
kw = kw.transform_values do |v|
FlexMock.forbid_mocking("<recursive call to mocked method in #inspect>") do
v.inspect
end
end
kw.map { |k, v| "#{k}: #{v}" }.join(', ')
elsif kw.nil?
# Don't append **kwargs to signature if ruby version < 3
# in order to not break existing code still on ruby2
"**kwargs" unless RUBY_VERSION < "3"
end
[(args unless args.empty?), kw].compact.join(", ")
end
# Check will assert the block returns true. If it doesn't, an
# assertion failure is triggered with the given message.
def check(msg, &block) # :nodoc:
if FlexMock.framework_adapter.respond_to?(:check)
FlexMock.framework_adapter.check(msg, &block)
else
FlexMock.framework_adapter.make_assertion(msg, &block)
end
end
end
# Container object to be used by the FlexMock.use method.
class UseContainer
include MockContainer
attr_accessor :got_exception
def initialize
@got_exception = false
end
def passed?
! got_exception
end
end
end
|