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 146 147 148 149 150 151 152 153 154 155
|
module RR
# RR::Double is the use case for a method call.
# It has the ArgumentEqualityExpectation, TimesCalledExpectation,
# and the implementation.
class Double
extend(Module.new do
def formatted_name(method_name, args)
formatted_errors = args.collect {|arg| arg.inspect}.join(', ')
"#{method_name}(#{formatted_errors})"
end
def list_message_part(doubles)
doubles.collect do |double|
"- #{formatted_name(double.method_name, double.expected_arguments)}"
end.join("\n")
end
end)
attr_reader :times_called, :double_injection, :definition, :times_called_expectation
include Space::Reader
def initialize(double_injection, definition)
@double_injection = double_injection
@definition = definition
@times_called = 0
@times_called_expectation = Expectations::TimesCalledExpectation.new(self)
definition.double = self
verify_method_signature if definition.verify_method_signature?
double_injection.register_double self
end
# Double#exact_match? returns true when the passed in arguments
# exactly match the ArgumentEqualityExpectation arguments.
def exact_match?(*arguments)
definition.exact_match?(*arguments)
end
# Double#wildcard_match? returns true when the passed in arguments
# wildcard match the ArgumentEqualityExpectation arguments.
def wildcard_match?(*arguments)
definition.wildcard_match?(*arguments)
end
# Double#attempt? returns true when the
# TimesCalledExpectation is satisfied.
def attempt?
verify_times_matcher_is_set
times_called_expectation.attempt?
end
# Double#verify verifies the the TimesCalledExpectation
# is satisfied for this double. A TimesCalledError
# is raised if the TimesCalledExpectation is not met.
def verify
verify_times_matcher_is_set
times_called_expectation.verify!
true
end
def terminal?
verify_times_matcher_is_set
times_called_expectation.terminal?
end
# The method name that this Double is attatched to
def method_name
double_injection.method_name
end
# The Arguments that this Double expects
def expected_arguments
verify_argument_expectation_is_set
argument_expectation.expected_arguments
end
# The TimesCalledMatcher for the TimesCalledExpectation
def times_matcher
definition.times_matcher
end
def formatted_name
self.class.formatted_name(method_name, expected_arguments)
end
def method_call(args)
if verbose?
puts Double.formatted_name(method_name, args)
end
times_called_expectation.attempt if definition.times_matcher
space.verify_ordered_double(self) if ordered?
end
def implementation_is_original_method?
definition.implementation_is_original_method?
end
protected
def ordered?
definition.ordered?
end
def verbose?
definition.verbose?
end
def verify_times_matcher_is_set
unless definition.times_matcher
raise RR::Errors.build_error(:DoubleDefinitionError, "#definition.times_matcher is not set")
end
end
def verify_argument_expectation_is_set
unless definition.argument_expectation
raise RR::Errors.build_error(:DoubleDefinitionError, "#definition.argument_expectation is not set")
end
end
def verify_method_signature
unless double_injection.subject_has_original_method?
raise RR::Errors.build_error(:SubjectDoesNotImplementMethodError)
end
raise RR::Errors.build_error(:SubjectHasDifferentArityError) unless arity_matches?
end
def subject_arity
double_injection.original_method.arity
end
def subject_accepts_only_varargs?
subject_arity == -1
end
def subject_accepts_varargs?
subject_arity < 0
end
def arity_matches?
return true if subject_accepts_only_varargs?
if subject_accepts_varargs?
return ((subject_arity * -1) - 1) <= args.size
else
return subject_arity == args.size
end
end
def args
definition.argument_expectation.expected_arguments
end
def argument_expectation
definition.argument_expectation
end
end
end
|