rr 0.3.11 → 0.4.0
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/CHANGES +8 -3
- data/README +130 -39
- data/Rakefile +6 -5
- data/lib/rr.rb +8 -8
- data/lib/rr/adapters/rr_methods.rb +228 -0
- data/lib/rr/adapters/rspec.rb +1 -1
- data/lib/rr/adapters/test_unit.rb +1 -1
- data/lib/rr/double.rb +294 -89
- data/lib/rr/{scenario_creator.rb → double_creator.rb} +65 -66
- data/lib/rr/{scenario_definition.rb → double_definition.rb} +36 -36
- data/lib/rr/{scenario_definition_builder.rb → double_definition_builder.rb} +3 -3
- data/lib/rr/double_insertion.rb +132 -0
- data/lib/rr/{scenario_matches.rb → double_matches.rb} +2 -2
- data/lib/rr/{scenario_method_proxy.rb → double_method_proxy.rb} +2 -2
- data/lib/rr/errors/argument_equality_error.rb +3 -3
- data/lib/rr/errors/rr_error.rb +13 -13
- data/lib/rr/errors/scenario_definition_error.rb +3 -3
- data/lib/rr/errors/scenario_not_found_error.rb +3 -3
- data/lib/rr/errors/scenario_order_error.rb +3 -3
- data/lib/rr/errors/times_called_error.rb +3 -3
- data/lib/rr/expectations/any_argument_expectation.rb +1 -1
- data/lib/rr/expectations/argument_equality_expectation.rb +1 -1
- data/lib/rr/expectations/times_called_expectation.rb +1 -1
- data/lib/rr/hash_with_object_id_key.rb +1 -1
- data/lib/rr/space.rb +40 -40
- data/lib/rr/times_called_matchers/any_times_matcher.rb +13 -13
- data/lib/rr/times_called_matchers/at_least_matcher.rb +11 -11
- data/lib/rr/times_called_matchers/at_most_matcher.rb +16 -16
- data/lib/rr/times_called_matchers/integer_matcher.rb +13 -13
- data/lib/rr/times_called_matchers/non_terminal.rb +21 -21
- data/lib/rr/times_called_matchers/proc_matcher.rb +7 -7
- data/lib/rr/times_called_matchers/range_matcher.rb +14 -14
- data/lib/rr/times_called_matchers/terminal.rb +16 -16
- data/lib/rr/times_called_matchers/times_called_matcher.rb +32 -32
- data/spec/core_spec_suite.rb +18 -0
- data/{examples → spec}/environment_fixture_setup.rb +0 -1
- data/{examples/high_level_example.rb → spec/high_level_spec.rb} +11 -11
- data/spec/rr/adapters/rr_methods_argument_matcher_spec.rb +67 -0
- data/spec/rr/adapters/rr_methods_creator_spec.rb +365 -0
- data/spec/rr/adapters/rr_methods_space_spec.rb +134 -0
- data/spec/rr/adapters/rr_methods_spec_helper.rb +11 -0
- data/{examples/rr/extensions/instance_methods_times_matcher_example.rb → spec/rr/adapters/rr_methods_times_matcher_spec.rb} +4 -4
- data/spec/rr/double/double_insertion_bind_spec.rb +78 -0
- data/spec/rr/double/double_insertion_dispatching_spec.rb +221 -0
- data/spec/rr/double/double_insertion_has_original_method_spec.rb +56 -0
- data/spec/rr/double/double_insertion_register_scenario_spec.rb +24 -0
- data/spec/rr/double/double_insertion_reset_spec.rb +89 -0
- data/spec/rr/double/double_insertion_spec.rb +66 -0
- data/spec/rr/double/double_insertion_verify_spec.rb +23 -0
- data/spec/rr/double_creator_spec.rb +454 -0
- data/{examples/rr/scenario_definition_example.rb → spec/rr/double_definition_spec.rb} +143 -143
- data/spec/rr/double_method_proxy_spec.rb +71 -0
- data/spec/rr/double_spec.rb +654 -0
- data/spec/rr/errors/rr_error_spec.rb +65 -0
- data/spec/rr/expectations/any_argument_expectation_spec.rb +47 -0
- data/spec/rr/expectations/anything_argument_equality_expectation_spec.rb +38 -0
- data/spec/rr/expectations/argument_equality_expectation_spec.rb +58 -0
- data/spec/rr/expectations/boolean_argument_equality_expectation_spec.rb +53 -0
- data/spec/rr/expectations/duck_type_argument_equality_expectation_spec.rb +71 -0
- data/spec/rr/expectations/is_a_argument_equality_expectation_spec.rb +51 -0
- data/spec/rr/expectations/numeric_argument_equality_expectation_spec.rb +47 -0
- data/spec/rr/expectations/range_argument_equality_expectation_spec.rb +59 -0
- data/spec/rr/expectations/regexp_argument_equality_expectation_spec.rb +72 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +43 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +67 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +71 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +21 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +103 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +79 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +81 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb +40 -0
- data/spec/rr/rspec/rspec_adapter_spec.rb +65 -0
- data/spec/rr/rspec/rspec_backtrace_tweaking_spec.rb +52 -0
- data/spec/rr/rspec/rspec_usage_spec.rb +67 -0
- data/spec/rr/space/hash_with_object_id_key_spec.rb +88 -0
- data/spec/rr/space/space_create_spec.rb +278 -0
- data/spec/rr/space/space_helper.rb +7 -0
- data/spec/rr/space/space_register_spec.rb +32 -0
- data/spec/rr/space/space_reset_spec.rb +131 -0
- data/spec/rr/space/space_spec.rb +32 -0
- data/spec/rr/space/space_verify_spec.rb +181 -0
- data/{examples → spec}/rr/test_unit/test_helper.rb +1 -1
- data/{examples → spec}/rr/test_unit/test_unit_backtrace_test.rb +0 -0
- data/{examples → spec}/rr/test_unit/test_unit_integration_test.rb +4 -4
- data/spec/rr/times_called_matchers/any_times_matcher_spec.rb +47 -0
- data/spec/rr/times_called_matchers/at_least_matcher_spec.rb +55 -0
- data/spec/rr/times_called_matchers/at_most_matcher_spec.rb +70 -0
- data/spec/rr/times_called_matchers/integer_matcher_spec.rb +70 -0
- data/spec/rr/times_called_matchers/proc_matcher_spec.rb +55 -0
- data/spec/rr/times_called_matchers/range_matcher_spec.rb +76 -0
- data/spec/rr/times_called_matchers/times_called_matcher_spec.rb +118 -0
- data/spec/rspec_spec_suite.rb +16 -0
- data/spec/spec_helper.rb +9 -0
- data/{examples/example_suite.rb → spec/spec_suite.rb} +3 -3
- data/{examples/test_unit_example_suite.rb → spec/test_unit_spec_suite.rb} +0 -0
- metadata +93 -93
- data/examples/core_example_suite.rb +0 -31
- data/examples/example_helper.rb +0 -9
- data/examples/rr/double/double_bind_example.rb +0 -70
- data/examples/rr/double/double_dispatching_example.rb +0 -236
- data/examples/rr/double/double_example.rb +0 -66
- data/examples/rr/double/double_has_original_method_example.rb +0 -56
- data/examples/rr/double/double_register_scenario_example.rb +0 -24
- data/examples/rr/double/double_reset_example.rb +0 -89
- data/examples/rr/double/double_verify_example.rb +0 -23
- data/examples/rr/errors/rr_error_example.rb +0 -65
- data/examples/rr/expectations/any_argument_expectation_example.rb +0 -52
- data/examples/rr/expectations/anything_argument_equality_expectation_example.rb +0 -38
- data/examples/rr/expectations/argument_equality_expectation_example.rb +0 -62
- data/examples/rr/expectations/boolean_argument_equality_expectation_example.rb +0 -48
- data/examples/rr/expectations/duck_type_argument_equality_expectation_example.rb +0 -67
- data/examples/rr/expectations/is_a_argument_equality_expectation_example.rb +0 -50
- data/examples/rr/expectations/numeric_argument_equality_expectation_example.rb +0 -46
- data/examples/rr/expectations/range_argument_equality_expectation_example.rb +0 -59
- data/examples/rr/expectations/regexp_argument_equality_expectation_example.rb +0 -67
- data/examples/rr/expectations/times_called_expectation/times_called_expectation_any_times_example.rb +0 -50
- data/examples/rr/expectations/times_called_expectation/times_called_expectation_at_least_example.rb +0 -73
- data/examples/rr/expectations/times_called_expectation/times_called_expectation_at_most_example.rb +0 -77
- data/examples/rr/expectations/times_called_expectation/times_called_expectation_example.rb +0 -42
- data/examples/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +0 -20
- data/examples/rr/expectations/times_called_expectation/times_called_expectation_integer_example.rb +0 -111
- data/examples/rr/expectations/times_called_expectation/times_called_expectation_proc_example.rb +0 -88
- data/examples/rr/expectations/times_called_expectation/times_called_expectation_range_example.rb +0 -90
- data/examples/rr/extensions/instance_methods_argument_matcher_example.rb +0 -65
- data/examples/rr/extensions/instance_methods_creator_example.rb +0 -363
- data/examples/rr/extensions/instance_methods_example_helper.rb +0 -11
- data/examples/rr/extensions/instance_methods_space_example.rb +0 -122
- data/examples/rr/rspec/rspec_adapter_example.rb +0 -63
- data/examples/rr/rspec/rspec_backtrace_tweaking_example.rb +0 -36
- data/examples/rr/rspec/rspec_usage_example.rb +0 -65
- data/examples/rr/scenario_creator_example.rb +0 -459
- data/examples/rr/scenario_example.rb +0 -701
- data/examples/rr/scenario_method_proxy_example.rb +0 -71
- data/examples/rr/space/hash_with_object_id_key_example.rb +0 -86
- data/examples/rr/space/space_create_example.rb +0 -278
- data/examples/rr/space/space_example.rb +0 -29
- data/examples/rr/space/space_helper.rb +0 -7
- data/examples/rr/space/space_register_example.rb +0 -32
- data/examples/rr/space/space_reset_example.rb +0 -120
- data/examples/rr/space/space_verify_example.rb +0 -169
- data/examples/rr/times_called_matchers/any_times_matcher_example.rb +0 -63
- data/examples/rr/times_called_matchers/at_least_matcher_example.rb +0 -70
- data/examples/rr/times_called_matchers/at_most_matcher_example.rb +0 -85
- data/examples/rr/times_called_matchers/integer_matcher_example.rb +0 -91
- data/examples/rr/times_called_matchers/proc_matcher_example.rb +0 -77
- data/examples/rr/times_called_matchers/range_matcher_example.rb +0 -97
- data/examples/rr/times_called_matchers/times_called_matcher_example.rb +0 -53
- data/examples/rspec_example_suite.rb +0 -25
- data/lib/rr/extensions/instance_methods.rb +0 -228
- data/lib/rr/scenario.rb +0 -337
@@ -1,8 +1,8 @@
|
|
1
1
|
module RR
|
2
|
-
# RR::
|
2
|
+
# RR::Double is the use case for a method call.
|
3
3
|
# It has the ArgumentEqualityExpectation, TimesCalledExpectation,
|
4
4
|
# and the implementation.
|
5
|
-
class
|
5
|
+
class DoubleDefinition #:nodoc:
|
6
6
|
ORIGINAL_METHOD = Object.new
|
7
7
|
attr_accessor :times_called,
|
8
8
|
:argument_expectation,
|
@@ -23,7 +23,7 @@ module RR
|
|
23
23
|
returns_block_callback_strategy!
|
24
24
|
end
|
25
25
|
|
26
|
-
#
|
26
|
+
# Double#with sets the expectation that the Double will receive
|
27
27
|
# the passed in arguments.
|
28
28
|
#
|
29
29
|
# Passing in a block sets the return value.
|
@@ -35,7 +35,7 @@ module RR
|
|
35
35
|
self
|
36
36
|
end
|
37
37
|
|
38
|
-
#
|
38
|
+
# Double#with_any_args sets the expectation that the Double can receive
|
39
39
|
# any arguments.
|
40
40
|
#
|
41
41
|
# Passing in a block sets the return value.
|
@@ -47,7 +47,7 @@ module RR
|
|
47
47
|
self
|
48
48
|
end
|
49
49
|
|
50
|
-
#
|
50
|
+
# Double#with_no_args sets the expectation that the Double will receive
|
51
51
|
# no arguments.
|
52
52
|
#
|
53
53
|
# Passing in a block sets the return value.
|
@@ -59,7 +59,7 @@ module RR
|
|
59
59
|
self
|
60
60
|
end
|
61
61
|
|
62
|
-
#
|
62
|
+
# Double#never sets the expectation that the Double will never be
|
63
63
|
# called.
|
64
64
|
#
|
65
65
|
# This method does not accept a block because it will never be called.
|
@@ -70,7 +70,7 @@ module RR
|
|
70
70
|
self
|
71
71
|
end
|
72
72
|
|
73
|
-
#
|
73
|
+
# Double#once sets the expectation that the Double will be called
|
74
74
|
# 1 time.
|
75
75
|
#
|
76
76
|
# Passing in a block sets the return value.
|
@@ -82,7 +82,7 @@ module RR
|
|
82
82
|
self
|
83
83
|
end
|
84
84
|
|
85
|
-
#
|
85
|
+
# Double#twice sets the expectation that the Double will be called
|
86
86
|
# 2 times.
|
87
87
|
#
|
88
88
|
# Passing in a block sets the return value.
|
@@ -94,7 +94,7 @@ module RR
|
|
94
94
|
self
|
95
95
|
end
|
96
96
|
|
97
|
-
#
|
97
|
+
# Double#at_least sets the expectation that the Double
|
98
98
|
# will be called at least n times.
|
99
99
|
# It works by creating a TimesCalledExpectation.
|
100
100
|
#
|
@@ -107,7 +107,7 @@ module RR
|
|
107
107
|
self
|
108
108
|
end
|
109
109
|
|
110
|
-
#
|
110
|
+
# Double#at_most allows sets the expectation that the Double
|
111
111
|
# will be called at most n times.
|
112
112
|
# It works by creating a TimesCalledExpectation.
|
113
113
|
#
|
@@ -120,9 +120,9 @@ module RR
|
|
120
120
|
self
|
121
121
|
end
|
122
122
|
|
123
|
-
#
|
123
|
+
# Double#any_number_of_times sets an that the Double will be called
|
124
124
|
# any number of times. This effectively removes the times called expectation
|
125
|
-
# from the
|
125
|
+
# from the Doublen
|
126
126
|
#
|
127
127
|
# Passing in a block sets the return value.
|
128
128
|
#
|
@@ -133,7 +133,7 @@ module RR
|
|
133
133
|
self
|
134
134
|
end
|
135
135
|
|
136
|
-
#
|
136
|
+
# Double#times creates an TimesCalledExpectation of the passed
|
137
137
|
# in number.
|
138
138
|
#
|
139
139
|
# Passing in a block sets the return value.
|
@@ -145,7 +145,7 @@ module RR
|
|
145
145
|
self
|
146
146
|
end
|
147
147
|
|
148
|
-
#
|
148
|
+
# Double#ordered sets the Double to have an ordered
|
149
149
|
# expectation.
|
150
150
|
#
|
151
151
|
# Passing in a block sets the return value.
|
@@ -153,10 +153,10 @@ module RR
|
|
153
153
|
# mock(subject).method_name.ordered {return_value}
|
154
154
|
def ordered(&returns)
|
155
155
|
raise(
|
156
|
-
Errors::
|
157
|
-
"
|
156
|
+
Errors::DoubleDefinitionError,
|
157
|
+
"Double Definitions must have a dedicated Double to be ordered. " <<
|
158
158
|
"For example, using instance_of does not allow ordered to be used. " <<
|
159
|
-
"
|
159
|
+
"proxy the class's #new method instead."
|
160
160
|
) unless @scenario
|
161
161
|
@ordered = true
|
162
162
|
@space.ordered_scenarios << @scenario unless @space.ordered_scenarios.include?(@scenario)
|
@@ -164,17 +164,17 @@ module RR
|
|
164
164
|
self
|
165
165
|
end
|
166
166
|
|
167
|
-
#
|
167
|
+
# Double#ordered? returns true when the Double is ordered.
|
168
168
|
#
|
169
169
|
# mock(subject).method_name.ordered?
|
170
170
|
def ordered?
|
171
171
|
@ordered
|
172
172
|
end
|
173
173
|
|
174
|
-
#
|
175
|
-
# the
|
174
|
+
# Double#yields sets the Double to invoke a passed in block when
|
175
|
+
# the Double is called.
|
176
176
|
# An Expection will be raised if no block is passed in when the
|
177
|
-
#
|
177
|
+
# Double is called.
|
178
178
|
#
|
179
179
|
# Passing in a block sets the return value.
|
180
180
|
#
|
@@ -186,29 +186,29 @@ module RR
|
|
186
186
|
self
|
187
187
|
end
|
188
188
|
|
189
|
-
#
|
189
|
+
# Double#after_call creates a callback that occurs after call
|
190
190
|
# is called. The passed in block receives the return value of
|
191
|
-
# the
|
191
|
+
# the Double being called.
|
192
192
|
# An Expection will be raised if no block is passed in.
|
193
193
|
#
|
194
194
|
# mock(subject).method_name {return_value}.after_call {|return_value|}
|
195
195
|
# subject.method_name # return_value
|
196
196
|
#
|
197
|
-
# This feature is built into
|
198
|
-
#
|
197
|
+
# This feature is built into proxys.
|
198
|
+
# mock.proxy(User).find('1') {|user| mock(user).valid? {false}}
|
199
199
|
def after_call(&block)
|
200
200
|
raise ArgumentError, "after_call expects a block" unless block
|
201
201
|
@after_call_value = block
|
202
202
|
self
|
203
203
|
end
|
204
204
|
|
205
|
-
#
|
205
|
+
# Double#returns accepts an argument value or a block.
|
206
206
|
# It will raise an ArgumentError if both are passed in.
|
207
207
|
#
|
208
|
-
# Passing in a block causes
|
208
|
+
# Passing in a block causes Double to return the return value of
|
209
209
|
# the passed in block.
|
210
210
|
#
|
211
|
-
# Passing in an argument causes
|
211
|
+
# Passing in an argument causes Double to return the argument.
|
212
212
|
def returns(value=nil, &implementation)
|
213
213
|
if value && implementation
|
214
214
|
raise ArgumentError, "returns cannot accept both an argument and a block"
|
@@ -221,9 +221,9 @@ module RR
|
|
221
221
|
self
|
222
222
|
end
|
223
223
|
|
224
|
-
#
|
224
|
+
# Double#implemented_by sets the implementation of the Double.
|
225
225
|
# This method takes a Proc or a Method. Passing in a Method allows
|
226
|
-
# the
|
226
|
+
# the Double to accept blocks.
|
227
227
|
#
|
228
228
|
# obj = Object.new
|
229
229
|
# def obj.foobar
|
@@ -235,9 +235,9 @@ module RR
|
|
235
235
|
self
|
236
236
|
end
|
237
237
|
|
238
|
-
#
|
239
|
-
# of the
|
240
|
-
# This is primarily used with
|
238
|
+
# Double#implemented_by_original_method sets the implementation
|
239
|
+
# of the Double to be the original method.
|
240
|
+
# This is primarily used with proxyies.
|
241
241
|
#
|
242
242
|
# obj = Object.new
|
243
243
|
# def obj.foobar
|
@@ -250,14 +250,14 @@ module RR
|
|
250
250
|
self
|
251
251
|
end
|
252
252
|
|
253
|
-
#
|
253
|
+
# Double#exact_match? returns true when the passed in arguments
|
254
254
|
# exactly match the ArgumentEqualityExpectation arguments.
|
255
255
|
def exact_match?(*arguments)
|
256
256
|
return false unless @argument_expectation
|
257
257
|
@argument_expectation.exact_match?(*arguments)
|
258
258
|
end
|
259
259
|
|
260
|
-
#
|
260
|
+
# Double#wildcard_match? returns true when the passed in arguments
|
261
261
|
# wildcard match the ArgumentEqualityExpectation arguments.
|
262
262
|
def wildcard_match?(*arguments)
|
263
263
|
return false unless @argument_expectation
|
@@ -269,7 +269,7 @@ module RR
|
|
269
269
|
@times_matcher.terminal?
|
270
270
|
end
|
271
271
|
|
272
|
-
# The Arguments that this
|
272
|
+
# The Arguments that this Double expects
|
273
273
|
def expected_arguments
|
274
274
|
return [] unless argument_expectation
|
275
275
|
argument_expectation.expected_arguments
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module RR
|
2
|
-
class
|
2
|
+
class DoubleDefinitionBuilder #:nodoc:
|
3
3
|
attr_reader :definition
|
4
4
|
|
5
5
|
def initialize(definition, args, handler)
|
@@ -17,7 +17,7 @@ module RR
|
|
17
17
|
permissive_argument!
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
20
|
+
def dont_allow!
|
21
21
|
@definition.never
|
22
22
|
permissive_argument!
|
23
23
|
reimplementation!
|
@@ -35,7 +35,7 @@ module RR
|
|
35
35
|
@definition.returns(&@handler)
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
38
|
+
def proxy!
|
39
39
|
@definition.after_call_block_callback_strategy!
|
40
40
|
@definition.implemented_by_original_method
|
41
41
|
@definition.after_call(&@handler) if @handler
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module RR
|
2
|
+
# RR::DoubleInsertion is the binding of an object and a method.
|
3
|
+
# A double_insertion has 0 to many Double objects. Each Double
|
4
|
+
# has Argument Expectations and Times called Expectations.
|
5
|
+
class DoubleInsertion
|
6
|
+
MethodArguments = Struct.new(:arguments, :block)
|
7
|
+
attr_reader :space, :object, :method_name, :scenarios
|
8
|
+
|
9
|
+
def initialize(space, object, method_name)
|
10
|
+
@space = space
|
11
|
+
@object = object
|
12
|
+
@method_name = method_name.to_sym
|
13
|
+
if object_has_method?(method_name)
|
14
|
+
meta.send(:alias_method, original_method_name, method_name)
|
15
|
+
end
|
16
|
+
@scenarios = []
|
17
|
+
end
|
18
|
+
|
19
|
+
# RR::DoubleInsertion#register_scenario adds the passed in Double
|
20
|
+
# into this DoubleInsertion's list of Double objects.
|
21
|
+
def register_scenario(scenario)
|
22
|
+
@scenarios << scenario
|
23
|
+
end
|
24
|
+
|
25
|
+
# RR::DoubleInsertion#bind injects a method that acts as a dispatcher
|
26
|
+
# that dispatches to the matching Double when the method
|
27
|
+
# is called.
|
28
|
+
def bind
|
29
|
+
define_implementation_placeholder
|
30
|
+
returns_method = <<-METHOD
|
31
|
+
def #{@method_name}(*args, &block)
|
32
|
+
arguments = MethodArguments.new(args, block)
|
33
|
+
#{placeholder_name}(arguments)
|
34
|
+
end
|
35
|
+
METHOD
|
36
|
+
meta.class_eval(returns_method, __FILE__, __LINE__ - 5)
|
37
|
+
end
|
38
|
+
|
39
|
+
# RR::DoubleInsertion#verify verifies each Double
|
40
|
+
# TimesCalledExpectation are met.
|
41
|
+
def verify
|
42
|
+
@scenarios.each do |scenario|
|
43
|
+
scenario.verify
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# RR::DoubleInsertion#reset removes the injected dispatcher method.
|
48
|
+
# It binds the original method implementation on the object
|
49
|
+
# if one exists.
|
50
|
+
def reset
|
51
|
+
meta.send(:remove_method, placeholder_name)
|
52
|
+
if object_has_original_method?
|
53
|
+
meta.send(:alias_method, @method_name, original_method_name)
|
54
|
+
meta.send(:remove_method, original_method_name)
|
55
|
+
else
|
56
|
+
meta.send(:remove_method, @method_name)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def call_original_method(*args, &block)
|
61
|
+
@object.__send__(original_method_name, *args, &block)
|
62
|
+
end
|
63
|
+
|
64
|
+
def object_has_original_method?
|
65
|
+
object_has_method?(original_method_name)
|
66
|
+
end
|
67
|
+
|
68
|
+
protected
|
69
|
+
def define_implementation_placeholder
|
70
|
+
me = self
|
71
|
+
meta.send(:define_method, placeholder_name) do |arguments|
|
72
|
+
me.send(:call_method, arguments.arguments, arguments.block)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def call_method(args, block)
|
77
|
+
if scenario = find_scenario_to_attempt(args)
|
78
|
+
return scenario.call(self, *args, &block)
|
79
|
+
end
|
80
|
+
scenario_not_found_error(*args)
|
81
|
+
end
|
82
|
+
|
83
|
+
def find_scenario_to_attempt(args)
|
84
|
+
matches = DoubleMatches.new(@scenarios).find_all_matches!(args)
|
85
|
+
|
86
|
+
unless matches.exact_terminal_scenarios_to_attempt.empty?
|
87
|
+
return matches.exact_terminal_scenarios_to_attempt.first
|
88
|
+
end
|
89
|
+
|
90
|
+
unless matches.exact_non_terminal_scenarios_to_attempt.empty?
|
91
|
+
return matches.exact_non_terminal_scenarios_to_attempt.last
|
92
|
+
end
|
93
|
+
|
94
|
+
unless matches.wildcard_terminal_scenarios_to_attempt.empty?
|
95
|
+
return matches.wildcard_terminal_scenarios_to_attempt.first
|
96
|
+
end
|
97
|
+
|
98
|
+
unless matches.wildcard_non_terminal_scenarios_to_attempt.empty?
|
99
|
+
return matches.wildcard_non_terminal_scenarios_to_attempt.last
|
100
|
+
end
|
101
|
+
|
102
|
+
unless matches.matching_scenarios.empty?
|
103
|
+
# This will raise a TimesCalledError
|
104
|
+
return matches.matching_scenarios.first
|
105
|
+
end
|
106
|
+
|
107
|
+
return nil
|
108
|
+
end
|
109
|
+
|
110
|
+
def scenario_not_found_error(*args)
|
111
|
+
message = "Unexpected method invocation #{Double.formatted_name(@method_name, args)}, expected\n"
|
112
|
+
message << Double.list_message_part(@scenarios)
|
113
|
+
raise Errors::DoubleNotFoundError, message
|
114
|
+
end
|
115
|
+
|
116
|
+
def placeholder_name
|
117
|
+
"__rr__#{@method_name}"
|
118
|
+
end
|
119
|
+
|
120
|
+
def original_method_name
|
121
|
+
"__rr__original_#{@method_name}"
|
122
|
+
end
|
123
|
+
|
124
|
+
def object_has_method?(method_name)
|
125
|
+
@object.methods.include?(method_name.to_s) || @object.respond_to?(method_name)
|
126
|
+
end
|
127
|
+
|
128
|
+
def meta
|
129
|
+
(class << @object; self; end)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module RR
|
2
|
-
class
|
2
|
+
class DoubleMatches
|
3
3
|
attr_reader :matching_scenarios,
|
4
4
|
:exact_terminal_scenarios_to_attempt,
|
5
5
|
:exact_non_terminal_scenarios_to_attempt,
|
6
6
|
:wildcard_terminal_scenarios_to_attempt,
|
7
7
|
:wildcard_non_terminal_scenarios_to_attempt
|
8
|
-
def initialize(scenarios)
|
8
|
+
def initialize(scenarios) #:nodoc:
|
9
9
|
@scenarios = scenarios
|
10
10
|
@matching_scenarios = []
|
11
11
|
@exact_terminal_scenarios_to_attempt = []
|
data/lib/rr/errors/rr_error.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
module RR
|
2
|
-
module Errors
|
3
|
-
|
2
|
+
module Errors
|
3
|
+
BACKTRACE_IDENTIFIER = /lib\/rr/
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
class RRError < RuntimeError
|
6
|
+
attr_writer :backtrace
|
7
|
+
def backtrace
|
8
|
+
original_backtrace = (@backtrace) ? @backtrace : super
|
9
|
+
return original_backtrace unless RR::Space.trim_backtrace
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
return original_backtrace unless original_backtrace.respond_to?(:each)
|
12
|
+
new_backtrace = []
|
13
|
+
original_backtrace.each do |line|
|
14
|
+
new_backtrace << line unless line =~ BACKTRACE_IDENTIFIER
|
15
|
+
end
|
16
|
+
new_backtrace
|
15
17
|
end
|
16
|
-
new_backtrace
|
17
18
|
end
|
18
19
|
end
|
19
|
-
end
|
20
20
|
end
|