mocha 1.1.0 → 1.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (263) hide show
  1. checksums.yaml +5 -5
  2. data/.github/FUNDING.yml +1 -0
  3. data/.rubocop.yml +61 -0
  4. data/.rubocop_todo.yml +27 -0
  5. data/.yardopts +1 -0
  6. data/CONTRIBUTING.md +4 -9
  7. data/README.md +114 -28
  8. data/RELEASE.md +248 -1
  9. data/Rakefile +53 -35
  10. data/gemfiles/Gemfile.test-unit.latest +5 -1
  11. data/init.rb +1 -3
  12. data/lib/mocha/any_instance_method.rb +12 -72
  13. data/lib/mocha/api.rb +121 -56
  14. data/lib/mocha/argument_iterator.rb +4 -8
  15. data/lib/mocha/backtrace_filter.rb +1 -5
  16. data/lib/mocha/block_matcher.rb +31 -0
  17. data/lib/mocha/cardinality.rb +60 -49
  18. data/lib/mocha/central.rb +21 -12
  19. data/lib/mocha/change_state_side_effect.rb +0 -4
  20. data/lib/mocha/class_methods.rb +19 -20
  21. data/lib/mocha/configuration.rb +361 -18
  22. data/lib/mocha/debug.rb +3 -2
  23. data/lib/mocha/deprecation.rb +8 -11
  24. data/lib/mocha/detection/mini_test.rb +0 -2
  25. data/lib/mocha/detection/test_unit.rb +3 -5
  26. data/lib/mocha/error_with_filtered_backtrace.rb +13 -0
  27. data/lib/mocha/exception_raiser.rb +4 -6
  28. data/lib/mocha/expectation.rb +125 -89
  29. data/lib/mocha/expectation_error.rb +1 -1
  30. data/lib/mocha/expectation_error_factory.rb +0 -1
  31. data/lib/mocha/expectation_list.rb +7 -11
  32. data/lib/mocha/hooks.rb +1 -3
  33. data/lib/mocha/in_state_ordering_constraint.rb +0 -4
  34. data/lib/mocha/inspect.rb +30 -38
  35. data/lib/mocha/instance_method.rb +15 -8
  36. data/lib/mocha/integration/mini_test/adapter.rb +2 -4
  37. data/lib/mocha/integration/mini_test/exception_translation.rb +1 -1
  38. data/lib/mocha/integration/mini_test/nothing.rb +4 -4
  39. data/lib/mocha/integration/mini_test/version_13.rb +4 -1
  40. data/lib/mocha/integration/mini_test/version_140.rb +4 -1
  41. data/lib/mocha/integration/mini_test/version_141.rb +4 -1
  42. data/lib/mocha/integration/mini_test/version_142_to_172.rb +4 -1
  43. data/lib/mocha/integration/mini_test/version_200.rb +4 -1
  44. data/lib/mocha/integration/mini_test/version_201_to_222.rb +4 -1
  45. data/lib/mocha/integration/mini_test/version_2110_to_2111.rb +4 -1
  46. data/lib/mocha/integration/mini_test/version_2112_to_320.rb +4 -1
  47. data/lib/mocha/integration/mini_test/version_230_to_2101.rb +4 -1
  48. data/lib/mocha/integration/mini_test.rb +7 -0
  49. data/lib/mocha/integration/monkey_patcher.rb +8 -2
  50. data/lib/mocha/integration/test_unit/adapter.rb +5 -6
  51. data/lib/mocha/integration/test_unit/gem_version_200.rb +5 -2
  52. data/lib/mocha/integration/test_unit/gem_version_201_to_202.rb +5 -2
  53. data/lib/mocha/integration/test_unit/gem_version_203_to_220.rb +5 -2
  54. data/lib/mocha/integration/test_unit/gem_version_230_to_250.rb +5 -2
  55. data/lib/mocha/integration/test_unit/nothing.rb +4 -4
  56. data/lib/mocha/integration/test_unit/ruby_version_185_and_below.rb +4 -1
  57. data/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb +4 -1
  58. data/lib/mocha/integration/test_unit.rb +7 -0
  59. data/lib/mocha/integration.rb +2 -5
  60. data/lib/mocha/invocation.rb +77 -0
  61. data/lib/mocha/is_a.rb +0 -2
  62. data/lib/mocha/logger.rb +0 -4
  63. data/lib/mocha/macos_version.rb +5 -0
  64. data/lib/mocha/method_matcher.rb +1 -5
  65. data/lib/mocha/minitest.rb +8 -0
  66. data/lib/mocha/mock.rb +94 -46
  67. data/lib/mocha/mockery.rb +72 -98
  68. data/lib/mocha/names.rb +2 -12
  69. data/lib/mocha/not_initialized_error.rb +7 -0
  70. data/lib/mocha/object_methods.rb +25 -31
  71. data/lib/mocha/parameter_matchers/all_of.rb +2 -8
  72. data/lib/mocha/parameter_matchers/any_of.rb +2 -8
  73. data/lib/mocha/parameter_matchers/any_parameters.rb +3 -9
  74. data/lib/mocha/parameter_matchers/anything.rb +2 -8
  75. data/lib/mocha/parameter_matchers/base.rb +6 -12
  76. data/lib/mocha/parameter_matchers/equals.rb +1 -7
  77. data/lib/mocha/parameter_matchers/{query_string.rb → equivalent_uri.rb} +15 -15
  78. data/lib/mocha/parameter_matchers/has_entries.rb +2 -7
  79. data/lib/mocha/parameter_matchers/has_entry.rb +26 -21
  80. data/lib/mocha/parameter_matchers/has_key.rb +2 -7
  81. data/lib/mocha/parameter_matchers/has_keys.rb +53 -0
  82. data/lib/mocha/parameter_matchers/has_value.rb +2 -7
  83. data/lib/mocha/parameter_matchers/includes.rb +50 -8
  84. data/lib/mocha/parameter_matchers/instance_methods.rb +18 -0
  85. data/lib/mocha/parameter_matchers/instance_of.rb +0 -6
  86. data/lib/mocha/parameter_matchers/is_a.rb +2 -7
  87. data/lib/mocha/parameter_matchers/kind_of.rb +2 -6
  88. data/lib/mocha/parameter_matchers/not.rb +2 -7
  89. data/lib/mocha/parameter_matchers/optionally.rb +4 -10
  90. data/lib/mocha/parameter_matchers/regexp_matches.rb +0 -6
  91. data/lib/mocha/parameter_matchers/responds_with.rb +3 -8
  92. data/lib/mocha/parameter_matchers/yaml_equivalent.rb +2 -6
  93. data/lib/mocha/parameter_matchers.rb +3 -4
  94. data/lib/mocha/parameters_matcher.rb +6 -9
  95. data/lib/mocha/raised_exception.rb +11 -0
  96. data/lib/mocha/receivers.rb +10 -14
  97. data/lib/mocha/return_values.rb +4 -8
  98. data/lib/mocha/ruby_version.rb +4 -0
  99. data/lib/mocha/sequence.rb +4 -9
  100. data/lib/mocha/setup.rb +5 -0
  101. data/lib/mocha/single_return_value.rb +2 -5
  102. data/lib/mocha/singleton_class.rb +9 -0
  103. data/lib/mocha/state_machine.rb +33 -46
  104. data/lib/mocha/stubbed_method.rb +125 -0
  105. data/lib/mocha/stubbing_error.rb +2 -13
  106. data/lib/mocha/test_unit.rb +7 -2
  107. data/lib/mocha/thrower.rb +4 -6
  108. data/lib/mocha/thrown_object.rb +12 -0
  109. data/lib/mocha/version.rb +1 -1
  110. data/lib/mocha/yield_parameters.rb +7 -17
  111. data/lib/mocha.rb +8 -0
  112. data/mocha.gemspec +42 -40
  113. data/yard-templates/default/layout/html/google_analytics.erb +6 -9
  114. data/yard-templates/default/layout/html/setup.rb +2 -3
  115. metadata +45 -191
  116. data/bin/build-matrix +0 -71
  117. data/gemfiles/Gemfile.minitest.1.3.0 +0 -7
  118. data/gemfiles/Gemfile.minitest.1.4.0 +0 -7
  119. data/gemfiles/Gemfile.minitest.1.4.1 +0 -7
  120. data/gemfiles/Gemfile.minitest.1.4.2 +0 -7
  121. data/gemfiles/Gemfile.minitest.2.0.0 +0 -7
  122. data/gemfiles/Gemfile.minitest.2.0.1 +0 -7
  123. data/gemfiles/Gemfile.minitest.2.11.0 +0 -7
  124. data/gemfiles/Gemfile.minitest.2.11.2 +0 -7
  125. data/gemfiles/Gemfile.minitest.2.3.0 +0 -7
  126. data/gemfiles/Gemfile.test-unit.2.0.0 +0 -7
  127. data/gemfiles/Gemfile.test-unit.2.0.1 +0 -7
  128. data/gemfiles/Gemfile.test-unit.2.0.3 +0 -7
  129. data/lib/mocha/class_method.rb +0 -127
  130. data/lib/mocha/mini_test.rb +0 -3
  131. data/lib/mocha/module_method.rb +0 -16
  132. data/lib/mocha/module_methods.rb +0 -14
  133. data/lib/mocha/multiple_yields.rb +0 -20
  134. data/lib/mocha/no_yields.rb +0 -11
  135. data/lib/mocha/parameter_matchers/object.rb +0 -17
  136. data/lib/mocha/pretty_parameters.rb +0 -28
  137. data/lib/mocha/single_yield.rb +0 -18
  138. data/lib/mocha/standalone.rb +0 -4
  139. data/lib/mocha/unexpected_invocation.rb +0 -26
  140. data/lib/mocha_standalone.rb +0 -4
  141. data/test/acceptance/acceptance_test_helper.rb +0 -41
  142. data/test/acceptance/bug_18914_test.rb +0 -43
  143. data/test/acceptance/bug_21465_test.rb +0 -34
  144. data/test/acceptance/bug_21563_test.rb +0 -25
  145. data/test/acceptance/exception_rescue_test.rb +0 -55
  146. data/test/acceptance/expectations_on_multiple_methods_test.rb +0 -55
  147. data/test/acceptance/expected_invocation_count_test.rb +0 -232
  148. data/test/acceptance/failure_messages_test.rb +0 -64
  149. data/test/acceptance/issue_65_test.rb +0 -63
  150. data/test/acceptance/issue_70_test.rb +0 -55
  151. data/test/acceptance/mocha_example_test.rb +0 -98
  152. data/test/acceptance/mocha_test_result_test.rb +0 -84
  153. data/test/acceptance/mock_test.rb +0 -100
  154. data/test/acceptance/mock_with_initializer_block_test.rb +0 -51
  155. data/test/acceptance/mocked_methods_dispatch_test.rb +0 -78
  156. data/test/acceptance/multiple_expectations_failure_message_test.rb +0 -68
  157. data/test/acceptance/optional_parameters_test.rb +0 -70
  158. data/test/acceptance/parameter_matcher_test.rb +0 -337
  159. data/test/acceptance/partial_mocks_test.rb +0 -47
  160. data/test/acceptance/prepend_test.rb +0 -88
  161. data/test/acceptance/raise_exception_test.rb +0 -39
  162. data/test/acceptance/return_value_test.rb +0 -52
  163. data/test/acceptance/sequence_test.rb +0 -192
  164. data/test/acceptance/states_test.rb +0 -70
  165. data/test/acceptance/stub_any_instance_method_defined_on_superclass_test.rb +0 -34
  166. data/test/acceptance/stub_any_instance_method_test.rb +0 -238
  167. data/test/acceptance/stub_class_method_defined_on_active_record_association_proxy_test.rb +0 -106
  168. data/test/acceptance/stub_class_method_defined_on_class_test.rb +0 -78
  169. data/test/acceptance/stub_class_method_defined_on_module_test.rb +0 -75
  170. data/test/acceptance/stub_class_method_defined_on_superclass_test.rb +0 -112
  171. data/test/acceptance/stub_everything_test.rb +0 -56
  172. data/test/acceptance/stub_instance_method_defined_on_active_record_association_proxy_test.rb +0 -93
  173. data/test/acceptance/stub_instance_method_defined_on_class_and_aliased_test.rb +0 -69
  174. data/test/acceptance/stub_instance_method_defined_on_class_test.rb +0 -69
  175. data/test/acceptance/stub_instance_method_defined_on_kernel_module_test.rb +0 -75
  176. data/test/acceptance/stub_instance_method_defined_on_module_test.rb +0 -75
  177. data/test/acceptance/stub_instance_method_defined_on_object_class_test.rb +0 -75
  178. data/test/acceptance/stub_instance_method_defined_on_singleton_class_test.rb +0 -70
  179. data/test/acceptance/stub_instance_method_defined_on_superclass_test.rb +0 -72
  180. data/test/acceptance/stub_module_method_test.rb +0 -163
  181. data/test/acceptance/stub_test.rb +0 -52
  182. data/test/acceptance/stubba_example_test.rb +0 -102
  183. data/test/acceptance/stubba_test_result_test.rb +0 -66
  184. data/test/acceptance/stubbing_error_backtrace_test.rb +0 -64
  185. data/test/acceptance/stubbing_frozen_object_test.rb +0 -88
  186. data/test/acceptance/stubbing_method_accepting_block_parameter_test.rb +0 -48
  187. data/test/acceptance/stubbing_method_unnecessarily_test.rb +0 -65
  188. data/test/acceptance/stubbing_nil_test.rb +0 -59
  189. data/test/acceptance/stubbing_non_existent_any_instance_method_test.rb +0 -130
  190. data/test/acceptance/stubbing_non_existent_class_method_test.rb +0 -157
  191. data/test/acceptance/stubbing_non_existent_instance_method_test.rb +0 -147
  192. data/test/acceptance/stubbing_non_public_any_instance_method_test.rb +0 -130
  193. data/test/acceptance/stubbing_non_public_class_method_test.rb +0 -163
  194. data/test/acceptance/stubbing_non_public_instance_method_test.rb +0 -143
  195. data/test/acceptance/stubbing_on_non_mock_object_test.rb +0 -64
  196. data/test/acceptance/stubbing_same_class_method_on_parent_and_child_classes_test.rb +0 -35
  197. data/test/acceptance/throw_test.rb +0 -45
  198. data/test/acceptance/unexpected_invocation_test.rb +0 -25
  199. data/test/acceptance/unstubbing_test.rb +0 -168
  200. data/test/assertions.rb +0 -6
  201. data/test/deprecation_disabler.rb +0 -15
  202. data/test/execution_point.rb +0 -36
  203. data/test/integration/mini_test_test.rb +0 -8
  204. data/test/integration/shared_tests.rb +0 -174
  205. data/test/integration/test_unit_test.rb +0 -8
  206. data/test/method_definer.rb +0 -24
  207. data/test/mini_test_result.rb +0 -90
  208. data/test/minitest_result.rb +0 -49
  209. data/test/simple_counter.rb +0 -13
  210. data/test/test_helper.rb +0 -50
  211. data/test/test_runner.rb +0 -58
  212. data/test/test_unit_result.rb +0 -20
  213. data/test/unit/any_instance_method_test.rb +0 -132
  214. data/test/unit/array_inspect_test.rb +0 -16
  215. data/test/unit/backtrace_filter_test.rb +0 -19
  216. data/test/unit/cardinality_test.rb +0 -56
  217. data/test/unit/central_test.rb +0 -100
  218. data/test/unit/change_state_side_effect_test.rb +0 -41
  219. data/test/unit/class_method_test.rb +0 -223
  220. data/test/unit/class_methods_test.rb +0 -40
  221. data/test/unit/configuration_test.rb +0 -38
  222. data/test/unit/date_time_inspect_test.rb +0 -21
  223. data/test/unit/exception_raiser_test.rb +0 -42
  224. data/test/unit/expectation_list_test.rb +0 -82
  225. data/test/unit/expectation_test.rb +0 -497
  226. data/test/unit/hash_inspect_test.rb +0 -16
  227. data/test/unit/hooks_test.rb +0 -29
  228. data/test/unit/in_state_ordering_constraint_test.rb +0 -43
  229. data/test/unit/method_matcher_test.rb +0 -28
  230. data/test/unit/mock_test.rb +0 -341
  231. data/test/unit/mockery_test.rb +0 -151
  232. data/test/unit/module_methods_test.rb +0 -19
  233. data/test/unit/multiple_yields_test.rb +0 -18
  234. data/test/unit/no_yields_test.rb +0 -18
  235. data/test/unit/object_inspect_test.rb +0 -38
  236. data/test/unit/object_methods_test.rb +0 -46
  237. data/test/unit/parameter_matchers/all_of_test.rb +0 -26
  238. data/test/unit/parameter_matchers/any_of_test.rb +0 -26
  239. data/test/unit/parameter_matchers/anything_test.rb +0 -21
  240. data/test/unit/parameter_matchers/equals_test.rb +0 -25
  241. data/test/unit/parameter_matchers/has_entries_test.rb +0 -51
  242. data/test/unit/parameter_matchers/has_entry_test.rb +0 -129
  243. data/test/unit/parameter_matchers/has_key_test.rb +0 -55
  244. data/test/unit/parameter_matchers/has_value_test.rb +0 -57
  245. data/test/unit/parameter_matchers/includes_test.rb +0 -59
  246. data/test/unit/parameter_matchers/instance_of_test.rb +0 -25
  247. data/test/unit/parameter_matchers/is_a_test.rb +0 -25
  248. data/test/unit/parameter_matchers/kind_of_test.rb +0 -25
  249. data/test/unit/parameter_matchers/not_test.rb +0 -26
  250. data/test/unit/parameter_matchers/regexp_matches_test.rb +0 -46
  251. data/test/unit/parameter_matchers/responds_with_test.rb +0 -32
  252. data/test/unit/parameter_matchers/stub_matcher.rb +0 -27
  253. data/test/unit/parameter_matchers/yaml_equivalent_test.rb +0 -25
  254. data/test/unit/parameters_matcher_test.rb +0 -121
  255. data/test/unit/receivers_test.rb +0 -66
  256. data/test/unit/return_values_test.rb +0 -63
  257. data/test/unit/sequence_test.rb +0 -104
  258. data/test/unit/single_return_value_test.rb +0 -14
  259. data/test/unit/single_yield_test.rb +0 -18
  260. data/test/unit/state_machine_test.rb +0 -98
  261. data/test/unit/string_inspect_test.rb +0 -11
  262. data/test/unit/thrower_test.rb +0 -20
  263. data/test/unit/yield_parameters_test.rb +0 -93
