-
-
Notifications
You must be signed in to change notification settings - Fork 359
/
chain.rb
77 lines (68 loc) · 1.9 KB
/
chain.rb
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
module RSpec
module Mocks
module AnyInstance
class Chain
class << self
private
# @macro [attach] record
# @method $1(*args, &block)
# Records the `$1` message for playback against an instance that
# invokes a method stubbed or mocked using `any_instance`.
#
# @see RSpec::Mocks::MessageExpectation#$1
#
def record(method_name)
class_eval(<<-EOM, __FILE__, __LINE__ + 1)
def #{method_name}(*args, &block)
record(:#{method_name}, *args, &block)
end
EOM
end
end
record :and_return
record :and_raise
record :and_throw
record :and_yield
record :with
record :once
record :twice
record :any_number_of_times
record :exactly
record :times
record :never
record :at_least
record :at_most
# @private
def playback!(instance)
messages.inject(instance) do |_instance, message|
_instance.__send__(*message.first, &message.last)
end
end
# @private
def constrained_to_any_of?(*constraints)
constraints.any? do |constraint|
messages.any? do |message|
message.first.first == constraint
end
end
end
# @private
def expectation_fulfilled!
@expectation_fulfilled = true
end
private
def messages
@messages ||= []
end
def last_message
messages.last.first.first unless messages.empty?
end
def record(rspec_method_name, *args, &block)
verify_invocation_order(rspec_method_name, *args, &block)
messages << [args.unshift(rspec_method_name), block]
self
end
end
end
end
end