rr 1.0.4 → 1.0.5.rc1

Sign up to get free protection for your applications and to get access to all the features.
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
+