@@ -9,12 +9,12 @@ require 'mocha/is_a'
9
9
  require 'mocha/in_state_ordering_constraint'
10
10
  require 'mocha/change_state_side_effect'
11
11
  require 'mocha/cardinality'
12
+ require 'mocha/configuration'
13
+ require 'mocha/block_matcher'
12
14
 
13
15
  module Mocha
14
-
15
16
  # Methods on expectations returned from {Mock#expects}, {Mock#stubs}, {ObjectMethods#expects} and {ObjectMethods#stubs}.
16
17
  class Expectation
17
-
18
18
  # Modifies expectation so that the number of calls to the expected method must be within a specific +range+.
19
19
  #
20
20
  # @param [Range,Integer] range specifies the allowable range in the number of expected invocations.
@@ -42,7 +42,7 @@ module Mocha
42
42
  # object.expected_method
43
43
  # # => verify fails
44
44
  def times(range)
45
- @cardinality = Cardinality.times(range)
45
+ @cardinality.times(range)
46
46
  self
47
47
  end
48
48
 
@@ -68,7 +68,7 @@ module Mocha
68
68
  # object.expected_method
69
69
  # # => verify fails
70
70
  def twice
71
- @cardinality = Cardinality.exactly(2)
71
+ @cardinality.exactly(2)
72
72
  self
