rspec-mocks 2.13.1 → 2.14.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Changelog.md +45 -4
- data/README.md +1 -1
- data/features/argument_matchers/README.md +2 -2
- data/features/argument_matchers/explicit.feature +2 -3
- data/features/argument_matchers/general_matchers.feature +2 -2
- data/features/argument_matchers/type_matchers.feature +3 -4
- data/features/message_expectations/README.md +2 -2
- data/features/message_expectations/any_instance.feature +2 -2
- data/features/message_expectations/block_local_expectations.feature.pending +3 -3
- data/features/message_expectations/expect_message_using_expect.feature +103 -0
- data/features/message_expectations/expect_message_using_should_receive.feature +118 -0
- data/features/message_expectations/receive_counts.feature +1 -1
- data/features/method_stubs/README.md +1 -1
- data/features/method_stubs/any_instance.feature +11 -11
- data/features/method_stubs/as_null_object.feature +1 -1
- data/features/method_stubs/stub_implementation.feature +2 -2
- data/features/outside_rspec/configuration.feature +0 -20
- data/features/spies/spy_partial_mock_method.feature +34 -0
- data/features/spies/spy_pure_mock_method.feature +76 -0
- data/features/spies/spy_unstubbed_method.feature +18 -0
- data/features/step_definitions/additional_cli_steps.rb +7 -0
- data/features/test_frameworks/test_unit.feature +43 -0
- data/lib/rspec/mocks.rb +9 -34
- data/lib/rspec/mocks/any_instance/chain.rb +8 -2
- data/lib/rspec/mocks/any_instance/expectation_chain.rb +19 -16
- data/lib/rspec/mocks/any_instance/recorder.rb +6 -3
- data/lib/rspec/mocks/any_instance/stub_chain.rb +11 -11
- data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +8 -10
- data/lib/rspec/mocks/argument_list_matcher.rb +7 -3
- data/lib/rspec/mocks/configuration.rb +28 -1
- data/lib/rspec/mocks/deprecation.rb +18 -0
- data/lib/rspec/mocks/error_generator.rb +60 -8
- data/lib/rspec/mocks/errors.rb +1 -1
- data/lib/rspec/mocks/example_methods.rb +39 -3
- data/lib/rspec/mocks/extensions/marshal.rb +4 -10
- data/lib/rspec/mocks/framework.rb +16 -4
- data/lib/rspec/mocks/instance_method_stasher.rb +3 -0
- data/lib/rspec/mocks/matchers/have_received.rb +93 -0
- data/lib/rspec/mocks/matchers/receive.rb +92 -0
- data/lib/rspec/mocks/message_expectation.rb +66 -129
- data/lib/rspec/mocks/method_double.rb +50 -43
- data/lib/rspec/mocks/mutate_const.rb +8 -20
- data/lib/rspec/mocks/proxy.rb +41 -25
- data/lib/rspec/mocks/proxy_for_nil.rb +36 -0
- data/lib/rspec/mocks/space.rb +64 -11
- data/lib/rspec/mocks/stub_chain.rb +51 -0
- data/lib/rspec/mocks/syntax.rb +329 -0
- data/lib/rspec/mocks/targets.rb +69 -0
- data/lib/rspec/mocks/test_double.rb +25 -4
- data/lib/rspec/mocks/version.rb +1 -1
- data/lib/spec/mocks.rb +1 -3
- data/spec/rspec/mocks/and_call_original_spec.rb +8 -0
- data/spec/rspec/mocks/and_yield_spec.rb +6 -6
- data/spec/rspec/mocks/any_instance_spec.rb +43 -31
- data/spec/rspec/mocks/any_number_of_times_spec.rb +6 -0
- data/spec/rspec/mocks/argument_expectation_spec.rb +12 -14
- data/spec/rspec/mocks/at_least_spec.rb +46 -37
- data/spec/rspec/mocks/at_most_spec.rb +12 -12
- data/spec/rspec/mocks/block_return_value_spec.rb +18 -1
- data/spec/rspec/mocks/bug_report_10260_spec.rb +1 -1
- data/spec/rspec/mocks/bug_report_10263_spec.rb +1 -1
- data/spec/rspec/mocks/bug_report_11545_spec.rb +4 -4
- data/spec/rspec/mocks/bug_report_600_spec.rb +1 -1
- data/spec/rspec/mocks/bug_report_7611_spec.rb +1 -1
- data/spec/rspec/mocks/configuration_spec.rb +124 -0
- data/spec/rspec/mocks/double_spec.rb +13 -1
- data/spec/rspec/mocks/failing_argument_matchers_spec.rb +17 -1
- data/spec/rspec/mocks/hash_excluding_matcher_spec.rb +13 -13
- data/spec/rspec/mocks/matchers/have_received_spec.rb +266 -0
- data/spec/rspec/mocks/matchers/receive_spec.rb +318 -0
- data/spec/rspec/mocks/methods_spec.rb +27 -0
- data/spec/rspec/mocks/mock_ordering_spec.rb +4 -4
- data/spec/rspec/mocks/mock_space_spec.rb +94 -39
- data/spec/rspec/mocks/mock_spec.rb +65 -50
- data/spec/rspec/mocks/multiple_return_value_spec.rb +10 -10
- data/spec/rspec/mocks/mutate_const_spec.rb +21 -1
- data/spec/rspec/mocks/nil_expectation_warning_spec.rb +10 -4
- data/spec/rspec/mocks/null_object_mock_spec.rb +11 -2
- data/spec/rspec/mocks/once_counts_spec.rb +5 -5
- data/spec/rspec/mocks/options_hash_spec.rb +4 -4
- data/spec/rspec/mocks/partial_mock_spec.rb +20 -11
- data/spec/rspec/mocks/partial_mock_using_mocks_directly_spec.rb +7 -7
- data/spec/rspec/mocks/passing_argument_matchers_spec.rb +2 -2
- data/spec/rspec/mocks/precise_counts_spec.rb +6 -6
- data/spec/rspec/mocks/serialization_spec.rb +1 -22
- data/spec/rspec/mocks/stash_spec.rb +4 -12
- data/spec/rspec/mocks/stub_implementation_spec.rb +3 -3
- data/spec/rspec/mocks/stub_spec.rb +44 -20
- data/spec/rspec/mocks/stubbed_message_expectations_spec.rb +6 -6
- data/spec/rspec/mocks/twice_counts_spec.rb +6 -6
- data/spec/rspec/mocks_spec.rb +1 -3
- data/spec/spec_helper.rb +25 -1
- metadata +86 -81
- data/features/message_expectations/expect_message.feature +0 -94
- data/lib/rspec/mocks/any_instance.rb +0 -81
- data/lib/rspec/mocks/extensions/psych.rb +0 -23
- data/lib/rspec/mocks/methods.rb +0 -155
- data/lib/rspec/mocks/serialization.rb +0 -34
- data/spec/rspec/mocks/combining_implementation_instructions_spec.rb +0 -197
@@ -0,0 +1,92 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Mocks
|
3
|
+
module Matchers
|
4
|
+
class Receive
|
5
|
+
def initialize(message, block)
|
6
|
+
@message = message
|
7
|
+
@block = block
|
8
|
+
@recorded_customizations = []
|
9
|
+
|
10
|
+
# MRI, JRuby and RBX report the caller inconsistently; MRI
|
11
|
+
# reports an extra "in `new'" line in the backtrace that the
|
12
|
+
# others do not include. The safest way to find the right
|
13
|
+
# line is to search for the first line BEFORE rspec/mocks/syntax.rb.
|
14
|
+
@backtrace_line = caller.find do |line|
|
15
|
+
!line.split(':').first.end_with?('rspec/mocks/syntax.rb')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup_expectation(subject, &block)
|
20
|
+
setup_mock_proxy_method_substitute(subject, :add_message_expectation, block)
|
21
|
+
end
|
22
|
+
alias matches? setup_expectation
|
23
|
+
|
24
|
+
def setup_negative_expectation(subject, &block)
|
25
|
+
setup_mock_proxy_method_substitute(subject, :add_negative_message_expectation, block)
|
26
|
+
end
|
27
|
+
alias does_not_match? setup_negative_expectation
|
28
|
+
|
29
|
+
def setup_allowance(subject, &block)
|
30
|
+
setup_mock_proxy_method_substitute(subject, :add_stub, block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def setup_any_instance_expectation(subject, &block)
|
34
|
+
setup_any_instance_method_substitute(subject, :should_receive, block)
|
35
|
+
end
|
36
|
+
|
37
|
+
def setup_any_instance_negative_expectation(subject, &block)
|
38
|
+
setup_any_instance_method_substitute(subject, :should_not_receive, block)
|
39
|
+
end
|
40
|
+
|
41
|
+
def setup_any_instance_allowance(subject, &block)
|
42
|
+
setup_any_instance_method_substitute(subject, :stub, block)
|
43
|
+
end
|
44
|
+
|
45
|
+
MessageExpectation.public_instance_methods(false).each do |method|
|
46
|
+
next if method_defined?(method)
|
47
|
+
|
48
|
+
class_eval(<<-RUBY)
|
49
|
+
def #{method}(*args, &block)
|
50
|
+
@recorded_customizations << Customization.new(#{method.inspect}, args, block)
|
51
|
+
self
|
52
|
+
end
|
53
|
+
RUBY
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def setup_mock_proxy_method_substitute(subject, method, block)
|
59
|
+
proxy = ::RSpec::Mocks.proxy_for(subject)
|
60
|
+
setup_method_substitute(proxy, method, block, @backtrace_line)
|
61
|
+
end
|
62
|
+
|
63
|
+
def setup_any_instance_method_substitute(subject, method, block)
|
64
|
+
any_instance_recorder = ::RSpec::Mocks.any_instance_recorder_for(subject)
|
65
|
+
setup_method_substitute(any_instance_recorder, method, block)
|
66
|
+
end
|
67
|
+
|
68
|
+
def setup_method_substitute(host, method, block, *args)
|
69
|
+
args << @message.to_sym
|
70
|
+
expectation = host.__send__(method, *args, &(@block || block))
|
71
|
+
|
72
|
+
@recorded_customizations.each do |customization|
|
73
|
+
customization.playback_onto(expectation)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class Customization
|
78
|
+
def initialize(method_name, args, block)
|
79
|
+
@method_name = method_name
|
80
|
+
@args = args
|
81
|
+
@block = block
|
82
|
+
end
|
83
|
+
|
84
|
+
def playback_onto(expectation)
|
85
|
+
expectation.__send__(@method_name, *@args, &@block)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
@@ -10,7 +10,7 @@ module RSpec
|
|
10
10
|
|
11
11
|
# @private
|
12
12
|
def initialize(error_generator, expectation_ordering, expected_from, method_double,
|
13
|
-
expected_received_count=1, opts={}, &
|
13
|
+
expected_received_count=1, opts={}, &implementation)
|
14
14
|
@error_generator = error_generator
|
15
15
|
@error_generator.opts = opts
|
16
16
|
@expected_from = expected_from
|
@@ -24,9 +24,8 @@ module RSpec
|
|
24
24
|
@args_to_yield = []
|
25
25
|
@failed_fast = nil
|
26
26
|
@eval_context = nil
|
27
|
-
|
28
|
-
@
|
29
|
-
self.inner_implementation_action = implementation_block
|
27
|
+
@implementation = implementation
|
28
|
+
@values_to_return = nil
|
30
29
|
end
|
31
30
|
|
32
31
|
# @private
|
@@ -77,12 +76,11 @@ module RSpec
|
|
77
76
|
|
78
77
|
if implementation
|
79
78
|
# TODO: deprecate `and_return { value }`
|
80
|
-
|
79
|
+
@implementation = implementation
|
81
80
|
else
|
82
|
-
|
81
|
+
@values_to_return = values
|
82
|
+
@implementation = build_implementation
|
83
83
|
end
|
84
|
-
|
85
|
-
nil
|
86
84
|
end
|
87
85
|
|
88
86
|
# Tells the object to delegate to the original unmodified method
|
@@ -100,7 +98,7 @@ module RSpec
|
|
100
98
|
if @method_double.object.is_a?(RSpec::Mocks::TestDouble)
|
101
99
|
@error_generator.raise_only_valid_on_a_partial_mock(:and_call_original)
|
102
100
|
else
|
103
|
-
@implementation =
|
101
|
+
@implementation = @method_double.original_method
|
104
102
|
end
|
105
103
|
end
|
106
104
|
|
@@ -130,8 +128,7 @@ module RSpec
|
|
130
128
|
exception = message ? exception.exception(message) : exception.exception
|
131
129
|
end
|
132
130
|
|
133
|
-
|
134
|
-
nil
|
131
|
+
@implementation = Proc.new { raise exception }
|
135
132
|
end
|
136
133
|
|
137
134
|
# @overload and_throw(symbol)
|
@@ -145,8 +142,7 @@ module RSpec
|
|
145
142
|
# car.stub(:go).and_throw(:out_of_gas)
|
146
143
|
# car.stub(:go).and_throw(:out_of_gas, :level => 0.1)
|
147
144
|
def and_throw(*args)
|
148
|
-
|
149
|
-
nil
|
145
|
+
@implementation = Proc.new { throw(*args) }
|
150
146
|
end
|
151
147
|
|
152
148
|
# Tells the object to yield one or more args to a block when the message
|
@@ -158,7 +154,7 @@ module RSpec
|
|
158
154
|
def and_yield(*args, &block)
|
159
155
|
yield @eval_context = Object.new.extend(RSpec::Mocks::InstanceExec) if block
|
160
156
|
@args_to_yield << args
|
161
|
-
|
157
|
+
@implementation = build_implementation
|
162
158
|
self
|
163
159
|
end
|
164
160
|
|
@@ -172,14 +168,16 @@ module RSpec
|
|
172
168
|
if (@expected_received_count == 0 && !@at_least) || ((@exactly || @at_most) && (@actual_received_count == @expected_received_count))
|
173
169
|
@actual_received_count += 1
|
174
170
|
@failed_fast = true
|
175
|
-
|
171
|
+
#args are the args we actually received, @argument_list_matcher is the
|
172
|
+
#list of args we were expecting
|
173
|
+
@error_generator.raise_expectation_error(@message, @expected_received_count, @argument_list_matcher, @actual_received_count, expectation_count_type, *args)
|
176
174
|
end
|
177
175
|
|
178
176
|
@order_group.handle_order_constraint self
|
179
177
|
|
180
178
|
begin
|
181
|
-
if implementation
|
182
|
-
implementation.call(*args, &block)
|
179
|
+
if @implementation
|
180
|
+
@implementation.call(*args, &block)
|
183
181
|
elsif parent_stub
|
184
182
|
parent_stub.invoke(nil, *args, &block)
|
185
183
|
end
|
@@ -247,12 +245,23 @@ module RSpec
|
|
247
245
|
# @private
|
248
246
|
def generate_error
|
249
247
|
if similar_messages.empty?
|
250
|
-
@error_generator.raise_expectation_error(@message, @expected_received_count, @actual_received_count, *expected_args)
|
248
|
+
@error_generator.raise_expectation_error(@message, @expected_received_count, @argument_list_matcher, @actual_received_count, expectation_count_type, *expected_args)
|
251
249
|
else
|
252
250
|
@error_generator.raise_similar_message_args_error(self, *@similar_messages)
|
253
251
|
end
|
254
252
|
end
|
255
253
|
|
254
|
+
def expectation_count_type
|
255
|
+
return :at_least if @at_least
|
256
|
+
return :at_most if @at_most
|
257
|
+
return nil
|
258
|
+
end
|
259
|
+
|
260
|
+
# @private
|
261
|
+
def description
|
262
|
+
@error_generator.describe_expectation(@message, @expected_received_count, @actual_received_count, *expected_args)
|
263
|
+
end
|
264
|
+
|
256
265
|
def raise_out_of_order_error
|
257
266
|
@error_generator.raise_out_of_order_error @message
|
258
267
|
end
|
@@ -282,7 +291,7 @@ module RSpec
|
|
282
291
|
# cart.add(Book.new(:isbn => 1934356379))
|
283
292
|
# # => passes
|
284
293
|
def with(*args, &block)
|
285
|
-
|
294
|
+
@implementation = block if block_given? unless args.empty?
|
286
295
|
@argument_list_matcher = ArgumentListMatcher.new(*args, &block)
|
287
296
|
self
|
288
297
|
end
|
@@ -294,7 +303,7 @@ module RSpec
|
|
294
303
|
#
|
295
304
|
# dealer.should_receive(:deal_card).exactly(10).times
|
296
305
|
def exactly(n, &block)
|
297
|
-
|
306
|
+
@implementation = block if block
|
298
307
|
set_expected_received_count :exactly, n
|
299
308
|
self
|
300
309
|
end
|
@@ -306,7 +315,11 @@ module RSpec
|
|
306
315
|
#
|
307
316
|
# dealer.should_receive(:deal_card).at_least(9).times
|
308
317
|
def at_least(n, &block)
|
309
|
-
|
318
|
+
if n == 0
|
319
|
+
RSpec.deprecate "at_least(0) with should_receive", :replacement => "stub"
|
320
|
+
end
|
321
|
+
|
322
|
+
@implementation = block if block
|
310
323
|
set_expected_received_count :at_least, n
|
311
324
|
self
|
312
325
|
end
|
@@ -318,7 +331,7 @@ module RSpec
|
|
318
331
|
#
|
319
332
|
# dealer.should_receive(:deal_card).at_most(10).times
|
320
333
|
def at_most(n, &block)
|
321
|
-
|
334
|
+
@implementation = block if block
|
322
335
|
set_expected_received_count :at_most, n
|
323
336
|
self
|
324
337
|
end
|
@@ -331,14 +344,15 @@ module RSpec
|
|
331
344
|
# dealer.should_receive(:deal_card).at_least(10).times
|
332
345
|
# dealer.should_receive(:deal_card).at_most(10).times
|
333
346
|
def times(&block)
|
334
|
-
|
347
|
+
@implementation = block if block
|
335
348
|
self
|
336
349
|
end
|
337
350
|
|
338
351
|
|
339
352
|
# Allows an expected message to be received any number of times.
|
340
353
|
def any_number_of_times(&block)
|
341
|
-
|
354
|
+
RSpec.deprecate "any_number_of_times", :replacement => "stub"
|
355
|
+
@implementation = block if block
|
342
356
|
@expected_received_count = :any
|
343
357
|
self
|
344
358
|
end
|
@@ -359,7 +373,7 @@ module RSpec
|
|
359
373
|
#
|
360
374
|
# car.should_receive(:go).once
|
361
375
|
def once(&block)
|
362
|
-
|
376
|
+
@implementation = block if block
|
363
377
|
set_expected_received_count :exactly, 1
|
364
378
|
self
|
365
379
|
end
|
@@ -370,7 +384,7 @@ module RSpec
|
|
370
384
|
#
|
371
385
|
# car.should_receive(:go).twice
|
372
386
|
def twice(&block)
|
373
|
-
|
387
|
+
@implementation = block if block
|
374
388
|
set_expected_received_count :exactly, 2
|
375
389
|
self
|
376
390
|
end
|
@@ -383,7 +397,7 @@ module RSpec
|
|
383
397
|
# api.should_receive(:run).ordered
|
384
398
|
# api.should_receive(:finish).ordered
|
385
399
|
def ordered(&block)
|
386
|
-
|
400
|
+
@implementation = block if block
|
387
401
|
@order_group.register(self)
|
388
402
|
@ordered = true
|
389
403
|
self
|
@@ -404,7 +418,7 @@ module RSpec
|
|
404
418
|
@actual_received_count += 1
|
405
419
|
end
|
406
420
|
|
407
|
-
|
421
|
+
protected
|
408
422
|
|
409
423
|
def failed_fast?
|
410
424
|
@failed_fast
|
@@ -421,16 +435,13 @@ module RSpec
|
|
421
435
|
end
|
422
436
|
end
|
423
437
|
|
424
|
-
|
425
|
-
implementation.initial_action = action
|
426
|
-
end
|
427
|
-
|
428
|
-
def inner_implementation_action=(action)
|
429
|
-
implementation.inner_action = action if action
|
430
|
-
end
|
438
|
+
private
|
431
439
|
|
432
|
-
def
|
433
|
-
|
440
|
+
def build_implementation
|
441
|
+
Implementation.new(
|
442
|
+
@values_to_return, @args_to_yield,
|
443
|
+
@eval_context, @error_generator
|
444
|
+
).method(:call)
|
434
445
|
end
|
435
446
|
end
|
436
447
|
|
@@ -441,13 +452,10 @@ module RSpec
|
|
441
452
|
super(error_generator, expectation_ordering, expected_from, method_double, 0, {}, &implementation)
|
442
453
|
end
|
443
454
|
|
455
|
+
# no-op
|
456
|
+
# @deprecated and_return is not supported with negative message expectations.
|
444
457
|
def and_return(*)
|
445
|
-
|
446
|
-
# @deprecated and_return is not supported with negative message expectations.
|
447
|
-
RSpec::Mocks.warn_deprecation <<-MSG
|
448
|
-
|
449
|
-
DEPRECATION: `and_return` with `should_not_receive` is deprecated. Called from #{caller(0)[1]}
|
450
|
-
MSG
|
458
|
+
RSpec.deprecate "and_return with should_not_receive"
|
451
459
|
end
|
452
460
|
|
453
461
|
# @private
|
@@ -456,20 +464,29 @@ MSG
|
|
456
464
|
end
|
457
465
|
end
|
458
466
|
|
459
|
-
#
|
467
|
+
# Represents a configured implementation. Takes into account
|
468
|
+
# `and_return` and `and_yield` instructions.
|
460
469
|
# @private
|
461
|
-
class
|
462
|
-
def initialize(args_to_yield, eval_context, error_generator)
|
470
|
+
class Implementation
|
471
|
+
def initialize(values_to_return, args_to_yield, eval_context, error_generator)
|
472
|
+
@values_to_return = values_to_return
|
463
473
|
@args_to_yield = args_to_yield
|
464
474
|
@eval_context = eval_context
|
465
475
|
@error_generator = error_generator
|
466
476
|
end
|
467
477
|
|
468
|
-
def
|
469
|
-
|
478
|
+
def call(*args_to_ignore, &block)
|
479
|
+
default_return_value = perform_yield(&block)
|
480
|
+
return default_return_value unless @values_to_return
|
481
|
+
|
482
|
+
if @values_to_return.size > 1
|
483
|
+
@values_to_return.shift
|
484
|
+
else
|
485
|
+
@values_to_return.first
|
486
|
+
end
|
470
487
|
end
|
471
488
|
|
472
|
-
def
|
489
|
+
def perform_yield(&block)
|
473
490
|
return if @args_to_yield.empty? && @eval_context.nil?
|
474
491
|
|
475
492
|
@error_generator.raise_missing_block_error @args_to_yield unless block
|
@@ -483,85 +500,5 @@ MSG
|
|
483
500
|
value
|
484
501
|
end
|
485
502
|
end
|
486
|
-
|
487
|
-
# Handles the implementation of an `and_return` implementation.
|
488
|
-
# @private
|
489
|
-
class AndReturnImplementation
|
490
|
-
def initialize(values_to_return)
|
491
|
-
@values_to_return = values_to_return
|
492
|
-
end
|
493
|
-
|
494
|
-
def arity
|
495
|
-
0
|
496
|
-
end
|
497
|
-
|
498
|
-
def call(&block)
|
499
|
-
if @values_to_return.size > 1
|
500
|
-
@values_to_return.shift
|
501
|
-
else
|
502
|
-
@values_to_return.first
|
503
|
-
end
|
504
|
-
end
|
505
|
-
end
|
506
|
-
|
507
|
-
# Represents a configured implementation. Takes into account
|
508
|
-
# any number of sub-implementations.
|
509
|
-
# @private
|
510
|
-
class Implementation
|
511
|
-
attr_accessor :initial_action, :inner_action, :terminal_action
|
512
|
-
|
513
|
-
def call(*args, &block)
|
514
|
-
actions.map do |action|
|
515
|
-
action.arity.zero? ? action.call(&block) : action.call(*args, &block)
|
516
|
-
end.last
|
517
|
-
end
|
518
|
-
|
519
|
-
def present?
|
520
|
-
actions.any?
|
521
|
-
end
|
522
|
-
|
523
|
-
private
|
524
|
-
|
525
|
-
def actions
|
526
|
-
[initial_action, inner_action, terminal_action].compact
|
527
|
-
end
|
528
|
-
end
|
529
|
-
|
530
|
-
# Represents an `and_call_original` implementation.
|
531
|
-
# @private
|
532
|
-
class AndCallOriginalImplementation
|
533
|
-
def initialize(method)
|
534
|
-
@method = method
|
535
|
-
end
|
536
|
-
|
537
|
-
CannotModifyFurtherError = Class.new(StandardError)
|
538
|
-
|
539
|
-
def initial_action=(value)
|
540
|
-
raise cannot_modify_further_error
|
541
|
-
end
|
542
|
-
|
543
|
-
def inner_action=(value)
|
544
|
-
raise cannot_modify_further_error
|
545
|
-
end
|
546
|
-
|
547
|
-
def terminal_action=(value)
|
548
|
-
raise cannot_modify_further_error
|
549
|
-
end
|
550
|
-
|
551
|
-
def present?
|
552
|
-
true
|
553
|
-
end
|
554
|
-
|
555
|
-
def call(*args, &block)
|
556
|
-
@method.call(*args, &block)
|
557
|
-
end
|
558
|
-
|
559
|
-
private
|
560
|
-
|
561
|
-
def cannot_modify_further_error
|
562
|
-
CannotModifyFurtherError.new "This method has already been configured " +
|
563
|
-
"to call the original implementation, and cannot be modified further."
|
564
|
-
end
|
565
|
-
end
|
566
503
|
end
|
567
504
|
end
|