rr 1.0.4 → 1.0.5.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.
Files changed (121) hide show
  1. checksums.yaml +15 -0
  2. data/CHANGES.md +376 -0
  3. data/Gemfile +7 -10
  4. data/README.md +822 -0
  5. data/Rakefile +24 -78
  6. data/VERSION +1 -0
  7. data/lib/rr.rb +3 -0
  8. data/lib/rr/adapters/minitest.rb +6 -0
  9. data/lib/rr/adapters/rr_methods.rb +6 -10
  10. data/lib/rr/adapters/rspec.rb +3 -0
  11. data/lib/rr/adapters/rspec2.rb +30 -0
  12. data/lib/rr/adapters/test_unit.rb +2 -0
  13. data/lib/rr/double.rb +3 -2
  14. data/lib/rr/double_definitions/child_double_definition_create.rb +3 -2
  15. data/lib/rr/double_definitions/double_definition.rb +15 -13
  16. data/lib/rr/double_definitions/double_definition_create.rb +9 -5
  17. data/lib/rr/double_definitions/double_injections/any_instance_of.rb +3 -2
  18. data/lib/rr/double_definitions/strategies/strategy.rb +5 -4
  19. data/lib/rr/double_definitions/strategies/strategy_methods.rb +6 -8
  20. data/lib/rr/double_definitions/strategies/verification/mock.rb +3 -3
  21. data/lib/rr/double_matches.rb +2 -1
  22. data/lib/rr/expectations/argument_equality_expectation.rb +2 -2
  23. data/lib/rr/expectations/times_called_expectation.rb +2 -2
  24. data/lib/rr/injections/double_injection.rb +12 -11
  25. data/lib/rr/injections/injection.rb +2 -2
  26. data/lib/rr/injections/method_missing_injection.rb +21 -7
  27. data/lib/rr/injections/singleton_method_added_injection.rb +3 -1
  28. data/lib/rr/method_dispatches/base_method_dispatch.rb +1 -1
  29. data/lib/rr/method_dispatches/method_dispatch.rb +2 -1
  30. data/lib/rr/method_dispatches/method_missing_dispatch.rb +2 -1
  31. data/lib/rr/proc_from_block.rb +8 -4
  32. data/lib/rr/space.rb +3 -2
  33. data/lib/rr/times_called_matchers/times_called_matcher.rb +2 -2
  34. data/lib/rr/version.rb +5 -0
  35. data/lib/rr/wildcard_matchers/boolean.rb +2 -2
  36. data/spec/runner.rb +41 -0
  37. metadata +45 -133
  38. data/.gitignore +0 -10
  39. data/.runrc +0 -3
  40. data/.rvmrc +0 -2
  41. data/CHANGES +0 -266
  42. data/Gemfile.lock +0 -31
  43. data/README.rdoc +0 -392
  44. data/benchmarks/rr_benchmark.rb +0 -32
  45. data/benchmarks/rspec_benchmark.rb +0 -14
  46. data/doc/0.6.0.release.markdown +0 -81
  47. data/doc/todo.txt +0 -0
  48. data/introducting_rr.txt +0 -206
  49. data/rr.gemspec +0 -37
  50. data/spec/api/any_instance_of/all_instances_of_spec.rb +0 -12
  51. data/spec/api/any_instance_of/any_instance_of_spec.rb +0 -47
  52. data/spec/api/any_instance_of/instance_of_spec.rb +0 -12
  53. data/spec/api/dont_allow/dont_allow_after_stub_spec.rb +0 -14
  54. data/spec/api/mock/mock_spec.rb +0 -193
  55. data/spec/api/proxy/proxy_spec.rb +0 -86
  56. data/spec/api/spy/spy_spec.rb +0 -49
  57. data/spec/api/strong/strong_spec.rb +0 -87
  58. data/spec/api/stub/stub_spec.rb +0 -152
  59. data/spec/core_spec_suite.rb +0 -19
  60. data/spec/environment_fixture_setup.rb +0 -8
  61. data/spec/minitest_spec_suite.rb +0 -21
  62. data/spec/proc_from_block_spec.rb +0 -14
  63. data/spec/rr/adapters/rr_methods_argument_matcher_spec.rb +0 -67
  64. data/spec/rr/adapters/rr_methods_creator_spec.rb +0 -137
  65. data/spec/rr/adapters/rr_methods_space_spec.rb +0 -98
  66. data/spec/rr/adapters/rr_methods_spec_helper.rb +0 -11
  67. data/spec/rr/adapters/rr_methods_times_matcher_spec.rb +0 -13
  68. data/spec/rr/double_definitions/child_double_definition_creator_spec.rb +0 -112
  69. data/spec/rr/double_definitions/double_definition_create_blank_slate_spec.rb +0 -91
  70. data/spec/rr/double_definitions/double_definition_create_spec.rb +0 -443
  71. data/spec/rr/double_injection/double_injection_spec.rb +0 -546
  72. data/spec/rr/double_injection/double_injection_verify_spec.rb +0 -29
  73. data/spec/rr/errors/rr_error_spec.rb +0 -67
  74. data/spec/rr/expectations/any_argument_expectation_spec.rb +0 -47
  75. data/spec/rr/expectations/anything_argument_equality_expectation_spec.rb +0 -14
  76. data/spec/rr/expectations/argument_equality_expectation_spec.rb +0 -135
  77. data/spec/rr/expectations/boolean_argument_equality_expectation_spec.rb +0 -34
  78. data/spec/rr/expectations/hash_including_argument_equality_expectation_spec.rb +0 -82
  79. data/spec/rr/expectations/hash_including_spec.rb +0 -17
  80. data/spec/rr/expectations/satisfy_argument_equality_expectation_spec.rb +0 -59
  81. data/spec/rr/expectations/satisfy_spec.rb +0 -14
  82. data/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +0 -22
  83. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +0 -37
  84. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +0 -43
  85. data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +0 -15
  86. data/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +0 -58
  87. data/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +0 -35
  88. data/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +0 -39
  89. data/spec/rr/minitest/minitest_integration_test.rb +0 -59
  90. data/spec/rr/minitest/test_helper.rb +0 -7
  91. data/spec/rr/rspec/invocation_matcher_spec.rb +0 -279
  92. data/spec/rr/rspec/rspec_adapter_spec.rb +0 -63
  93. data/spec/rr/rspec/rspec_backtrace_tweaking_spec.rb +0 -31
  94. data/spec/rr/rspec/rspec_backtrace_tweaking_spec_fixture.rb +0 -11
  95. data/spec/rr/rspec/rspec_usage_spec.rb +0 -86
  96. data/spec/rr/space/hash_with_object_id_key_spec.rb +0 -88
  97. data/spec/rr/space/space_spec.rb +0 -596
  98. data/spec/rr/test_unit/test_helper.rb +0 -7
  99. data/spec/rr/test_unit/test_unit_backtrace_test.rb +0 -36
  100. data/spec/rr/test_unit/test_unit_integration_test.rb +0 -59
  101. data/spec/rr/times_called_matchers/any_times_matcher_spec.rb +0 -47
  102. data/spec/rr/times_called_matchers/at_least_matcher_spec.rb +0 -55
  103. data/spec/rr/times_called_matchers/at_most_matcher_spec.rb +0 -70
  104. data/spec/rr/times_called_matchers/integer_matcher_spec.rb +0 -70
  105. data/spec/rr/times_called_matchers/proc_matcher_spec.rb +0 -55
  106. data/spec/rr/times_called_matchers/range_matcher_spec.rb +0 -76
  107. data/spec/rr/times_called_matchers/times_called_matcher_spec.rb +0 -118
  108. data/spec/rr/wildcard_matchers/anything_spec.rb +0 -24
  109. data/spec/rr/wildcard_matchers/boolean_spec.rb +0 -36
  110. data/spec/rr/wildcard_matchers/duck_type_spec.rb +0 -52
  111. data/spec/rr/wildcard_matchers/is_a_spec.rb +0 -32
  112. data/spec/rr/wildcard_matchers/numeric_spec.rb +0 -32
  113. data/spec/rr/wildcard_matchers/range_spec.rb +0 -35
  114. data/spec/rr/wildcard_matchers/regexp_spec.rb +0 -43
  115. data/spec/rr_spec.rb +0 -28
  116. data/spec/rspec_spec_suite.rb +0 -17
  117. data/spec/spec.opts +0 -10
  118. data/spec/spec_helper.rb +0 -41
  119. data/spec/spec_suite.rb +0 -54
  120. data/spec/spy_verification_spec.rb +0 -129
  121. data/spec/test_unit_spec_suite.rb +0 -21
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MzZiOTU0OTRjZjQ4NTUxODZhMTNkOTAxMjg3NmZiY2E1YWZmYTE1MQ==
5
+ data.tar.gz: !binary |-
6
+ OGFkYmIyMWRiNTg0ZTU5OTIyYmM4NDM3YzZkODAzOTJkMDg1MDIyMA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ YzI1MDhlMDhkMDZmMWU0ODBjZjdjZDdjZjQ5ZDkwNTEyZTA4NDM2ZmI0N2Nk
10
+ MDM4MDVlOTg5NTJjYWRiYTVjMTA5NDQ2MDFiNzhmMzMyZjliZjI0NTE0MjJl
11
+ YzM0Y2RlY2I5ZjkyNmZkN2M5MzNjNjJmZTUzMTg5YjkyOWQwN2U=
12
+ data.tar.gz: !binary |-
13
+ OWI5YTViOGFiMzg0YmIzYzZlNjZmZmFkMDkwMjczYWRjNmUxMDRhYjAzZjgw
14
+ MjNhNmU4YjQ1Njg3OTlkYTY3NzNmNTc1MWM0OTUzMGEyZTg0MTMzZjRmNjIy
15
+ YmUyYzU1ZjVlMmI4ZDc5ZmEzODc3OTlkYjQ1Nzg3Y2I5MWQzNGE=
data/CHANGES.md ADDED
@@ -0,0 +1,376 @@
1
+ # Changelog
2
+
3
+ ## 1.0.4 (2011-06-11)
4
+
5
+ * Fixed bug using workaround with leftover MethodMissingInjections
6
+
7
+ ## 1.0.3 (2011-06-11)
8
+
9
+ * Eliminate usage of ObjectSpace._id2ref (Patch Evan Phoenix)
10
+ * Added minitest adapter (Patch Caleb Spare)
11
+ * Added instructions on installing the gem (Patch Gavin Miller)
12
+ * delete missing scratch.rb file from gemspec (Patch bonkydog)
13
+
14
+ ## 1.0.2 (2010-11-01)
15
+
16
+ * Fixed Two calls recorded to a mock expecting only one call when called via
17
+ another mock's yield block
18
+ (http://github.com/btakita/rr/issues/closed#issue/42). Patch by Eugene Pimenov
19
+ (http://github.com/libc).
20
+
21
+ ## 1.0.1 (2010-10-30)
22
+
23
+ * Removed new_instance_of for Ruby 1.9.2 compatibility. instance_of is now an
24
+ alias for any_instance_of.
25
+ * Compatible with Ruby 1.9.2
26
+
27
+ ## 1.0.0 (2010-08-23)
28
+
29
+ * Added any_instance_of (aliased by all_instances_of), which binds methods
30
+ directly to the class (instead of the eigenclass).
31
+ * Subclasses of a injected class do not have their methods overridden.
32
+ * any_instance_of and new_instance_of now have a block syntax
33
+
34
+ ## 0.10.11 (2010-03-22)
35
+
36
+ * Added RR.blank_slate_whitelist
37
+ * Fixed class_eval method redefinition warning in jruby
38
+
39
+ ## 0.10.10 (2010-02-25)
40
+
41
+ * Suite passes for Ruby 1.9.1
42
+
43
+ ## 0.10.9 (2010-02-17)
44
+
45
+ * Fixed 1.8.6 bug for real
46
+
47
+ ## 0.10.8 (2010-02-16)
48
+
49
+ * Fixed 1.8.6 bug
50
+
51
+ ## 0.10.7 (2010-02-15)
52
+
53
+ * Fixed issue with DoubleInjections binding to objects overriding the method
54
+ method.
55
+
56
+ ## 0.10.6 (2010-02-15)
57
+
58
+ * Added MIT license
59
+ * Fixed Bug - dont_allow doesn't work when it follows stub
60
+ (http://github.com/btakita/rr/issues#issue/20)
61
+ * Fixed exception with DoubleInjections on proxy objects
62
+ (http://github.com/btakita/rr/issues#issue/24)
63
+ * Fixed Bug - Can't stub attribute methods on a BelongsToAssociation
64
+ (http://github.com/btakita/rr/issues#issue/24)
65
+
66
+ ## 0.10.5 (2009-12-20)
67
+
68
+ * Fixed stack overflow caused by double include in Test::Unit adapter
69
+ [http://github.com/btakita/rr/issues#issue/16]. Identified by Dave Myron
70
+ (http://github.com/contentfree)
71
+ * Fixed warnings (Patch by Bryan Helmkamp)
72
+
73
+ ## 0.10.4 (2009-09-26)
74
+
75
+ * Handle lazily defined methods (where respond_to? returns true yet the method
76
+ is not yet defined and the first call to method_missing defines the method).
77
+ This pattern is used in ActiveRecord and ActionMailer.
78
+ * Fixed warning about aliasing #instance_exec in jruby.
79
+ http://github.com/btakita/rr/issues#issue/9 (Patch by Nathan Sobo)
80
+
81
+ ## 0.10.2 (2009-08-30)
82
+
83
+ * RR properly proxies subjects with private methods
84
+ [http://github.com/btakita/rr/issues/#issue/7]. Identified by Matthew
85
+ O'Connor.
86
+
87
+ ## 0.10.1 (???)
88
+
89
+ * Fixed issue with DoubleInjection not invoking methods that are lazily created
90
+ [http://github.com/btakita/rr/issues/#issue/4]. Identified by davidlee
91
+ (http://github.com/davidlee)
92
+ * Fixed issue with mock.proxy and returns
93
+ [http://github.com/btakita/rr/issues/#issue/2]. Identified by trogdoro
94
+ (http://github.com/trogdoro)
95
+
96
+ ## 0.10.0 (2009-06-01)
97
+
98
+ * Method is no longer invoked if respond_to? returns false. This was in place to
99
+ support ActiveRecord association proxies, and is no longer needed.
100
+
101
+ ## 0.9.0 (2009-04-25)
102
+
103
+ * instance_of Doubles now apply to methods invoked in the subject's #initialize
104
+ method.
105
+
106
+ ## 0.8.1 (2009-03-29)
107
+
108
+ * Fixed exception where the Subject uses method delegation via method_missing
109
+ (e.g. certain ActiveRecord AssociationProxy methods)
110
+
111
+ ## 0.8.0 (2009-03-29)
112
+
113
+ * Fixed compatability issues with Ruby 1.9
114
+ * Aliased any_number_of_times with any_times
115
+ * Better error messages for have_received and assert_received matchers (Patch by
116
+ Joe Ferris)
117
+ * Better documentation on RR wilcard matchers (Patch by Phil Arnowsky)
118
+
119
+ ## 0.7.1 (2009-01-16)
120
+
121
+ * Performance improvements
122
+
123
+ ## 0.7.0 (2008-12-14)
124
+
125
+ * Added spies (Patchs by Joe Ferris, Michael Niessner & Mike Mangino)
126
+ * Added strongly typed reimplementation doubles (Patch by Michael Niessner)
127
+
128
+ ## 0.6.2 (???)
129
+
130
+ * Fixed DoubleDefinition chaining edge cases
131
+
132
+ ## 0.6.1 (???)
133
+
134
+ * DoubleDefinitionCreatorProxy definition eval block is instance_evaled when the
135
+ arity is not 1. When the arity is 1, the block is yielded with the
136
+ DoubleDefinitionCreatorProxy passed in.
137
+
138
+ ## 0.6.0 (2008-10-13)
139
+
140
+ * Friendlier DoubleNotFound error message
141
+ * Implemented Double strategy creation methods (#mock, #stub, #proxy,
142
+ #instance_of, and ! equivalents) on DoubleDefinition
143
+ * Implemented hash_including matcher (Patch by Matthew O'Conner)
144
+ * Implemented satisfy matcher (Patch by Matthew O'Conner)
145
+ * Implemented DoubleDefinitionCreator#mock!, #stub!, and #dont_allow!
146
+ * Modified api to method chain Doubles
147
+ * Fix conflict with Mocha overriding Object#verify
148
+
149
+ ## 0.5.0 (???)
150
+
151
+ * Method chaining Doubles (Patch by Nick Kallen)
152
+ * Chained ordered expectations (Patch by Nick Kallen)
153
+ * Space#verify_doubles can take one or more objects with DoubleInjections to be
154
+ verified
155
+
156
+ ## 0.4.10 (2008-07-06)
157
+
158
+ * DoubleDefinitionCreatorProxy does not undef #object_id
159
+ * Fixed rdoc pointer to README
160
+
161
+ ## 0.4.9 (2008-06-18)
162
+
163
+ * Proxying from RR module to RR::Space.instance
164
+
165
+ ## 0.4.8 (2008-01-23)
166
+
167
+ * Fixed issue with Hash arguments
168
+
169
+ ## 0.4.7 (2008-01-23)
170
+
171
+ * Improved error message
172
+
173
+ ## 0.4.6 (2008-01-23)
174
+
175
+ * Added Double#verbose and Double#verbose?
176
+
177
+ ## 0.4.5 (2008-01-15)
178
+
179
+ * Fixed doubles for == and #eql? methods
180
+
181
+ ## 0.4.4 (2008-01-15)
182
+
183
+ * Doc improvements
184
+ * Methods that are not alphabetic, such as ==, can be doubles
185
+
186
+ ## 0.4.3 (2008-01-07)
187
+
188
+ * Doc improvements
189
+ * Cleanup
190
+ * Finished renaming scenario to double
191
+
192
+ ## 0.4.2 (2007-12-31)
193
+
194
+ * Renamed DoubleInsertion to DoubleInjection to be consistent with Mocha
195
+ terminology
196
+
197
+ ## 0.4.1 (2007-12-31)
198
+
199
+ * Fixed backward compatability issues with rspec
200
+ * Renamed Space#verify_double_insertions to #verify_doubles
201
+
202
+ ## 0.4.0 (2007-12-30)
203
+
204
+ * Documentation improvements
205
+ * Renamed Double to DoubleInsertion
206
+ * Renamed Scenario to Double
207
+
208
+ ## 0.3.11 (2007-09-06)
209
+
210
+ * Fixed [#13724] Mock Proxy on Active Record Association proxies causes error
211
+
212
+ ## 0.3.10 (2007-08-18)
213
+
214
+ * Fixed [#13139] Blocks added to proxy sets the return_value and not the
215
+ after_call callback
216
+
217
+ ## 0.3.9 (2007-08-14)
218
+
219
+ * Alias probe to proxy
220
+
221
+ ## 0.3.8 (2007-08-12)
222
+
223
+ * Implemented [#13009] Better error mesage from TimesCalledMatcher
224
+
225
+ ## 0.3.7 (2007-08-09)
226
+
227
+ * Fixed [#12928] Reset doubles fails on Rails association proxies
228
+
229
+ ## 0.3.6 (2007-08-01)
230
+
231
+ * Fixed [#12765] Issues with ObjectSpace._id2ref
232
+
233
+ ## 0.3.5 (2007-07-29)
234
+
235
+ * trim_backtrace is only set for Test::Unit
236
+
237
+ ## 0.3.4 (2007-07-22)
238
+
239
+ * Implemented instance_of
240
+
241
+ ## 0.3.3 (2007-07-22)
242
+
243
+ * Fixed [#12495] Error Probing method_missing interaction
244
+
245
+ ## 0.3.2 (2007-07-22)
246
+
247
+ * Fixed [#12486] ScenarioMethodProxy when Kernel passed into instance methods
248
+
249
+ ## 0.3.1 (2007-07-22)
250
+
251
+ * Automatically require Test::Unit and Rspec adapters
252
+
253
+ ## 0.3.0 (2007-07-22)
254
+
255
+ * ScenarioCreator strategy method chaining
256
+ * Removed mock_probe
257
+ * Removed stub_probe
258
+
259
+ ## 0.2.5 (2007-07-21)
260
+
261
+ * mock takes method_name argument
262
+ * stub takes method_name argument
263
+ * mock_probe takes method_name argument
264
+ * stub_probe takes method_name argument
265
+ * probe takes method_name argument
266
+ * dont_allow takes method_name argument
267
+ * do_not_allow takes method_name argument
268
+
269
+ ## 0.2.4 (2007-07-19)
270
+
271
+ * Space#doubles key is now the object id
272
+ * Fixed [#12402] Stubbing return value of probes fails after calling the stubbed
273
+ method two times
274
+
275
+ ## 0.2.3 (2007-07-18)
276
+
277
+ * Added RRMethods#rr_verify and RRMethods#rr_reset
278
+
279
+ ## 0.2.2 (2007-07-17)
280
+
281
+ * Fixed "singleton method bound for a different object"
282
+ * Doing Method aliasing again to store original method
283
+
284
+ ## 0.2.1 (2007-07-17)
285
+
286
+ * Added mock_probe
287
+ * Added stub_probe
288
+ * Probe returns the return value of the passed in block, instead of ignoring its
289
+ return value
290
+ * Scenario#after_call returns the return value of the passed in block
291
+ * Not using method aliasing to store original method
292
+ * Renamed DoubleMethods to RRMethods
293
+ * Added RRMethods#mock_probe
294
+
295
+ ## 0.1.15 (2007-07-17)
296
+
297
+ * Fixed [#12333] Rebinding original_methods causes blocks not to work
298
+
299
+ ## 0.1.14 (2007-07-16)
300
+
301
+ * Introduced concept of Terminal and NonTerminal TimesCalledMatchers
302
+ * Doubles that can be called many times can be replaced
303
+ * Terminal Scenarios are called before NonTerminal Scenarios
304
+ * Error message tweaking
305
+ * Raise error when making a Scenarios with NonTerminal TimesMatcher Ordered
306
+
307
+ ## 0.1.13 (2007-07-14)
308
+
309
+ * Fixed [#12290] Scenario#returns with false causes a return value of nil
310
+
311
+ ## 0.1.12 (2007-07-14)
312
+
313
+ * Fixed bug where Creators methods are not removed when methods are defined on
314
+ Object
315
+ * Fixed [#12289] Creators methods are not removed in Rails environment
316
+
317
+ ## 0.1.11 (2007-07-14)
318
+
319
+ * Fixed [#12287] AtLeastMatcher does not cause Scenario to be called
320
+
321
+ ## 0.1.10 (2007-07-14)
322
+
323
+ * Fixed [#12286] AnyArgumentExpectation#expected_arguments not implemented
324
+
325
+ ## 0.1.9 (2007-07-14)
326
+
327
+ * Added DoubleMethods#any_times
328
+ * Added Scenario#any_number_of_times
329
+
330
+ ## 0.1.8 (2007-07-14)
331
+
332
+ * TimesCalledError Message Formatted to be on multiple lines
333
+ * ScenarioNotFoundError Message includes all Scenarios for the Double
334
+ * ScenarioOrderError shows list of remaining ordered scenarios
335
+
336
+ ## 0.1.7 (2007-07-14)
337
+
338
+ * Fixed [#12194] Double#reset_doubles are not clearing Ordered Scenarios bug
339
+ * Added Space#reset
340
+ * Space#reset_doubles and Space#reset_ordered_scenarios is now protected
341
+ * Added Scenario#at_least
342
+ * Added Scenario#at_most
343
+
344
+ ## 0.1.6 (2007-07-10)
345
+
346
+ * [#12120] probe allows a the return value to be intercepted
347
+
348
+ ## 0.1.5 (2007-07-09)
349
+
350
+ * TimesCalledExpectation says how many times were called and how many times
351
+ called were expected on error
352
+
353
+ ## 0.1.4 (2007-07-09)
354
+
355
+ * TimesCalledError prints the backtrace to where the Scenario was defined when
356
+ being verified
357
+ * Error message includes method name when Scenario is not found
358
+
359
+ ## 0.1.3 (2007-07-09)
360
+
361
+ * Fixed issue where Double#placeholder_name issues when Double method name has a
362
+ ! or ?
363
+
364
+ ## 0.1.2 (2007-07-08)
365
+
366
+ * Scenario#returns also accepts an argument
367
+ * Implemented Scenario#yields
368
+
369
+ ## 0.1.1 (2007-07-08)
370
+
371
+ * Trim the backtrace for Rspec and Test::Unit
372
+ * Rspec and Test::Unit integration fixes
373
+
374
+ ## 0.1.0 (2007-07-07)
375
+
376
+ * Initial Release
data/Gemfile CHANGED
@@ -1,12 +1,9 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
- group :test do
4
- gem "rspec", "1.3.0"
5
- gem "session", "3.1.0"
6
- gem "diff-lcs", "1.1.2"
7
- if RUBY_VERSION.include?("1.9")
8
- gem "ruby-debug19", "0.11.6"
9
- else
10
- gem "ruby-debug", "0.10.4"
11
- end
3
+ gem 'rake', '~> 10.0'
4
+
5
+ gem "rspec", "~> 2.13.0"
6
+ if RUBY_VERSION !~ /^1.8/
7
+ gem "minitest", "~> 4.7.0"
12
8
  end
9
+ gem "session", "~> 2.4.0"
data/README.md ADDED
@@ -0,0 +1,822 @@
1
+ # RR [![Build Status](https://secure.travis-ci.org/rr/rr.png)](http://travis-ci.org/rr/rr)
2
+
3
+ RR (Double Ruby) is a test double framework that features a rich selection of
4
+ double techniques and a terse syntax.
5
+
6
+ To get started, install RR from the command prompt:
7
+
8
+ ~~~
9
+ gem install rr
10
+ ~~~
11
+
12
+
13
+ ## What is a test double?
14
+
15
+ A test double is a generalization of something that replaces a real object to
16
+ make it easier to test another object. It's like a stunt double for tests. The
17
+ following are test doubles:
18
+
19
+ * Mocks
20
+ * Stubs
21
+ * Fakes
22
+ * Spies
23
+ * Proxies
24
+
25
+ *Learn more: <http://xunitpatterns.com/Test%20Double.html>*
26
+
27
+ Currently RR implements mocks, stubs, proxies, and spies. Fakes usually require
28
+ custom code, so it is beyond the scope of RR.
29
+
30
+
31
+ ## Using RR with your test framework
32
+
33
+ ### Test::Unit
34
+
35
+ ~~~ ruby
36
+ class Test::Unit::TestCase
37
+ include RR::Adapters::TestUnit
38
+ end
39
+ ~~~
40
+
41
+ ### RSpec
42
+
43
+ RR actually has two adapters, one for the newest version of RSpec (2) and
44
+ another for the older version (1). Currently RSpec targets RR's RSpec-1 adapter
45
+ and so until this is fixed you will need to specify the RSpec-2 adapter:
46
+
47
+ ~~~ ruby
48
+ RSpec.configure do |config|
49
+ config.include(RR::Adapters::RSpec2)
50
+ end
51
+ ~~~
52
+
53
+ ### MiniTest / MiniSpec
54
+
55
+ ~~~ ruby
56
+ class MiniTest::Unit::TestCase
57
+ include RR::Adapters::MiniTest
58
+ end
59
+ ~~~
60
+
61
+
62
+ ## Syntax between RR and other double/mock frameworks
63
+
64
+ ### Terse syntax
65
+
66
+ One of the goals of RR is to make doubles more scannable. This is accomplished
67
+ by making the double declaration look as much as the actual method invocation as
68
+ possible. Here is RR compared to other mock frameworks:
69
+
70
+ ~~~ ruby
71
+ # Flexmock
72
+ flexmock(User).should_receive(:find).with('42').and_return(jane)
73
+ # RSpec
74
+ User.should_receive(:find).with('42').and_return(jane)
75
+ # Mocha
76
+ User.expects(:find).with('42').returns { jane }
77
+ # rspec-mocks (using return value blocks)
78
+ User.should_receive(:find).with('42') { jane }
79
+ # RR
80
+ mock(User).find('42') { jane }
81
+ ~~~
82
+
83
+ ### Double injections (aka partial mocking)
84
+
85
+ RR utilizes a technique known as "double injection".
86
+
87
+ ~~~ ruby
88
+ my_object = MyClass.new
89
+ mock(my_object).hello
90
+ ~~~
91
+
92
+ Compare this with doing a mock in Mocha:
93
+
94
+ ~~~ ruby
95
+ my_mocked_object = mock()
96
+ my_mocked_object.expects(:hello)
97
+ ~~~
98
+
99
+ ### Pure mock objects
100
+
101
+ If you wish to use objects for the sole purpose of being a mock, you can do so
102
+ by creating an empty object:
103
+
104
+ ~~~ ruby
105
+ mock(my_mock_object = Object.new).hello
106
+ ~~~
107
+
108
+ However as a shortcut you can also use #mock!:
109
+
110
+ ~~~ ruby
111
+ # Create a new mock object with an empty #hello method, then retrieve that mock
112
+ # object via the #subject method
113
+ my_mock_object = mock!.hello.subject
114
+ ~~~
115
+
116
+ ### No #should_receive or #expects method
117
+
118
+ RR uses #method_missing to set your method expectation. This means you do not
119
+ need to use a method such as #should_receive or #expects.
120
+
121
+ ~~~ ruby
122
+ # In Mocha, #expects sets the #hello method expectation:
123
+ my_object.expects(:hello)
124
+ # Using rspec-mocks, #should_receive sets the #hello method expectation:
125
+ my_object.should_receive(:hello)
126
+ # And here's how you say it using RR:
127
+ mock(my_object).hello
128
+ ~~~
129
+
130
+ ### #with method call is not necessary
131
+
132
+ The fact that RR uses #method_missing also makes using the #with method
133
+ unnecessary in most circumstances to set the argument expectation itself
134
+ (although you can still use it if you want):
135
+
136
+ ~~~ ruby
137
+ # Mocha
138
+ my_object.expects(:hello).with('bob', 'jane')
139
+ # rspec-mocks
140
+ my_object.should_receive(:hello).with('bob', 'jane')
141
+ # RR
142
+ mock(my_object).hello('bob', 'jane')
143
+ mock(my_object).hello.with('bob', 'jane') # same thing, just more verbose
144
+ ~~~
145
+
146
+ ### Using a block to set the return value
147
+
148
+ RR supports using a block to set the return value as opposed to a specific
149
+ method call (although again, you can use #returns if you like):
150
+
151
+ ~~~ ruby
152
+ # Mocha
153
+ my_object.expects(:hello).with('bob', 'jane').returns('Hello Bob and Jane')
154
+ # rspec-mocks
155
+ my_object.should_receive(:hello).with('bob', 'jane') { 'Hello Bob and Jane' }
156
+ my_object.should_receive(:hello).with('bob', 'jane').and_return('Hello Bob and Jane') # same thing, just more verbose
157
+ # RR
158
+ mock(my_object).hello('bob', 'jane') { 'Hello Bob and Jane' }
159
+ mock(my_object).hello('bob', 'jane').returns('Hello Bob and Jane') # same thing, just more verbose
160
+ ~~~
161
+
162
+
163
+ ## Using RR
164
+
165
+ To create a double on an object, you can use the following methods:
166
+
167
+ * #mock / #mock!
168
+ * #stub / #stub!
169
+ * #dont_allow / #dont_allow!
170
+ * #proxy / #proxy!
171
+ * #instance_of / #instance_of!
172
+
173
+ These methods are composable. #mock, #stub, and #dont_allow can be used by
174
+ themselves and are mutually exclusive. #proxy and #instance_of must be chained
175
+ with #mock or #stub. You can also chain #proxy and #instance_of together.
176
+
177
+ The ! (bang) version of these methods causes the subject object of the Double to
178
+ be instantiated.
179
+
180
+ ### #mock
181
+
182
+ \#mock replaces the method on the object with an expectation and implementation.
183
+ The expectations are a mock will be called with certain arguments a certain
184
+ number of times (the default is once). You can also set the return value of the
185
+ method invocation.
186
+
187
+ *Learn more: <http://xunitpatterns.com/Mock%20Object.html>*
188
+
189
+ The following example sets an expectation that the view will receive a method
190
+ call to #render with the arguments `{:partial => "user_info"}` once. When the
191
+ method is called, `"Information"` is returned.
192
+
193
+ ~~~ ruby
194
+ view = controller.template
195
+ mock(view).render(:partial => "user_info") {"Information"}
196
+ ~~~
197
+
198
+ You can also allow any number of arguments to be passed into the mock like
199
+ this:
200
+
201
+ ~~~ ruby
202
+ mock(view).render.with_any_args.twice do |*args|
203
+ if args.first == {:partial => "user_info"}
204
+ "User Info"
205
+ else
206
+ "Stuff in the view #{args.inspect}"
207
+ end
208
+ end
209
+ ~~~
210
+
211
+ ### #stub
212
+
213
+ \#stub replaces the method on the object with only an implementation. You can
214
+ still use arguments to differentiate which stub gets invoked.
215
+
216
+ *Learn more: <http://xunitpatterns.com/Test%20Stub.html>*
217
+
218
+ The following example makes the User.find method return `jane` when passed "42"
219
+ and returns `bob` when passed "99". If another id is passed to User.find, an
220
+ exception is raised.
221
+
222
+ ~~~ ruby
223
+ jane = User.new
224
+ bob = User.new
225
+ stub(User).find('42') {jane}
226
+ stub(User).find('99') {bob}
227
+ stub(User).find do |id|
228
+ raise "Unexpected id #{id.inspect} passed to me"
229
+ end
230
+ ~~~
231
+
232
+ ### #dont_allow (aliased to #do_not_allow, #dont_call, and #do_not_call)
233
+
234
+ \#dont_allow is the opposite of #mock -- it sets an expectation on the Double
235
+ that it will never be called. If the Double actually does end up being called, a
236
+ TimesCalledError is raised.
237
+
238
+ ~~~ ruby
239
+ dont_allow(User).find('42')
240
+ User.find('42') # raises a TimesCalledError
241
+ ~~~
242
+
243
+ ### `mock.proxy`
244
+
245
+ `mock.proxy` replaces the method on the object with an expectation,
246
+ implementation, and also invokes the actual method. `mock.proxy` also intercepts
247
+ the return value and passes it into the return value block.
248
+
249
+ The following example makes sets an expectation that `view.render({:partial =>
250
+ "right_navigation"})` gets called once and returns the actual content of the
251
+ rendered partial template. A call to `view.render({:partial => "user_info"})`
252
+ will render the "user_info" partial template and send the content into the block
253
+ and is represented by the `html` variable. An assertion is done on the value of
254
+ `html` and `"Different html"` is returned.
255
+
256
+ ~~~ ruby
257
+ view = controller.template
258
+ mock.proxy(view).render(:partial => "right_navigation")
259
+ mock.proxy(view).render(:partial => "user_info") do |html|
260
+ html.should include("John Doe")
261
+ "Different html"
262
+ end
263
+ ~~~
264
+
265
+ You can also use `mock.proxy` to set expectations on the returned value. In the
266
+ following example, a call to User.find('5') does the normal ActiveRecord
267
+ implementation and passes the actual value, represented by the variable `bob`,
268
+ into the block. `bob` is then set with a `mock.proxy` for projects to return only
269
+ the first 3 projects. `bob` is also mocked so that #valid? returns false.
270
+
271
+ ~~~ ruby
272
+ mock.proxy(User).find('5') do |bob|
273
+ mock.proxy(bob).projects do |projects|
274
+ projects[0..3]
275
+ end
276
+ mock(bob).valid? { false }
277
+ bob
278
+ end
279
+ ~~~
280
+
281
+ ### `stub.proxy`
282
+
283
+ Intercept the return value of a method call. The following example verifies
284
+ `render(:partial)` will be called and renders the partial.
285
+
286
+ ~~~ ruby
287
+ view = controller.template
288
+ stub.proxy(view).render(:partial => "user_info") do |html|
289
+ html.should include("Joe Smith")
290
+ html
291
+ end
292
+ ~~~
293
+
294
+ ### #any_instance_of
295
+
296
+ Allows stubs to be added to all instances of a class. It works by binding to
297
+ methods from the class itself, rather than the eigenclass. This allows all
298
+ instances (excluding instances with the method redefined in the eigenclass) to
299
+ get the change.
300
+
301
+ Due to Ruby runtime limitations, mocks will not work as expected. It's not
302
+ obviously feasible (without an ObjectSpace lookup) to support all of RR's
303
+ methods (such as mocking). ObjectSpace is not readily supported in JRuby, since
304
+ it causes general slowness in the interpreter. I'm of the opinion that test
305
+ speed is more important than having mocks on all instances of a class. If there
306
+ is another solution, I'd be willing to add it.
307
+
308
+ ~~~ ruby
309
+ any_instance_of(User) do |u|
310
+ stub(u).valid? { false }
311
+ end
312
+ # or
313
+ any_instance_of(User, :valid? => false)
314
+ # or
315
+ any_instance_of(User, :valid? => lambda { false })
316
+ ~~~
317
+
318
+ ### Spies
319
+
320
+ Adding a DoubleInjection to an object + method (done by #stub, #mock, or
321
+ \#dont_allow) causes RR to record any method invocations to the object + method.
322
+ Assertions can then be made on the recorded method calls.
323
+
324
+ #### Test::Unit
325
+
326
+ ~~~ ruby
327
+ subject = Object.new
328
+ stub(subject).foo
329
+ subject.foo(1)
330
+ assert_received(subject) {|subject| subject.foo(1) }
331
+ assert_received(subject) {|subject| subject.bar } # This fails
332
+ ~~~
333
+
334
+ #### RSpec
335
+
336
+ ~~~ ruby
337
+ subject = Object.new
338
+ stub(subject).foo
339
+ subject.foo(1)
340
+ subject.should have_received.foo(1)
341
+ subject.should have_received.bar # This fails
342
+ ~~~
343
+
344
+ ### Block syntax
345
+
346
+ The block syntax has two modes:
347
+
348
+ * A normal block mode with a DoubleDefinitionCreatorProxy argument:
349
+
350
+ ~~~ ruby
351
+ script = MyScript.new
352
+ mock(script) do |expect|
353
+ expect.system("cd #{RAILS_ENV}") {true}
354
+ expect.system("rake foo:bar") {true}
355
+ expect.system("rake baz") {true}
356
+ end
357
+ ~~~
358
+
359
+ * An instance_eval mode where the DoubleDefinitionCreatorProxy is
360
+ instance_eval'ed:
361
+
362
+ ~~~ ruby
363
+ script = MyScript.new
364
+ mock(script) do
365
+ system("cd #{RAILS_ENV}") {true}
366
+ system("rake foo:bar") {true}
367
+ system("rake baz") {true}
368
+ end
369
+ ~~~
370
+
371
+ ### Double graphs
372
+
373
+ RR has a method-chaining API support for double graphs. For example, let's say
374
+ you want an object to receive a method call to #foo, and have the return value
375
+ receive a method call to #bar.
376
+
377
+ In RR, you would do:
378
+
379
+ ~~~ ruby
380
+ stub(object).foo.stub!.bar { :baz }
381
+ object.foo.bar #=> :baz
382
+ # or:
383
+ stub(object).foo { stub!.bar {:baz} }
384
+ object.foo.bar #=> :baz
385
+ # or:
386
+ bar = stub!.bar { :baz }
387
+ stub(object).foo { bar }
388
+ object.foo.bar #=> :baz
389
+ ~~~
390
+
391
+ ### Modifying doubles
392
+
393
+ Whenever you create a double by calling a method on an object you've wrapped,
394
+ you get back a special object: a DoubleDefinition. In other words:
395
+
396
+ ~~~ ruby
397
+ stub(object).foo #=> RR::DoubleDefinitions::DoubleDefinition
398
+ ~~~
399
+
400
+ There are several ways you can modify the behavior of these doubles via the
401
+ DoubleDefinition API, and they are listed in this section.
402
+
403
+ Quick note: all of these methods accept blocks as a shortcut for setting the
404
+ return value at the same time. In other words, if you have something like this:
405
+
406
+ ~~~ ruby
407
+ mock(object).foo { 'bar' }
408
+ ~~~
409
+
410
+ you can modify the mock and keep the return value like so:
411
+
412
+ ~~~ ruby
413
+ mock(object).foo.times(2) { 'bar' }
414
+ ~~~
415
+
416
+ You can even flip around the block:
417
+
418
+ ~~~ ruby
419
+ mock(object).foo { 'bar' }.times(2)
420
+ ~~~
421
+
422
+ And as we explain below, this is just a shortcut for:
423
+
424
+ ~~~ ruby
425
+ mock(object).foo.returns { 'bar' }.times(2)
426
+ ~~~
427
+
428
+ #### Stubbing method implementation / return value
429
+
430
+ There are two ways here. We have already covered this usage:
431
+
432
+ ~~~ ruby
433
+ stub(object).foo { 'bar' }
434
+ ~~~
435
+
436
+ However, you can also use #returns if it's more clear to you:
437
+
438
+ ~~~ ruby
439
+ stub(object).foo.returns { 'bar' }
440
+ ~~~
441
+
442
+ Regardless, keep in mind that you're actually supplying the implementation of
443
+ the method in question here, so you can put whatever you want in this block:
444
+
445
+ ~~~ ruby
446
+ stub(object).foo { |age, count|
447
+ raise 'hell' if age < 16
448
+ ret = yield count
449
+ blue? ? ret : 'whatever'
450
+ }
451
+ ~~~
452
+
453
+ This works for mocks as well as stubs.
454
+
455
+ #### Stubbing method implementation based on argument expectation
456
+
457
+ A double's implementation is always tied to its argument expectation. This means
458
+ that it is possible to return one value if the method is called one way and
459
+ return a second value if the method is called a second way. For example:
460
+
461
+ ~~~ ruby
462
+ stub(object).foo { 'bar' }
463
+ stub(object).foo(1, 2) { 'baz' }
464
+ object.foo #=> 'bar'
465
+ object.foo(1, 2) #=> 'baz'
466
+ ~~~
467
+
468
+ This works for mocks as well as stubs.
469
+
470
+ #### Stubbing method to yield given block
471
+
472
+ If you need to stub a method such that a block given to it is guaranteed to be
473
+ called when the method is called, then use #yields.
474
+
475
+ ~~~ ruby
476
+ # This outputs: [1, 2, 3]
477
+ stub(object).foo.yields(1, 2, 3)
478
+ object.foo {|*args| pp args }
479
+ ~~~
480
+
481
+ This works for mocks as well as stubs.
482
+
483
+ #### Expecting method to be called with exact argument list
484
+
485
+ There are two ways to do this. Here is the way we have shown before:
486
+
487
+ ~~~ ruby
488
+ mock(object).foo(1, 2)
489
+ object.foo(1, 2) # ok
490
+ object.foo(3) # fails
491
+ ~~~
492
+
493
+ But if this is not clear enough to you, you can use #with:
494
+
495
+ ~~~ ruby
496
+ mock(object).foo.with(1, 2)
497
+ object.foo(1, 2) # ok
498
+ object.foo(3) # fails
499
+ ~~~
500
+
501
+ As seen above, if you create an the expectation for a set of arguments and the
502
+ method is called with another set of arguments, even if *those* arguments are of
503
+ a completely different size, you will need to create another expectation for
504
+ them somehow. A simple way to do this is to #stub the method beforehand:
505
+
506
+ ~~~ ruby
507
+ stub(object).foo
508
+ mock(object).foo(1, 2)
509
+ object.foo(1, 2) # ok
510
+ object.foo(3) # ok too
511
+ ~~~
512
+
513
+ #### Expecting method to be called with any arguments
514
+
515
+ Use #with_any_args:
516
+
517
+ ~~~ ruby
518
+ mock(object).foo.with_any_args
519
+ object.foo # ok
520
+ object.foo(1) # also ok
521
+ object.foo(1, 2) # also ok
522
+ # ... you get the idea
523
+ ~~~
524
+
525
+ #### Expecting method to be called with no arguments
526
+
527
+ Use #with_no_args:
528
+
529
+ ~~~ ruby
530
+ mock(object).foo.with_no_args
531
+ object.foo # ok
532
+ object.foo(1) # fails
533
+ ~~~
534
+
535
+ #### Expecting method to never be called
536
+
537
+ Use #never:
538
+
539
+ ~~~ ruby
540
+ mock(object).foo.never
541
+ object.foo # fails
542
+ ~~~
543
+
544
+ You can also narrow the negative expectation to a specific set of arguments.
545
+ Of course, you will still need to set explicit expectations for any other ways
546
+ that your method could be called. For instance:
547
+
548
+ ~~~ ruby
549
+ mock(object).foo.with(1, 2).never
550
+ object.foo(3, 4) # fails
551
+ ~~~
552
+
553
+ RR will complain here that this is an unexpected invocation, so we need to add
554
+ an expectation for this beforehand. We can do this easily with #stub:
555
+
556
+ ~~~ ruby
557
+ stub(object).foo
558
+ ~~~
559
+
560
+ So, a full example would look like:
561
+
562
+ ~~~ ruby
563
+ stub(object).foo
564
+ mock(object).foo.with(1, 2).never
565
+ object.foo(3, 4) # ok
566
+ object.foo(1, 2) # fails
567
+ ~~~
568
+
569
+ Alternatively, you can also use #dont_allow, although the same rules apply as
570
+ above:
571
+
572
+ ~~~ ruby
573
+ stub(object).foo
574
+ dont_allow(object).foo.with(1, 2)
575
+ object.foo(3, 4) # ok
576
+ object.foo(1, 2) # fails
577
+ ~~~
578
+
579
+ #### Expecting method to be called only once
580
+
581
+ Use #once:
582
+
583
+ ~~~ ruby
584
+ mock(object).foo.once
585
+ object.foo
586
+ object.foo # fails
587
+ ~~~
588
+
589
+ #### Expecting method to called exact number of times
590
+
591
+ Use #times:
592
+
593
+ ~~~ ruby
594
+ mock(object).foo.times(3)
595
+ object.foo
596
+ object.foo
597
+ object.foo
598
+ object.foo # fails
599
+ ~~~
600
+
601
+ #### Expecting method to be called minimum number of times
602
+
603
+ Use #at_least.
604
+
605
+ For instance, this would pass:
606
+
607
+ ~~~ ruby
608
+ mock(object).foo.at_least(3)
609
+ object.foo
610
+ object.foo
611
+ object.foo
612
+ object.foo
613
+ ~~~
614
+
615
+ But this would fail:
616
+
617
+ ~~~ ruby
618
+ mock(object).foo.at_least(3)
619
+ object.foo
620
+ object.foo
621
+ ~~~
622
+
623
+ #### Expecting method to be called maximum number of times
624
+
625
+ Use #at_most.
626
+
627
+ For instance, this would pass:
628
+
629
+ ~~~ ruby
630
+ mock(object).foo.at_most(3)
631
+ object.foo
632
+ object.foo
633
+ ~~~
634
+
635
+ But this would fail:
636
+
637
+ ~~~ ruby
638
+ mock(object).foo.at_most(3)
639
+ object.foo
640
+ object.foo
641
+ object.foo
642
+ object.foo
643
+ ~~~
644
+
645
+ #### Expecting method to be called any number of times
646
+
647
+ Use #any_times. This effectively disables the times-called expectation.
648
+
649
+ ~~~ ruby
650
+ mock(object).foo.any_times
651
+ object.foo
652
+ object.foo
653
+ object.foo
654
+ ...
655
+ ~~~
656
+
657
+ You can also use #times + the argument invocation #any_times matcher:
658
+
659
+ ~~~ ruby
660
+ mock(object).foo.times(any_times)
661
+ object.foo
662
+ object.foo
663
+ object.foo
664
+ ...
665
+ ~~~
666
+
667
+
668
+
669
+ ### Argument wildcard matchers
670
+
671
+ RR also has several methods which you can use with argument expectations which
672
+ act as placeholders for arguments. When RR goes to verify the argument
673
+ expectation it will compare the placeholders with the actual arguments the
674
+ method was called with, and if they match then the test passes (hence
675
+ "matchers").
676
+
677
+ #### #anything
678
+
679
+ Matches any value.
680
+
681
+ ~~~ ruby
682
+ mock(object).foobar(1, anything)
683
+ object.foobar(1, :my_symbol)
684
+ ~~~
685
+
686
+ #### #is_a
687
+
688
+ Matches an object which `.is_a?(*Class*)`.
689
+
690
+ ~~~ ruby
691
+ mock(object).foobar(is_a(Time))
692
+ object.foobar(Time.now)
693
+ ~~~
694
+
695
+ #### #numeric
696
+
697
+ Matches a value which `.is_a?(Numeric)`.
698
+
699
+ ~~~ ruby
700
+ mock(object).foobar(numeric)
701
+ object.foobar(99)
702
+ ~~~~
703
+
704
+ #### #boolean
705
+
706
+ Matches true or false.
707
+
708
+ ~~~ ruby
709
+ mock(object).foobar(boolean)
710
+ object.foobar(false)
711
+ ~~~
712
+
713
+ #### #duck_type
714
+
715
+ Matches an object which responds to certain methods.
716
+
717
+ ~~~ ruby
718
+ mock(object).foobar(duck_type(:walk, :talk))
719
+ arg = Object.new
720
+ def arg.walk; 'waddle'; end
721
+ def arg.talk; 'quack'; end
722
+ object.foobar(arg)
723
+ ~~~
724
+
725
+ #### Ranges
726
+
727
+ Matches a number within a certain range.
728
+
729
+ ~~~ ruby
730
+ mock(object).foobar(1..10)
731
+ object.foobar(5)
732
+ ~~~
733
+
734
+ #### Regexps
735
+
736
+ Matches a string which matches a certain regex.
737
+
738
+ ~~~ ruby
739
+ mock(object).foobar(/on/)
740
+ object.foobar("ruby on rails")
741
+ ~~~
742
+
743
+ #### #hash_including
744
+
745
+ Matches a hash which contains a subset of keys and values.
746
+
747
+ ~~~ ruby
748
+ mock(object).foobar(hash_including(:red => "#FF0000", :blue => "#0000FF"))
749
+ object.foobar({:red => "#FF0000", :blue => "#0000FF", :green => "#00FF00"})
750
+ ~~~
751
+
752
+ #### #satisfy
753
+
754
+ Matches an argument which satisfies a custom requirement.
755
+
756
+ ~~~ ruby
757
+ mock(object).foobar(satisfy {|arg| arg.length == 2 })
758
+ object.foobar("xy")
759
+ ~~~
760
+
761
+ #### Writing your own argument matchers
762
+
763
+ Writing a custom argument wildcard matcher is not difficult. See
764
+ RR::WildcardMatchers for details.
765
+
766
+ ### Invocation amount wildcard matchers
767
+
768
+ #### #any_times
769
+
770
+ Only used with #times and matches any number.
771
+
772
+ ~~~ ruby
773
+ mock(object).foo.times(any_times) { return_value }
774
+ object.foo
775
+ object.foo
776
+ object.foo
777
+ ...
778
+ ~~~
779
+
780
+
781
+ ## Special thanks to
782
+
783
+ With any development effort, there are countless people who have contributed to
784
+ making it possible. We all are standing on the shoulders of giants. If you have
785
+ directly contributed to RR and I missed you in this list, please let me know and
786
+ I will add you. Thanks!
787
+
788
+ * Andreas Haller for patches
789
+ * Aslak Hellesoy for Developing RSpec
790
+ * Bryan Helmkamp for patches
791
+ * Caleb Spare for patches
792
+ * Christopher Redinger for patches
793
+ * Dan North for syntax ideas
794
+ * Dave Astels for some BDD inspiration
795
+ * Dave Myron for a bug report
796
+ * David Chelimsky for encouragement to make the RR framework, for developing the
797
+ RSpec mock framework, syntax ideas, and patches
798
+ * Daniel Sudol for identifing performance issues with RR
799
+ * Dmitry Ratnikov for patches
800
+ * Eugene Pimenov for patches
801
+ * Evan Phoenix for patches
802
+ * Felix Morio for pairing with me
803
+ * Gabriel Horner for patches
804
+ * Gavin Miller for patches
805
+ * Gerard Meszaros for his excellent book "xUnit Test Patterns"
806
+ * James Mead for developing Mocha
807
+ * Jeff Whitmire for documentation suggestions
808
+ * Jim Weirich for developing Flexmock, the first Terse ruby mock framework in Ruby
809
+ * Joe Ferris for patches
810
+ * Matthew O'Connor for patches and pairing with me
811
+ * Michael Niessner for patches and pairing with me
812
+ * Mike Mangino (from Elevated Rails) for patches and pairing with me
813
+ * Myron Marston for bug reports
814
+ * Nick Kallen for documentation suggestions, bug reports, and patches
815
+ * Nathan Sobo for various ideas and inspiration for cleaner and more expressive code
816
+ * Parker Thompson for pairing with me
817
+ * Phil Darnowsky for patches
818
+ * Pivotal Labs for sponsoring RR development
819
+ * Steven Baker for Developing RSpec
820
+ * Tatsuya Ono for patches
821
+ * Tuomas Kareinen for a bug report
822
+