73
73
  end
74
74
 
@@ -93,7 +93,7 @@ module Mocha
93
93
  # object.expects(:expected_method).once
94
94
  # # => verify fails
95
95
  def once
96
- @cardinality = Cardinality.exactly(1)
96
+ @cardinality.exactly(1)
97
97
  self
98
98
  end
99
99
 
@@ -110,7 +110,7 @@ module Mocha
110
110
  # object.expects(:expected_method).never
111
111
  # # => verify succeeds
112
112
  def never
113
- @cardinality = Cardinality.exactly(0)
113
+ @cardinality.exactly(0)
114
114
  self
115
115
  end
116
116
 
@@ -130,7 +130,7 @@ module Mocha
130
130
  # object.expected_method
131
131
  # # => verify fails
132
132
  def at_least(minimum_number_of_times)
133
- @cardinality = Cardinality.at_least(minimum_number_of_times)
133
+ @cardinality.at_least(minimum_number_of_times)
134
134
  self
135
135
  end
136
136
 
@@ -149,7 +149,6 @@ module Mocha
149
149
  # # => verify fails
150
150
  def at_least_once
151
151
  at_least(1)
152
- self
153
152
  end
154
153
 
155
154
  # Modifies expectation so that the expected method must be called at most a +maximum_number_of_times+.
