# File lib/spec/mocks/proxy.rb, line 10
10: def self.allow_message_expectations_on_nil
11: @@warn_about_expectations_on_nil = false
12:
13: # ensure nil.rspec_verify is called even if an expectation is not set in the example
14: # otherwise the allowance would effect subsequent examples
15: $rspec_mocks.add(nil) unless $rspec_mocks.nil?
16: end
# File lib/spec/mocks/proxy.rb, line 18
18: def initialize(target, name=nil, options={})
19: @target = target
20: @name = name
21: @error_generator = ErrorGenerator.new target, name, options
22: @expectation_ordering = OrderGroup.new @error_generator
23: @expectations = []
24: @messages_received = []
25: @stubs = []
26: @proxied_methods = []
27: @options = options ? DEFAULT_OPTIONS.dup.merge(options) : DEFAULT_OPTIONS
28: @already_proxied_respond_to = false
29: end
# File lib/spec/mocks/proxy.rb, line 40
40: def add_message_expectation(expected_from, sym, opts={}, &block)
41: __add sym
42: warn_if_nil_class sym
43: @expectations << build_expectation(expected_from, sym, opts, &block)
44: @expectations.last
45: end
# File lib/spec/mocks/proxy.rb, line 55
55: def add_negative_message_expectation(expected_from, sym, &block)
56: __add sym
57: warn_if_nil_class sym
58: @expectations << NegativeMessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil)
59: @expectations.last
60: end
# File lib/spec/mocks/proxy.rb, line 62
62: def add_stub(expected_from, sym, opts={}, &implementation)
63: __add sym
64: @stubs.unshift MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, nil, :any, opts, &implementation)
65: @stubs.first
66: end
# File lib/spec/mocks/proxy.rb, line 35
35: def as_null_object
36: @options[:null_object] = true
37: @target
38: end
# File lib/spec/mocks/proxy.rb, line 47
47: def build_expectation(expected_from, sym, opts, &block)
48: if stub = find_matching_method_stub(sym)
49: stub.build_child(expected_from, block_given?? block : nil, 1, opts)
50: else
51: MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil, 1, opts)
52: end
53: end
# File lib/spec/mocks/proxy.rb, line 149
149: def find_matching_method_stub(sym, *args)
150: @stubs.find {|stub| stub.matches(sym, args)}
151: end
# File lib/spec/mocks/proxy.rb, line 96
96: def has_negative_expectation?(sym)
97: @expectations.any? {|expectation| expectation.negative_expectation_for?(sym)}
98: end
# File lib/spec/mocks/proxy.rb, line 126
126: def invoke_expectation(expectation, *args, &block)
127: expectation.invoke(*args, &block)
128: end
# File lib/spec/mocks/proxy.rb, line 104
104: def message_received(sym, *args, &block)
105: expectation = find_matching_expectation(sym, *args)
106: stub = find_matching_method_stub(sym, *args)
107:
108: if ok_to_invoke_stub?(stub, expectation)
109: record_stub(stub, sym, args, &block)
110: elsif expectation
111: invoke_expectation(expectation, *args, &block)
112: elsif expectation = find_almost_matching_expectation(sym, *args)
113: record_almost_matching_expectation(expectation, sym, *args, &block)
114: else
115: @target.__send__ :method_missing, sym, *args, &block
116: end
117: end
# File lib/spec/mocks/proxy.rb, line 31
31: def null_object?
32: @options[:null_object]
33: end
# File lib/spec/mocks/proxy.rb, line 137
137: def ok_to_invoke_stub?(stub, expectation)
138: stub && (!expectation || expectation.called_max_times?)
139: end
# File lib/spec/mocks/proxy.rb, line 141
141: def raise_unexpected_message_args_error(expectation, *args)
142: @error_generator.raise_unexpected_message_args_error expectation, *args
143: end
# File lib/spec/mocks/proxy.rb, line 145
145: def raise_unexpected_message_error(sym, *args)
146: @error_generator.raise_unexpected_message_error sym, *args
147: end
# File lib/spec/mocks/proxy.rb, line 92
92: def received_message?(sym, *args, &block)
93: @messages_received.any? {|array| array == [sym, args, block]}
94: end
# File lib/spec/mocks/proxy.rb, line 130
130: def record_almost_matching_expectation(expectation, sym, *args, &block)
131: expectation.advise(args, block)
132: unless (null_object? or has_negative_expectation?(sym))
133: raise_unexpected_message_args_error(expectation, *args)
134: end
135: end
# File lib/spec/mocks/proxy.rb, line 100
100: def record_message_received(sym, args, block)
101: @messages_received << [sym, args, block]
102: end
# File lib/spec/mocks/proxy.rb, line 119
119: def record_stub(stub, sym, args, &block)
120: almost_matching_expectation(sym, *args) do |e|
121: e.advise(args, block)
122: end
123: stub.invoke(*args, &block)
124: end
# File lib/spec/mocks/proxy.rb, line 68
68: def remove_stub(message)
69: message = message.to_sym
70: if stub_to_remove = @stubs.detect { |s| s.matches_name?(message) }
71: reset_proxied_method(message)
72: @stubs.delete(stub_to_remove)
73: else
74: raise MockExpectationError, "The method `#{message}` was not stubbed or was already unstubbed"
75: end
76: end
# File lib/spec/mocks/proxy.rb, line 155
155: def __add(sym)
156: $rspec_mocks.add(@target) unless $rspec_mocks.nil?
157: define_expected_method(sym)
158: end
# File lib/spec/mocks/proxy.rb, line 255
255: def almost_matching_expectation(sym, *args, &block)
256: if e = find_almost_matching_expectation(sym, *args)
257: yield e
258: end
259: end
# File lib/spec/mocks/proxy.rb, line 207
207: def clear_expectations
208: @expectations.clear
209: end
# File lib/spec/mocks/proxy.rb, line 215
215: def clear_proxied_methods
216: @proxied_methods.clear
217: end
# File lib/spec/mocks/proxy.rb, line 211
211: def clear_stubs
212: @stubs.clear
213: end
# File lib/spec/mocks/proxy.rb, line 166
166: def define_expected_method(sym)
167: unless @proxied_methods.include?(sym)
168: visibility_string = "#{visibility(sym)} :#{sym}"
169: if target_responds_to?(sym)
170: munged_sym = munge(sym)
171: target_metaclass.instance_eval do
172: alias_method munged_sym, sym if method_defined?(sym)
173: end
174: @proxied_methods << sym
175: end
176: target_metaclass.class_eval( def #{sym}(*args, &block) __mock_proxy.message_received :#{sym}, *args, &block end #{visibility_string}, __FILE__, __LINE__)
177: end
178: end
# File lib/spec/mocks/proxy.rb, line 261
261: def find_almost_matching_expectation(sym, *args)
262: @expectations.find {|expectation| expectation.matches_name_but_not_args(sym, args)}
263: end
# File lib/spec/mocks/proxy.rb, line 250
250: def find_matching_expectation(sym, *args)
251: @expectations.find {|expectation| expectation.matches(sym, args) && !expectation.called_max_times?} ||
252: @expectations.find {|expectation| expectation.matches(sym, args)}
253: end
# File lib/spec/mocks/proxy.rb, line 203
203: def munge(sym)
204: "proxied_by_rspec__#{sym}"
205: end
# File lib/spec/mocks/proxy.rb, line 242
242: def proxy_for_nil_class?
243: @target.nil?
244: end
# File lib/spec/mocks/proxy.rb, line 246
246: def reset_nil_expectations_warning
247: @@warn_about_expectations_on_nil = true if proxy_for_nil_class?
248: end
# File lib/spec/mocks/proxy.rb, line 231
231: def reset_proxied_method(sym)
232: munged_sym = munge(sym)
233: target_metaclass.instance_eval do
234: remove_method sym
235: if method_defined?(munged_sym)
236: alias_method sym, munged_sym
237: remove_method munged_sym
238: end
239: end
240: end
# File lib/spec/mocks/proxy.rb, line 227
227: def reset_proxied_methods
228: @proxied_methods.map {|sym| reset_proxied_method(sym)}
229: end
# File lib/spec/mocks/proxy.rb, line 219
219: def target_metaclass
220: class << @target; self; end
221: end
# File lib/spec/mocks/proxy.rb, line 185
185: def target_responds_to?(sym)
186: return @target.__send__(munge(:respond_to?),sym) if @already_proxied_respond_to
187: return @already_proxied_respond_to = true if sym == :respond_to?
188: return @target.respond_to?(sym, true)
189: end
# File lib/spec/mocks/proxy.rb, line 223
223: def verify_expectations
224: @expectations.map {|e| e.verify_messages_received}
225: end
# File lib/spec/mocks/proxy.rb, line 191
191: def visibility(sym)
192: if Mock === @target
193: 'public'
194: elsif target_metaclass.private_method_defined?(sym)
195: 'private'
196: elsif target_metaclass.protected_method_defined?(sym)
197: 'protected'
198: else
199: 'public'
200: end
201: end
# File lib/spec/mocks/proxy.rb, line 160
160: def warn_if_nil_class(sym)
161: if proxy_for_nil_class? & @@warn_about_expectations_on_nil
162: Kernel.warn("An expectation of :#{sym} was set on nil. Called from #{caller[2]}. Use allow_message_expectations_on_nil to disable warnings.")
163: end
164: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.