@@ -167,7 +166,7 @@ module Mocha
167
166
  # object.expects(:expected_method).at_most(2)
168
167
  # 3.times { object.expected_method } # => unexpected invocation
169
168
  def at_most(maximum_number_of_times)
170
- @cardinality = Cardinality.at_most(maximum_number_of_times)
169
+ @cardinality.at_most(maximum_number_of_times)
171
170
  self
172
171
  end
173
172
 
@@ -184,9 +183,8 @@ module Mocha
184
183
  # object = mock()
185
184
  # object.expects(:expected_method).at_most_once
186
185
  # 2.times { object.expected_method } # => unexpected invocation
187
- def at_most_once()
186
+ def at_most_once
188
187
  at_most(1)
189
- self
190
188
  end
191
189
 
192
190
  # Modifies expectation so that the expected method must be called with +expected_parameters+.
@@ -225,7 +223,49 @@ module Mocha
225
223
  self
226
224
  end
227
225
 
228
- # Modifies expectation so that when the expected method is called, it yields with the specified +parameters+.
226
+ # Modifies expectation so that the expected method must be called with a block.
227
+ #
228
+ # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
229
+ #
230
+ # @example Expected method must be called with a block.
231
+ # object = mock()
232
+ # object.expects(:expected_method).with_block_given
233
+ # object.expected_method { 1 + 1 }
234
+ # # => verify succeeds
235
+ #
236
+ # object = mock()
237
+ # object.expects(:expected_method).with_block_given
238
+ # object.expected_method
239
+ # # => verify fails
240
+ def with_block_given
241
+ @block_matcher = BlockMatchers::BlockGiven.new
242
+ self
243
+ end
244
+
245
+ # Modifies expectation so that the expected method must be called without a block.
246
+ #
247
+ # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
248
+ #
249
+ # @example Expected method must be called without a block.
250
+ # object = mock()
251
+ # object.expects(:expected_method).with_no_block_given
252
+ # object.expected_method
253
+ # # => verify succeeds
254
+ #
255
+ # object = mock()
256
+ # object.expects(:expected_method).with_block_given
257
+ # object.expected_method { 1 + 1 }
258
+ # # => verify fails
259
+ def with_no_block_given
260
+ @block_matcher = BlockMatchers::NoBlockGiven.new
261
+ self
262
+ end
263
+
264
+ # Modifies expectation so that when the expected method is called, it yields to the block with the specified +parameters+.
265
+ #
266
+ # If no +parameters+ are specified, it yields to the block without any parameters.
267
+ #
268
+ # If no block is provided, the method will still attempt to yield resulting in a +LocalJumpError+. Note that this is what would happen if a "real" (non-mock) method implementation tried to yield to a non-existent block.
229
269
  #
230
270
  # May be called multiple times on the same expectation for consecutive invocations.
231
271
  #
@@ -233,51 +273,58 @@ module Mocha
233
273
  # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
234
274
  # @see #then
235
275
  #
276
+ # @example Yield when expected method is invoked.
277
+ # benchmark = mock()
278
+ # benchmark.expects(:measure).yields
279
+ # yielded = false
280
+ # benchmark.measure { yielded = true }
281
+ # yielded # => true
282
+ #
236
283
  # @example Yield parameters when expected method is invoked.
237
- # object = mock()
238
- # object.expects(:expected_method).yields('result')
239
- # yielded_value = nil
240
- # object.expected_method { |value| yielded_value = value }
241
- # yielded_value # => 'result'
284
+ # fibonacci = mock()
285
+ # fibonacci.expects(:next_pair).yields(0, 1)
286
+ # sum = 0
287
+ # fibonacci.next_pair { |first, second| sum = first + second }
288
+ # sum # => 1
242
289
  #
243
290
  # @example Yield different parameters on different invocations of the expected method.
244
- # object = mock()
245
- # object.stubs(:expected_method).yields(1).then.yields(2)
246
- # yielded_values_from_first_invocation = []
247
- # yielded_values_from_second_invocation = []
248
- # object.expected_method { |value| yielded_values_from_first_invocation << value } # first invocation
249
- # object.expected_method { |value| yielded_values_from_second_invocation << value } # second invocation
250
- # yielded_values_from_first_invocation # => [1]
251
- # yielded_values_from_second_invocation # => [2]
291
+ # fibonacci = mock()
292
+ # fibonacci.expects(:next_pair).yields(0, 1).then.yields(1, 1)
293
+ # sum = 0
294
+ # fibonacci.next_pair { |first, second| sum = first + second }
295
+ # sum # => 1
296
+ # fibonacci.next_pair { |first, second| sum = first + second }
297
+ # sum # => 2
252
298
  def yields(*parameters)
253
- @yield_parameters.add(*parameters)
254
- self
299
+ multiple_yields(parameters)
255
300
  end
256
301
 
257
302
  # Modifies expectation so that when the expected method is called, it yields multiple times per invocation with the specified +parameter_groups+.
258
303
  #
259
- # @param [*Array<Array>] parameter_groups each element of +parameter_groups+ should iself be an +Array+ representing the parameters to be passed to the block for a single yield.
304
+ # If no block is provided, the method will still attempt to yield resulting in a +LocalJumpError+. Note that this is what would happen if a "real" (non-mock) method implementation tried to yield to a non-existent block.
305
+ #
306
+ # @param [*Array<Array>] parameter_groups each element of +parameter_groups+ should iself be an +Array+ representing the parameters to be passed to the block for a single yield. Any element of +parameter_groups+ that is not an +Array+ is wrapped in an +Array+.
260
307
  # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
261
308
  # @see #then
262
309
  #
263
- # @example When the +expected_method+ is called, the stub will invoke the block twice, the first time it passes +'result_1'+, +'result_2'+ as the parameters, and the second time it passes 'result_3' as the parameters.
264
- # object = mock()
265
- # object.expects(:expected_method).multiple_yields(['result_1', 'result_2'], ['result_3'])
266
- # yielded_values = []
267
- # object.expected_method { |*values| yielded_values << values }
268
- # yielded_values # => [['result_1', 'result_2'], ['result_3]]
269
- #
270
- # @example Yield different groups of parameters on different invocations of the expected method.
271
- # object = mock()
272
- # object.stubs(:expected_method).multiple_yields([1, 2], [3]).then.multiple_yields([4], [5, 6])
273
- # yielded_values_from_first_invocation = []
274
- # yielded_values_from_second_invocation = []
275
- # object.expected_method { |*values| yielded_values_from_first_invocation << values } # first invocation
276
- # object.expected_method { |*values| yielded_values_from_second_invocation << values } # second invocation
277
- # yielded_values_from_first_invocation # => [[1, 2], [3]]
278
- # yielded_values_from_second_invocation # => [[4], [5, 6]]
310
+ # @example When +foreach+ is called, the stub will invoke the block twice, the first time it passes ['row1_col1', 'row1_col2'] as the parameters, and the second time it passes ['row2_col1', ''] as the parameters.
311
+ # csv = mock()
312
+ # csv.expects(:foreach).with("path/to/file.csv").multiple_yields(['row1_col1', 'row1_col2'], ['row2_col1', ''])
313
+ # rows = []
314
+ # csv.foreach { |row| rows << row }
315
+ # rows # => [['row1_col1', 'row1_col2'], ['row2_col1', '']]
316
+ #
317
+ # @example Yield different groups of parameters on different invocations of the expected method. Simulating a situation where the CSV file at 'path/to/file.csv' has been modified between the two calls to +foreach+.
318
+ # csv = mock()
319
+ # csv.stubs(:foreach).with("path/to/file.csv").multiple_yields(['old_row1_col1', 'old_row1_col2'], ['old_row2_col1', '']).then.multiple_yields(['new_row1_col1', ''], ['new_row2_col1', 'new_row2_col2'])
320
+ # rows_from_first_invocation = []
321
+ # rows_from_second_invocation = []
322
+ # csv.foreach { |row| rows_from_first_invocation << row } # first invocation
323
+ # csv.foreach { |row| rows_from_second_invocation << row } # second invocation
324
+ # rows_from_first_invocation # => [['old_row1_col1', 'old_row1_col2'], ['old_row2_col1', '']]
325
+ # rows_from_second_invocation # => [['new_row1_col1', ''], ['new_row2_col1', 'new_row2_col2']]
279
326
  def multiple_yields(*parameter_groups)
280
- @yield_parameters.multiple_add(*parameter_groups)
327
+ @yield_parameters.add(*parameter_groups)
281
328
  self
282
329
  end
283
330
 
@@ -409,9 +456,9 @@ module Mocha
409
456
 
410
457
  # @overload def then
411
458
  # Used as syntactic sugar to improve readability. It has no effect on state of the expectation.
412
- # @overload def then(state_machine.is(state_name))
413
- # Used to change the +state_machine+ to the state specified by +state_name+ when the expected invocation occurs.
414
- # @param [StateMachine::State] state_machine.is(state_name) provides a mechanism to change the +state_machine+ into the state specified by +state_name+ when the expected method is invoked.
459
+ # @overload def then(state)
460
+ # Used to change the +state_machine+ to the specified state when the expected invocation occurs.
461
+ # @param [StateMachine::State] state state_machine.is(state_name) provides a mechanism to change the +state_machine+ into the state specified by +state_name+ when the expected method is invoked.
415
462
  #
416
463
  # @see API#states
417
464
  # @see StateMachine
@@ -437,17 +484,14 @@ module Mocha
437
484
  # radio.expects(:select_channel).with('BBC World Service').when(power.is('on'))
438
485
  # radio.expects(:adjust_volume).with(-5).when(power.is('on'))
439
486
  # radio.expects(:switch_off).then(power.is('off'))
440
- def then(*parameters)
441
- if parameters.length == 1
442
- state = parameters.first
443
- add_side_effect(ChangeStateSideEffect.new(state))
444
- end
487
+ def then(state = nil)
488
+ add_side_effect(ChangeStateSideEffect.new(state)) if state
445
489
  self
446
490
  end
447
491
 
448
- # Constrains the expectation to occur only when the +state_machine+ is in the state specified by +state_name+.
492
+ # Constrains the expectation to occur only when the +state_machine+ is in the state specified by +state_predicate+.
449
493
  #
450
- # @param [StateMachine::StatePredicate] state_machine.is(state_name) provides a mechanism to determine whether the +state_machine+ is in the state specified by +state_name+ when the expected method is invoked.
494
+ # @param [StateMachine::StatePredicate] state_predicate +state_machine.is(state_name)+ provides a mechanism to determine whether the +state_machine+ is in the state specified by +state_predicate+ when the expected method is invoked.
451
495
  # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
452
496
  #
453
497
  # @see API#states
@@ -479,7 +523,8 @@ module Mocha
479
523
  #
480
524
  # An expected method can appear in multiple sequences.
481
525
  #
482
- # @param [*Array<Sequence>] sequences sequences in which expected method should appear.
526
+ # @param [Sequence] sequence sequence in which expected method should appear.
527
+ # @param [*Array<Sequence>] sequences more sequences in which expected method should appear.
483
528
  # @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
484
529
  #
485
530
  # @see API#sequence
@@ -491,8 +536,8 @@ module Mocha
491
536
  # egg.expects(:crack).in_sequence(breakfast)
492
537
  # egg.expects(:fry).in_sequence(breakfast)
493
538
  # egg.expects(:eat).in_sequence(breakfast)
494
- def in_sequence(*sequences)
495
- sequences.each { |sequence| add_in_sequence_ordering_constraint(sequence) }
539
+ def in_sequence(sequence, *sequences)
540
+ sequences.unshift(sequence).each { |seq| add_in_sequence_ordering_constraint(seq) }
496
541
  self
497
542
  end
498
543
 
@@ -504,9 +549,10 @@ module Mocha
504
549
  @mock = mock
505
550
  @method_matcher = MethodMatcher.new(expected_method_name.to_sym)
506
551
  @parameters_matcher = ParametersMatcher.new
552
+ @block_matcher = BlockMatchers::OptionalBlock.new
507
553
  @ordering_constraints = []
508
554
  @side_effects = []
509
- @cardinality, @invocation_count = Cardinality.exactly(1), 0
555
+ @cardinality = Cardinality.new.exactly(1)
510
556
  @return_values = ReturnValues.new
511
557
  @yield_parameters = YieldParameters.new
512
558
  @backtrace = backtrace || caller
@@ -529,12 +575,12 @@ module Mocha
529
575
 
530
576
  # @private
531
577
  def perform_side_effects
532
- @side_effects.each { |side_effect| side_effect.perform }
578
+ @side_effects.each(&:perform)
533
579
  end
534
580
 
535
581
  # @private
536
582
  def in_correct_order?
537
- @ordering_constraints.all? { |ordering_constraint| ordering_constraint.allows_invocation_now? }
583
+ @ordering_constraints.all?(&:allows_invocation_now?)
538
584
  end
539
585
 
540
586
  # @private
@@ -543,70 +589,60 @@ module Mocha
543
589
  end
544
590
 
545
591
  # @private
546
- def match?(actual_method_name, *actual_parameters)
547
- @method_matcher.match?(actual_method_name) && @parameters_matcher.match?(actual_parameters) && in_correct_order?
592
+ def match?(invocation)
593
+ @method_matcher.match?(invocation.method_name) && @parameters_matcher.match?(invocation.arguments) && @block_matcher.match?(invocation.block) && in_correct_order?
548
594
  end
549
595
 
550
596
  # @private
551
597
  def invocations_allowed?
552
- @cardinality.invocations_allowed?(@invocation_count)
598
+ @cardinality.invocations_allowed?
553
599
  end
554
600
 
555
601
  # @private
556
602
  def satisfied?
557
- @cardinality.satisfied?(@invocation_count)
603
+ @cardinality.satisfied?
558
604
  end
559
605
 
560
606
  # @private
561
- def invoke
562
- @invocation_count += 1
563
- perform_side_effects()
564
- if block_given? then
565
- @yield_parameters.next_invocation.each do |yield_parameters|
566
- yield(*yield_parameters)
567
- end
568
- end
569
- @return_values.next
607
+ def invoke(invocation)
608
+ perform_side_effects
609
+ @cardinality << invocation
610
+ invocation.call(@yield_parameters, @return_values)
570
611
  end
571
612
 
572
613
  # @private
573
614
  def verified?(assertion_counter = nil)
574
615
  assertion_counter.increment if assertion_counter && @cardinality.needs_verifying?
575
- @cardinality.verified?(@invocation_count)
616
+ @cardinality.verified?
576
617
  end
577
618
 
578
619
  # @private
579
620
  def used?
580
- @cardinality.used?(@invocation_count)
621
+ @cardinality.used?
581
622
  end
582
623
 
583
624
  # @private
584
625
  def inspect
585
626
  address = __id__ * 2
586
627
  address += 0x100000000 if address < 0
587
- "#<Expectation:0x#{'%x' % address} #{mocha_inspect} >"
628
+ "#<Expectation:0x#{format('%x', address)} #{mocha_inspect} >"
588
629
  end
589
630
 
590
631
  # @private
591
632
  def mocha_inspect
592
- message = "#{@cardinality.mocha_inspect}, "
593
- message << case @invocation_count
594
- when 0 then "not yet invoked"
595
- when 1 then "invoked once"
596
- when 2 then "invoked twice"
597
- else "invoked #{@invocation_count} times"
633
+ message = "#{@cardinality.anticipated_times}, #{@cardinality.invoked_times}: #{method_signature}"
634
+ message << "; #{@ordering_constraints.map(&:mocha_inspect).join('; ')}" unless @ordering_constraints.empty?
635
+ if Mocha.configuration.display_matching_invocations_on_failure?
636
+ message << @cardinality.actual_invocations
598
637
  end
599
- message << ": "
600
- message << method_signature
601
- message << "; #{@ordering_constraints.map { |oc| oc.mocha_inspect }.join("; ")}" unless @ordering_constraints.empty?
602
638
  message
603
639
  end
604
640
 
605
641
  # @private
606
642
  def method_signature
607
- "#{@mock.mocha_inspect}.#{@method_matcher.mocha_inspect}#{@parameters_matcher.mocha_inspect}"
643
+ signature = "#{@mock.mocha_inspect}.#{@method_matcher.mocha_inspect}#{@parameters_matcher.mocha_inspect}"
644
+ signature << " #{@block_matcher.mocha_inspect}" if @block_matcher.mocha_inspect
645
+ signature
608
646
  end
609
-
610
647
  end
611
-
612
648
  end
@@ -4,5 +4,5 @@ module Mocha
4
4
  # Authors of test libraries may use +Mocha::ExpectationErrorFactory+ to have Mocha raise a different exception.
5
5
  #
6
6
  # @see Mocha::ExpectationErrorFactory
7
- class ExpectationError < Exception; end
7
+ class ExpectationError < Exception; end # rubocop:disable Lint/InheritException
8
8
  end
@@ -2,7 +2,6 @@ require 'mocha/backtrace_filter'
2
2
  require 'mocha/expectation_error'
3
3
 
4
4
  module Mocha
5
-
6
5
  # This factory determines what class of exception should be raised when Mocha detects a test failure.
7
6
  #
8
7
  # This class should only be used by authors of test libraries and not by typical "users" of Mocha.
@@ -1,7 +1,5 @@
1
1
  module Mocha
2
-
3
2
  class ExpectationList
4
-
5
3
  def initialize(expectations = [])
6
4
  @expectations = expectations
7
5
  end
@@ -19,12 +17,12 @@ module Mocha
19
17
  @expectations.any? { |expectation| expectation.matches_method?(method_name) }
20
18
  end
21
19
 
22
- def match(method_name, *arguments)
23
- matching_expectations(method_name, *arguments).first
20
+ def match(invocation)
21
+ matching_expectations(invocation).first
24
22
  end
25
23
 
26
- def match_allowing_invocation(method_name, *arguments)
27
- matching_expectations(method_name, *arguments).detect { |e| e.invocations_allowed? }
24
+ def match_allowing_invocation(invocation)
25
+ matching_expectations(invocation).detect(&:invocations_allowed?)
28
26
  end
29
27
 
30
28
  def verified?(assertion_counter = nil)
@@ -48,15 +46,13 @@ module Mocha
48
46
  end
49
47
 
50
48
  def +(other)
51
- self.class.new(self.to_a + other.to_a)
49
+ self.class.new(to_a + other.to_a)
52
50
  end
53
51
 
54
52
  private
55
53
 
56
- def matching_expectations(method_name, *arguments)
57
- @expectations.select { |e| e.match?(method_name, *arguments) }
54
+ def matching_expectations(invocation)
55
+ @expectations.select { |e| e.match?(invocation) }
58
56
  end
59
-
60
57
  end
61
-
62
58
  end
data/lib/mocha/hooks.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require 'mocha/mockery'
2
2
 
3
3
  module Mocha
4
-
5
4
  # Integration hooks for test library authors.
6
5
  #
7
6
  # The methods in this module should be called from test libraries wishing to integrate with Mocha.
@@ -21,6 +20,7 @@ module Mocha
21
20
  #
22
21
  # This method should be called before each individual test starts (including before any "setup" code).
23
22
  def mocha_setup
23
+ Mockery.setup
24
24
  end
25
25
 
26
26
  # Verifies that all mock expectations have been met (only for use by authors of test libraries).
@@ -37,8 +37,6 @@ module Mocha
37
37
  # This method should be called after each individual test has finished (including after any "teardown" code).
38
38
  def mocha_teardown
39
39
  Mockery.teardown
40
- ensure
41
- Mockery.reset_instance
42
40
  end
43
41
  end
44
42
  end
@@ -1,7 +1,5 @@
1
1
  module Mocha
2
-
3
2
  class InStateOrderingConstraint
4
-
5
3
  def initialize(state_predicate)
6
4
  @state_predicate = state_predicate
7
5
  end
@@ -13,7 +11,5 @@ module Mocha
13
11
  def mocha_inspect
14
12
  "when #{@state_predicate.mocha_inspect}"
15
13
  end
16
-
17
14
  end
18
-
19
15
  end
data/lib/mocha/inspect.rb CHANGED
@@ -1,67 +1,59 @@
1
1
  require 'date'
2
2
 
3
3
  module Mocha
4
-
5
- module ObjectMethods
6
- def mocha_inspect
7
- address = self.__id__ * 2
8
- address += 0x100000000 if address < 0
9
- inspect =~ /#</ ? "#<#{self.class}:0x#{'%x' % address}>" : inspect
4
+ module Inspect
5
+ module ObjectMethods
6
+ def mocha_inspect
7
+ address = __id__ * 2
8
+ address += 0x100000000 if address < 0
9
+ inspect =~ /#</ ? "#<#{self.class}:0x#{Kernel.format('%x', address)}>" : inspect
10
+ end
10
11
  end
11
- end
12
12
 
13
- module StringMethods
14
- def mocha_inspect
15
- inspect.gsub(/\"/, "'")
13
+ module ArrayMethods
14
+ def mocha_inspect(wrapped = true)
15
+ unwrapped = collect(&:mocha_inspect).join(', ')
16
+ wrapped ? "[#{unwrapped}]" : unwrapped
17
+ end
16
18
  end
17
- end
18
19
 
19
- module ArrayMethods
20
- def mocha_inspect
21
- "[#{collect { |member| member.mocha_inspect }.join(', ')}]"
20
+ module HashMethods
21
+ def mocha_inspect(wrapped = true)
22
+ unwrapped = collect { |key, value| "#{key.mocha_inspect} => #{value.mocha_inspect}" }.join(', ')
23
+ wrapped ? "{#{unwrapped}}" : unwrapped
24
+ end
22
25
  end
23
- end
24
26
 
25
- module HashMethods
26
- def mocha_inspect
27
- "{#{collect { |key, value| "#{key.mocha_inspect} => #{value.mocha_inspect}" }.join(', ')}}"
27
+ module TimeMethods
28
+ def mocha_inspect
29
+ "#{inspect} (#{to_f} secs)"
30
+ end
28
31
  end
29
- end
30
32
 
31
- module TimeMethods
32
- def mocha_inspect
33
- "#{inspect} (#{to_f} secs)"
33
+ module DateMethods
34
+ def mocha_inspect
35
+ to_s
36
+ end
34
37
  end
35
38
  end
36
-
37
- module DateMethods
38
- def mocha_inspect
39
- to_s
40
- end
41
- end
42
-
43
39
  end
44
40
 
45
41
  class Object
46
- include Mocha::ObjectMethods
47
- end
48
-
49
- class String
50
- include Mocha::StringMethods
42
+ include Mocha::Inspect::ObjectMethods
51
43
  end
52
44
 
53
45
  class Array
54
- include Mocha::ArrayMethods
46
+ include Mocha::Inspect::ArrayMethods
55
47
  end
56
48
 
57
49
  class Hash
58
- include Mocha::HashMethods
50
+ include Mocha::Inspect::HashMethods
59
51
  end
60
52
 
61
53
  class Time
62
- include Mocha::TimeMethods
54
+ include Mocha::Inspect::TimeMethods
63
55
  end
64
56
 
65
57
  class Date
66
- include Mocha::DateMethods
58
+ include Mocha::Inspect::DateMethods
67
59
  end
@@ -1,16 +1,23 @@
1
- require 'mocha/class_method'
1
+ require 'mocha/stubbed_method'
2
2
 
3
3
  module Mocha
4
+ class InstanceMethod < StubbedMethod
5
+ private
4
6
 
5
- class InstanceMethod < ClassMethod
7
+ def mock_owner
8
+ stubbee
9
+ end
6
10
 
7
- def method_exists?(method)
8
- return true if stubbee.public_methods(false).include?(method)
9
- return true if stubbee.protected_methods(false).include?(method)
10
- return true if stubbee.private_methods(false).include?(method)
11
- return false
11
+ def method_body(method)
12
+ PRE_RUBY_V19 ? proc { |*args, &block| method.call(*args, &block) } : method
12
13
  end
13
14
 
14
- end
15
+ def stubbee_method(method_name)
16
+ stubbee._method(method_name)
17
+ end
15
18
 
19
+ def original_method_owner
20
+ stubbee.singleton_class
21
+ end
22
+ end
16
23
  end
@@ -5,7 +5,6 @@ require 'mocha/expectation_error_factory'
5
5
  module Mocha
6
6
  module Integration
7
7
  module MiniTest
8
-
9
8
  # Integrates Mocha into recent versions of MiniTest.
10
9
  #
11
10
  # See the source code for an example of how to integrate Mocha into a test library.
@@ -19,11 +18,11 @@ module Mocha
19
18
 
20
19
  # @private
21
20
  def self.description
22
- "adapter for MiniTest gem >= v3.3.0"
21
+ 'adapter for MiniTest gem >= v3.3.0'
23
22
  end
24
23
 
25
24
  # @private
26
- def self.included(mod)
25
+ def self.included(_mod)
27
26
  Mocha::ExpectationErrorFactory.exception_class = ::MiniTest::Assertion
28
27
  end
29
28
 
@@ -51,4 +50,3 @@ module Mocha
51
50
  end
52
51
  end
53
52
  end
54
-
@@ -4,7 +4,7 @@ module Mocha
4
4
  module Integration
5
5
  module MiniTest
6
6
  def self.translate(exception)
7
- return exception unless exception.kind_of?(::Mocha::ExpectationError)
7
+ return exception unless exception.is_a?(::Mocha::ExpectationError)
8
8
  translated_exception = ::MiniTest::Assertion.new(exception.message)
9
9
  translated_exception.set_backtrace(exception.backtrace)
10
10
  translated_exception