mocha 1.11.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (262) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -1
  3. data/CONTRIBUTING.md +1 -1
  4. data/Gemfile +29 -0
  5. data/README.md +35 -31
  6. data/RELEASE.md +128 -0
  7. data/Rakefile +26 -22
  8. data/gemfiles/Gemfile.minitest.latest +1 -0
  9. data/gemfiles/Gemfile.test-unit.latest +2 -5
  10. data/lib/mocha/any_instance_method.rb +0 -5
  11. data/lib/mocha/api.rb +29 -78
  12. data/lib/mocha/cardinality.rb +30 -27
  13. data/lib/mocha/class_methods.rb +2 -2
  14. data/lib/mocha/configuration.rb +30 -108
  15. data/lib/mocha/expectation.rb +86 -31
  16. data/lib/mocha/inspect.rb +5 -3
  17. data/lib/mocha/instance_method.rb +0 -4
  18. data/lib/mocha/integration/mini_test.rb +10 -38
  19. data/lib/mocha/integration/test_unit/adapter.rb +1 -1
  20. data/lib/mocha/integration/test_unit.rb +10 -33
  21. data/lib/mocha/invocation.rb +12 -16
  22. data/lib/mocha/minitest.rb +2 -4
  23. data/lib/mocha/mock.rb +26 -26
  24. data/lib/mocha/mockery.rb +10 -25
  25. data/lib/mocha/parameter_matchers/base.rb +1 -1
  26. data/lib/mocha/parameter_matchers/equivalent_uri.rb +0 -1
  27. data/lib/mocha/parameter_matchers/has_entry.rb +22 -13
  28. data/lib/mocha/parameter_matchers/has_keys.rb +53 -0
  29. data/lib/mocha/parameter_matchers/instance_methods.rb +10 -1
  30. data/lib/mocha/parameter_matchers/positional_or_keyword_hash.rb +64 -0
  31. data/lib/mocha/parameter_matchers.rb +1 -0
  32. data/lib/mocha/parameters_matcher.rb +3 -3
  33. data/lib/mocha/ruby_version.rb +1 -2
  34. data/lib/mocha/state_machine.rb +30 -38
  35. data/lib/mocha/stubbed_method.rb +5 -42
  36. data/lib/mocha/test_unit.rb +2 -4
  37. data/lib/mocha/version.rb +1 -1
  38. data/lib/mocha.rb +0 -8
  39. data/mocha.gemspec +6 -31
  40. metadata +10 -286
  41. data/bin/build-matrix +0 -82
  42. data/docs/CNAME +0 -1
  43. data/docs/Mocha/API.html +0 -1285
  44. data/docs/Mocha/ClassMethods.html +0 -264
  45. data/docs/Mocha/Configuration.html +0 -1525
  46. data/docs/Mocha/Expectation.html +0 -2862
  47. data/docs/Mocha/ExpectationError.html +0 -152
  48. data/docs/Mocha/ExpectationErrorFactory.html +0 -260
  49. data/docs/Mocha/Hooks.html +0 -370
  50. data/docs/Mocha/Integration/MiniTest/Adapter.html +0 -164
  51. data/docs/Mocha/Integration/MiniTest.html +0 -123
  52. data/docs/Mocha/Integration/TestUnit/Adapter.html +0 -164
  53. data/docs/Mocha/Integration/TestUnit.html +0 -123
  54. data/docs/Mocha/Integration.html +0 -125
  55. data/docs/Mocha/Mock.html +0 -1210
  56. data/docs/Mocha/ObjectMethods.html +0 -765
  57. data/docs/Mocha/ParameterMatchers/AllOf.html +0 -153
  58. data/docs/Mocha/ParameterMatchers/AnyOf.html +0 -153
  59. data/docs/Mocha/ParameterMatchers/AnyParameters.html +0 -153
  60. data/docs/Mocha/ParameterMatchers/Anything.html +0 -153
  61. data/docs/Mocha/ParameterMatchers/Base.html +0 -441
  62. data/docs/Mocha/ParameterMatchers/Equals.html +0 -153
  63. data/docs/Mocha/ParameterMatchers/EquivalentUri.html +0 -153
  64. data/docs/Mocha/ParameterMatchers/HasEntries.html +0 -153
  65. data/docs/Mocha/ParameterMatchers/HasEntry.html +0 -153
  66. data/docs/Mocha/ParameterMatchers/HasKey.html +0 -153
  67. data/docs/Mocha/ParameterMatchers/HasValue.html +0 -153
  68. data/docs/Mocha/ParameterMatchers/Includes.html +0 -153
  69. data/docs/Mocha/ParameterMatchers/InstanceOf.html +0 -153
  70. data/docs/Mocha/ParameterMatchers/IsA.html +0 -153
  71. data/docs/Mocha/ParameterMatchers/KindOf.html +0 -153
  72. data/docs/Mocha/ParameterMatchers/Not.html +0 -153
  73. data/docs/Mocha/ParameterMatchers/Optionally.html +0 -153
  74. data/docs/Mocha/ParameterMatchers/RegexpMatches.html +0 -153
  75. data/docs/Mocha/ParameterMatchers/RespondsWith.html +0 -153
  76. data/docs/Mocha/ParameterMatchers/YamlEquivalent.html +0 -153
  77. data/docs/Mocha/ParameterMatchers.html +0 -2949
  78. data/docs/Mocha/Sequence.html +0 -149
  79. data/docs/Mocha/StateMachine/State.html +0 -140
  80. data/docs/Mocha/StateMachine/StatePredicate.html +0 -140
  81. data/docs/Mocha/StateMachine.html +0 -527
  82. data/docs/Mocha/StubbingError.html +0 -150
  83. data/docs/Mocha.html +0 -254
  84. data/docs/_index.html +0 -519
  85. data/docs/class_list.html +0 -51
  86. data/docs/css/common.css +0 -1
  87. data/docs/css/full_list.css +0 -58
  88. data/docs/css/style.css +0 -496
  89. data/docs/file.COPYING.html +0 -81
  90. data/docs/file.MIT-LICENSE.html +0 -85
  91. data/docs/file.README.html +0 -448
  92. data/docs/file.RELEASE.html +0 -1028
  93. data/docs/file_list.html +0 -71
  94. data/docs/frames.html +0 -17
  95. data/docs/index.html +0 -448
  96. data/docs/js/app.js +0 -303
  97. data/docs/js/full_list.js +0 -216
  98. data/docs/js/jquery.js +0 -4
  99. data/docs/method_list.html +0 -651
  100. data/docs/top-level-namespace.html +0 -118
  101. data/gemfiles/Gemfile.minitest.1.3.0 +0 -7
  102. data/gemfiles/Gemfile.minitest.1.4.0 +0 -7
  103. data/gemfiles/Gemfile.minitest.1.4.1 +0 -7
  104. data/gemfiles/Gemfile.minitest.1.4.2 +0 -7
  105. data/gemfiles/Gemfile.minitest.2.0.0 +0 -7
  106. data/gemfiles/Gemfile.minitest.2.0.1 +0 -7
  107. data/gemfiles/Gemfile.minitest.2.11.0 +0 -7
  108. data/gemfiles/Gemfile.minitest.2.11.2 +0 -7
  109. data/gemfiles/Gemfile.minitest.2.3.0 +0 -7
  110. data/gemfiles/Gemfile.minitest.5.11.3 +0 -7
  111. data/gemfiles/Gemfile.test-unit.2.0.0 +0 -7
  112. data/gemfiles/Gemfile.test-unit.2.0.1 +0 -7
  113. data/gemfiles/Gemfile.test-unit.2.0.3 +0 -7
  114. data/init.rb +0 -1
  115. data/lib/mocha/integration/mini_test/nothing.rb +0 -19
  116. data/lib/mocha/integration/mini_test/version_13.rb +0 -54
  117. data/lib/mocha/integration/mini_test/version_140.rb +0 -54
  118. data/lib/mocha/integration/mini_test/version_141.rb +0 -65
  119. data/lib/mocha/integration/mini_test/version_142_to_172.rb +0 -65
  120. data/lib/mocha/integration/mini_test/version_200.rb +0 -66
  121. data/lib/mocha/integration/mini_test/version_201_to_222.rb +0 -66
  122. data/lib/mocha/integration/mini_test/version_2110_to_2111.rb +0 -70
  123. data/lib/mocha/integration/mini_test/version_2112_to_320.rb +0 -73
  124. data/lib/mocha/integration/mini_test/version_230_to_2101.rb +0 -68
  125. data/lib/mocha/integration/test_unit/gem_version_200.rb +0 -62
  126. data/lib/mocha/integration/test_unit/gem_version_201_to_202.rb +0 -62
  127. data/lib/mocha/integration/test_unit/gem_version_203_to_220.rb +0 -62
  128. data/lib/mocha/integration/test_unit/gem_version_230_to_250.rb +0 -68
  129. data/lib/mocha/integration/test_unit/nothing.rb +0 -19
  130. data/lib/mocha/integration/test_unit/ruby_version_185_and_below.rb +0 -61
  131. data/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb +0 -63
  132. data/lib/mocha/integration.rb +0 -11
  133. data/lib/mocha/setup.rb +0 -14
  134. data/lib/mocha/singleton_class.rb +0 -9
  135. data/test/acceptance/acceptance_test_helper.rb +0 -42
  136. data/test/acceptance/bug_18914_test.rb +0 -37
  137. data/test/acceptance/bug_21465_test.rb +0 -31
  138. data/test/acceptance/bug_21563_test.rb +0 -22
  139. data/test/acceptance/display_matching_invocations_alongside_expectations_test.rb +0 -69
  140. data/test/acceptance/exception_rescue_test.rb +0 -53
  141. data/test/acceptance/expectations_on_multiple_methods_test.rb +0 -55
  142. data/test/acceptance/expected_invocation_count_test.rb +0 -229
  143. data/test/acceptance/failure_messages_test.rb +0 -77
  144. data/test/acceptance/issue_272_test.rb +0 -50
  145. data/test/acceptance/issue_457_test.rb +0 -31
  146. data/test/acceptance/issue_65_test.rb +0 -64
  147. data/test/acceptance/issue_70_test.rb +0 -53
  148. data/test/acceptance/mocha_example_test.rb +0 -106
  149. data/test/acceptance/mocha_test_result_test.rb +0 -83
  150. data/test/acceptance/mock_built_with_first_argument_type_being_string_test.rb +0 -98
  151. data/test/acceptance/mock_test.rb +0 -191
  152. data/test/acceptance/mocked_methods_dispatch_test.rb +0 -75
  153. data/test/acceptance/multiple_expectations_failure_message_test.rb +0 -66
  154. data/test/acceptance/multiple_yielding_test.rb +0 -59
  155. data/test/acceptance/optional_parameters_test.rb +0 -67
  156. data/test/acceptance/parameter_matcher_test.rb +0 -299
  157. data/test/acceptance/partial_mocks_test.rb +0 -44
  158. data/test/acceptance/prepend_test.rb +0 -86
  159. data/test/acceptance/prevent_use_of_mocha_outside_test_test.rb +0 -76
  160. data/test/acceptance/raise_exception_test.rb +0 -36
  161. data/test/acceptance/return_value_test.rb +0 -49
  162. data/test/acceptance/sequence_test.rb +0 -189
  163. data/test/acceptance/states_test.rb +0 -71
  164. data/test/acceptance/stub_any_instance_method_defined_on_superclass_test.rb +0 -64
  165. data/test/acceptance/stub_any_instance_method_test.rb +0 -301
  166. data/test/acceptance/stub_class_method_defined_on_active_record_association_proxy_test.rb +0 -105
  167. data/test/acceptance/stub_class_method_defined_on_class_test.rb +0 -78
  168. data/test/acceptance/stub_class_method_defined_on_module_test.rb +0 -73
  169. data/test/acceptance/stub_class_method_defined_on_superclass_test.rb +0 -144
  170. data/test/acceptance/stub_everything_test.rb +0 -53
  171. data/test/acceptance/stub_instance_method_defined_on_active_record_association_proxy_test.rb +0 -91
  172. data/test/acceptance/stub_instance_method_defined_on_class_and_aliased_test.rb +0 -67
  173. data/test/acceptance/stub_instance_method_defined_on_class_test.rb +0 -67
  174. data/test/acceptance/stub_instance_method_defined_on_kernel_module_test.rb +0 -136
  175. data/test/acceptance/stub_instance_method_defined_on_module_test.rb +0 -76
  176. data/test/acceptance/stub_instance_method_defined_on_object_class_test.rb +0 -75
  177. data/test/acceptance/stub_instance_method_defined_on_singleton_class_test.rb +0 -67
  178. data/test/acceptance/stub_instance_method_defined_on_superclass_test.rb +0 -70
  179. data/test/acceptance/stub_method_defined_on_module_and_aliased_test.rb +0 -38
  180. data/test/acceptance/stub_module_method_test.rb +0 -200
  181. data/test/acceptance/stub_test.rb +0 -49
  182. data/test/acceptance/stubba_example_test.rb +0 -103
  183. data/test/acceptance/stubba_test_result_test.rb +0 -71
  184. data/test/acceptance/stubbing_error_backtrace_test.rb +0 -63
  185. data/test/acceptance/stubbing_frozen_object_test.rb +0 -88
  186. data/test/acceptance/stubbing_method_accepting_block_parameter_test.rb +0 -52
  187. data/test/acceptance/stubbing_method_unnecessarily_test.rb +0 -63
  188. data/test/acceptance/stubbing_nil_test.rb +0 -60
  189. data/test/acceptance/stubbing_non_existent_any_instance_method_test.rb +0 -157
  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 -145
  192. data/test/acceptance/stubbing_non_public_any_instance_method_test.rb +0 -128
  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 -141
  195. data/test/acceptance/stubbing_on_non_mock_object_test.rb +0 -70
  196. data/test/acceptance/stubbing_same_class_method_on_parent_and_child_classes_test.rb +0 -33
  197. data/test/acceptance/throw_test.rb +0 -42
  198. data/test/acceptance/unexpected_invocation_test.rb +0 -23
  199. data/test/acceptance/unstubbing_test.rb +0 -194
  200. data/test/acceptance/yielding_test.rb +0 -80
  201. data/test/assertions.rb +0 -8
  202. data/test/deprecation_disabler.rb +0 -15
  203. data/test/execution_point.rb +0 -36
  204. data/test/integration/mini_test_test.rb +0 -8
  205. data/test/integration/shared_tests.rb +0 -178
  206. data/test/integration/test_unit_test.rb +0 -8
  207. data/test/method_definer.rb +0 -16
  208. data/test/mini_test_result.rb +0 -96
  209. data/test/minitest_result.rb +0 -48
  210. data/test/simple_counter.rb +0 -11
  211. data/test/test_helper.rb +0 -58
  212. data/test/test_runner.rb +0 -58
  213. data/test/test_unit_result.rb +0 -22
  214. data/test/unit/any_instance_method_test.rb +0 -175
  215. data/test/unit/array_inspect_test.rb +0 -14
  216. data/test/unit/backtrace_filter_test.rb +0 -17
  217. data/test/unit/cardinality_test.rb +0 -72
  218. data/test/unit/central_test.rb +0 -98
  219. data/test/unit/change_state_side_effect_test.rb +0 -37
  220. data/test/unit/class_methods_test.rb +0 -69
  221. data/test/unit/configuration_test.rb +0 -37
  222. data/test/unit/date_time_inspect_test.rb +0 -19
  223. data/test/unit/exception_raiser_test.rb +0 -45
  224. data/test/unit/expectation_list_test.rb +0 -82
  225. data/test/unit/expectation_test.rb +0 -504
  226. data/test/unit/hash_inspect_test.rb +0 -14
  227. data/test/unit/hooks_test.rb +0 -35
  228. data/test/unit/in_state_ordering_constraint_test.rb +0 -39
  229. data/test/unit/instance_method_test.rb +0 -282
  230. data/test/unit/method_matcher_test.rb +0 -26
  231. data/test/unit/mock_test.rb +0 -372
  232. data/test/unit/mockery_test.rb +0 -171
  233. data/test/unit/module_methods_test.rb +0 -16
  234. data/test/unit/object_inspect_test.rb +0 -60
  235. data/test/unit/object_methods_test.rb +0 -63
  236. data/test/unit/parameter_matchers/all_of_test.rb +0 -24
  237. data/test/unit/parameter_matchers/any_of_test.rb +0 -24
  238. data/test/unit/parameter_matchers/anything_test.rb +0 -19
  239. data/test/unit/parameter_matchers/equals_test.rb +0 -23
  240. data/test/unit/parameter_matchers/equivalent_uri_test.rb +0 -41
  241. data/test/unit/parameter_matchers/has_entries_test.rb +0 -51
  242. data/test/unit/parameter_matchers/has_entry_test.rb +0 -128
  243. data/test/unit/parameter_matchers/has_key_test.rb +0 -54
  244. data/test/unit/parameter_matchers/has_value_test.rb +0 -55
  245. data/test/unit/parameter_matchers/includes_test.rb +0 -106
  246. data/test/unit/parameter_matchers/instance_of_test.rb +0 -23
  247. data/test/unit/parameter_matchers/is_a_test.rb +0 -23
  248. data/test/unit/parameter_matchers/kind_of_test.rb +0 -23
  249. data/test/unit/parameter_matchers/not_test.rb +0 -24
  250. data/test/unit/parameter_matchers/regexp_matches_test.rb +0 -45
  251. data/test/unit/parameter_matchers/responds_with_test.rb +0 -38
  252. data/test/unit/parameter_matchers/stub_matcher.rb +0 -23
  253. data/test/unit/parameter_matchers/yaml_equivalent_test.rb +0 -23
  254. data/test/unit/parameters_matcher_test.rb +0 -119
  255. data/test/unit/receivers_test.rb +0 -96
  256. data/test/unit/return_values_test.rb +0 -66
  257. data/test/unit/sequence_test.rb +0 -100
  258. data/test/unit/single_return_value_test.rb +0 -17
  259. data/test/unit/state_machine_test.rb +0 -96
  260. data/test/unit/string_inspect_test.rb +0 -9
  261. data/test/unit/thrower_test.rb +0 -23
  262. data/test/unit/yield_parameters_test.rb +0 -73
@@ -1,49 +1,26 @@
1
1
  require 'mocha/debug'
2
-
3
2
  require 'mocha/detection/test_unit'
4
-
5
- require 'mocha/integration/test_unit/nothing'
6
- require 'mocha/integration/test_unit/ruby_version_185_and_below'
7
- require 'mocha/integration/test_unit/ruby_version_186_and_above'
8
- require 'mocha/integration/test_unit/gem_version_200'
9
- require 'mocha/integration/test_unit/gem_version_201_to_202'
10
- require 'mocha/integration/test_unit/gem_version_203_to_220'
11
- require 'mocha/integration/test_unit/gem_version_230_to_250'
12
3
  require 'mocha/integration/test_unit/adapter'
13
4
 
14
- require 'mocha/deprecation'
15
-
16
5
  module Mocha
17
6
  module Integration
18
7
  module TestUnit
19
8
  def self.activate
20
- return false unless Detection::TestUnit.testcase
21
- test_unit_version = Gem::Version.new(Detection::TestUnit.version)
22
- ruby_version = Gem::Version.new(RUBY_VERSION.dup)
9
+ target = Detection::TestUnit.testcase
10
+ return false unless target
23
11
 
24
- Debug.puts "Detected Ruby version: #{ruby_version}"
12
+ test_unit_version = Gem::Version.new(Detection::TestUnit.version)
25
13
  Debug.puts "Detected Test::Unit version: #{test_unit_version}"
26
14
 
27
- integration_module = [
28
- TestUnit::Adapter,
29
- TestUnit::GemVersion230To250,
30
- TestUnit::GemVersion203To220,
31
- TestUnit::GemVersion201To202,
32
- TestUnit::GemVersion200,
33
- TestUnit::RubyVersion186AndAbove,
34
- TestUnit::RubyVersion185AndBelow,
35
- TestUnit::Nothing
36
- ].detect { |m| m.applicable_to?(test_unit_version, ruby_version) }
15
+ unless TestUnit::Adapter.applicable_to?(test_unit_version)
16
+ raise 'Versions of test-unit earlier than v2.5.1 are not supported.'
17
+ end
37
18
 
38
- unless ::Test::Unit::TestCase < integration_module
39
- unless integration_module == TestUnit::Adapter
40
- Deprecation.warning(
41
- 'Versions of test-unit earlier than v2.5.1 will not be supported in future versions of Mocha.'
42
- )
43
- end
44
- Debug.puts "Applying #{integration_module.description}"
45
- ::Test::Unit::TestCase.send(:include, integration_module)
19
+ unless target < TestUnit::Adapter
20
+ Debug.puts "Applying #{TestUnit::Adapter.description}"
21
+ target.send(:include, TestUnit::Adapter)
46
22
  end
23
+
47
24
  true
48
25
  end
49
26
  end
@@ -3,14 +3,12 @@ require 'mocha/raised_exception'
3
3
  require 'mocha/return_values'
4
4
  require 'mocha/thrown_object'
5
5
  require 'mocha/yield_parameters'
6
- require 'mocha/configuration'
7
- require 'mocha/deprecation'
8
6
 
9
7
  module Mocha
10
8
  class Invocation
11
9
  attr_reader :method_name, :block
12
10
 
13
- def initialize(mock, method_name, *arguments, &block)
11
+ def initialize(mock, method_name, arguments = [], block = nil)
14
12
  @mock = mock
15
13
  @method_name = method_name
16
14
  @arguments = arguments
@@ -22,18 +20,8 @@ module Mocha
22
20
  def call(yield_parameters = YieldParameters.new, return_values = ReturnValues.new)
23
21
  yield_parameters.next_invocation.each do |yield_args|
24
22
  @yields << ParametersMatcher.new(yield_args)
25
- if @block
26
- @block.call(*yield_args)
27
- else
28
- raise LocalJumpError unless Mocha.configuration.reinstate_undocumented_behaviour_from_v1_9?
29
- yield_args_description = ParametersMatcher.new(yield_args).mocha_inspect
30
- Deprecation.warning(
31
- "Stubbed method was instructed to yield #{yield_args_description}, but no block was given by invocation: #{call_description}.",
32
- ' This will raise a LocalJumpError in the future.',
33
- ' Use Expectation#with_block_given to constrain this expectation to match invocations supplying a block.',
34
- ' And, if necessary, add another expectation to match invocations not supplying a block.'
35
- )
36
- end
23
+ raise LocalJumpError unless @block
24
+ @block.call(*yield_args)
37
25
  end
38
26
  return_values.next(self)
39
27
  end
@@ -55,7 +43,7 @@ module Mocha
55
43
  end
56
44
 
57
45
  def call_description
58
- description = "#{@mock.mocha_inspect}.#{@method_name}#{ParametersMatcher.new(@arguments).mocha_inspect}"
46
+ description = "#{@mock.mocha_inspect}.#{@method_name}#{argument_description}"
59
47
  description << ' { ... }' unless @block.nil?
60
48
  description
61
49
  end
@@ -73,5 +61,13 @@ module Mocha
73
61
  def full_description
74
62
  "\n - #{call_description} #{result_description}"
75
63
  end
64
+
65
+ private
66
+
67
+ def argument_description
68
+ signature = arguments.mocha_inspect
69
+ signature = signature.gsub(/^\[|\]$/, '')
70
+ "(#{signature})"
71
+ end
76
72
  end
77
73
  end
@@ -1,8 +1,6 @@
1
+ require 'mocha/ruby_version'
1
2
  require 'mocha/integration/mini_test'
2
- require 'mocha/deprecation'
3
3
 
4
4
  unless Mocha::Integration::MiniTest.activate
5
- Mocha::Deprecation.warning(
6
- "MiniTest must be loaded *before* `require 'mocha/minitest'`."
7
- )
5
+ raise "MiniTest must be loaded *before* `require 'mocha/minitest'`."
8
6
  end
data/lib/mocha/mock.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'mocha/singleton_class'
1
+ require 'ruby2_keywords'
2
2
  require 'mocha/expectation'
3
3
  require 'mocha/expectation_list'
4
4
  require 'mocha/invocation'
@@ -8,7 +8,6 @@ require 'mocha/method_matcher'
8
8
  require 'mocha/parameters_matcher'
9
9
  require 'mocha/argument_iterator'
10
10
  require 'mocha/expectation_error_factory'
11
- require 'mocha/ruby_version'
12
11
 
13
12
  module Mocha
14
13
  # Traditional mock object.
@@ -109,6 +108,7 @@ module Mocha
109
108
  # object.expects(:expected_method_one).returns(:result_one)
110
109
  # object.expects(:expected_method_two).returns(:result_two)
111
110
  def expects(method_name_or_hash, backtrace = nil)
111
+ expectation = nil
112
112
  iterator = ArgumentIterator.new(method_name_or_hash)
113
113
  iterator.each do |*args|
114
114
  method_name = args.shift
@@ -117,6 +117,7 @@ module Mocha
117
117
  expectation.returns(args.shift) unless args.empty?
118
118
  @expectations.add(expectation)
119
119
  end
120
+ expectation
120
121
  end
121
122
 
122
123
  # Adds an expectation that the specified method may be called any number of times with any parameters.
@@ -145,6 +146,7 @@ module Mocha
145
146
  # object.stubs(:stubbed_method_one).returns(:result_one)
146
147
  # object.stubs(:stubbed_method_two).returns(:result_two)
147
148
  def stubs(method_name_or_hash, backtrace = nil)
149
+ expectation = nil
148
150
  iterator = ArgumentIterator.new(method_name_or_hash)
149
151
  iterator.each do |*args|
150
152
  method_name = args.shift
@@ -154,6 +156,7 @@ module Mocha
154
156
  expectation.returns(args.shift) unless args.empty?
155
157
  @expectations.add(expectation)
156
158
  end
159
+ expectation
157
160
  end
158
161
 
159
162
  # Removes the specified stubbed methods (added by calls to {#expects} or {#stubs}) and all expectations associated with them.
@@ -161,7 +164,7 @@ module Mocha
161
164
  # @param [Array<Symbol>] method_names names of methods to unstub.
162
165
  #
163
166
  # @example Invoking an unstubbed method causes error to be raised
164
- # object = mock('mock') do
167
+ # object = mock('mock')
165
168
  # object.stubs(:stubbed_method).returns(:result_one)
166
169
  # object.stubbed_method # => :result_one
167
170
  # object.unstub(:stubbed_method)
@@ -306,10 +309,18 @@ module Mocha
306
309
  end
307
310
 
308
311
  # @private
309
- def method_missing(symbol, *arguments, &block) # rubocop:disable Style/MethodMissingSuper
312
+ # rubocop:disable Style/MethodMissingSuper
313
+ def method_missing(symbol, *arguments, &block)
314
+ handle_method_call(symbol, arguments, block)
315
+ end
316
+ ruby2_keywords(:method_missing)
317
+ # rubocop:enable Style/MethodMissingSuper
318
+
319
+ # @private
320
+ def handle_method_call(symbol, arguments, block)
310
321
  check_expiry
311
322
  check_responder_responds_to(symbol)
312
- invocation = Invocation.new(self, symbol, *arguments, &block)
323
+ invocation = Invocation.new(self, symbol, arguments, block)
313
324
  if (matching_expectation_allowing_invocation = all_expectations.match_allowing_invocation(invocation))
314
325
  matching_expectation_allowing_invocation.invoke(invocation)
315
326
  elsif (matching_expectation = all_expectations.match(invocation)) || (!matching_expectation && !@everything_stubbed)
@@ -318,25 +329,14 @@ module Mocha
318
329
  end
319
330
 
320
331
  # @private
321
- def respond_to_missing?(symbol, include_private = false)
332
+ def respond_to_missing?(symbol, include_all)
322
333
  if @responder
323
- if @responder.method(:respond_to?).arity > 1
324
- @responder.respond_to?(symbol, include_private)
325
- else
326
- @responder.respond_to?(symbol)
327
- end
334
+ @responder.respond_to?(symbol, include_all)
328
335
  else
329
336
  @everything_stubbed || all_expectations.matches_method?(symbol)
330
337
  end
331
338
  end
332
339
 
333
- # @private
334
- if PRE_RUBY_V19
335
- def respond_to?(symbol, include_private = false)
336
- respond_to_missing?(symbol, include_private)
337
- end
338
- end
339
-
340
340
  # @private
341
341
  def __verified__?(assertion_counter = nil)
342
342
  @expectations.verified?(assertion_counter)
@@ -387,14 +387,14 @@ module Mocha
387
387
  end
388
388
 
389
389
  def check_expiry
390
- if @expired # rubocop:disable Style/GuardClause
391
- Deprecation.warning(
392
- "#{mocha_inspect} was instantiated in one test but it is receiving invocations within another test.",
393
- ' This can lead to unintended interactions between tests and hence unexpected test failures.',
394
- ' Ensure that every test correctly cleans up any state that it introduces.',
395
- ' A Mocha::StubbingError will be raised in this scenario in the future.'
396
- )
397
- end
390
+ return unless @expired
391
+
392
+ sentences = [
393
+ "#{mocha_inspect} was instantiated in one test but it is receiving invocations within another test.",
394
+ 'This can lead to unintended interactions between tests and hence unexpected test failures.',
395
+ 'Ensure that every test correctly cleans up any state that it introduces.'
396
+ ]
397
+ raise StubbingError.new(sentences.join(' '), caller)
398
398
  end
399
399
  end
400
400
  end
data/lib/mocha/mockery.rb CHANGED
@@ -1,4 +1,3 @@
1
- require 'mocha/ruby_version'
2
1
  require 'mocha/central'
3
2
  require 'mocha/mock'
4
3
  require 'mocha/names'
@@ -35,12 +34,13 @@ module Mocha
35
34
 
36
35
  class << self
37
36
  def instance
38
- instances.last || Null.new
37
+ @instances.last || Null.new
39
38
  end
40
39
 
41
40
  def setup
41
+ @instances ||= []
42
42
  mockery = new
43
- mockery.logger = instance.logger unless instances.empty?
43
+ mockery.logger = instance.logger unless @instances.empty?
44
44
  @instances.push(mockery)
45
45
  end
46
46
 
@@ -52,13 +52,6 @@ module Mocha
52
52
  instance.teardown
53
53
  ensure
54
54
  @instances.pop
55
- @instances = nil if instances.empty?
56
- end
57
-
58
- private
59
-
60
- def instances
61
- @instances ||= []
62
55
  end
63
56
  end
64
57
 
@@ -92,11 +85,9 @@ module Mocha
92
85
  end
93
86
  raise ExpectationErrorFactory.build(message, backtrace)
94
87
  end
95
- expectations.each do |e|
96
- unless Mocha.configuration.stubbing_method_unnecessarily == :allow
97
- next if e.used?
98
- on_stubbing_method_unnecessarily(e)
99
- end
88
+ expectations.reject(&:used?).each do |expectation|
89
+ signature_proc = lambda { expectation.method_signature }
90
+ check(:stubbing_method_unnecessarily, 'method unnecessarily', signature_proc, expectation.backtrace)
100
91
  end
101
92
  end
102
93
 
@@ -120,17 +111,16 @@ module Mocha
120
111
 
121
112
  def mocha_inspect
122
113
  message = ''
123
- message << "unsatisfied expectations:\n- #{unsatisfied_expectations.map(&:mocha_inspect).join("\n- ")}\n" unless unsatisfied_expectations.empty?
124
- message << "satisfied expectations:\n- #{satisfied_expectations.map(&:mocha_inspect).join("\n- ")}\n" unless satisfied_expectations.empty?
125
- message << "states:\n- #{state_machines.map(&:mocha_inspect).join("\n- ")}" unless state_machines.empty?
114
+ message << "unsatisfied expectations:\n- #{unsatisfied_expectations.map(&:mocha_inspect).join("\n- ")}\n" if unsatisfied_expectations.any?
115
+ message << "satisfied expectations:\n- #{satisfied_expectations.map(&:mocha_inspect).join("\n- ")}\n" if satisfied_expectations.any?
116
+ message << "states:\n- #{state_machines.map(&:mocha_inspect).join("\n- ")}\n" if state_machines.any?
126
117
  message
127
118
  end
128
119
 
129
120
  def on_stubbing(object, method)
130
- method = PRE_RUBY_V19 ? method.to_s : method.to_sym
131
121
  signature_proc = lambda { "#{object.mocha_inspect}.#{method}" }
132
122
  check(:stubbing_non_existent_method, 'non-existent method', signature_proc) do
133
- !(object.stubba_class.__method_exists__?(method, true) || object.respond_to?(method.to_sym))
123
+ !(object.stubba_class.__method_exists__?(method, true) || object.respond_to?(method))
134
124
  end
135
125
  check(:stubbing_non_public_method, 'non-public method', signature_proc) do
136
126
  object.stubba_class.__method_exists__?(method, false)
@@ -139,11 +129,6 @@ module Mocha
139
129
  check(:stubbing_method_on_non_mock_object, 'method on non-mock object', signature_proc)
140
130
  end
141
131
 
142
- def on_stubbing_method_unnecessarily(expectation)
143
- signature_proc = lambda { expectation.method_signature }
144
- check(:stubbing_method_unnecessarily, 'method unnecessarily', signature_proc, expectation.backtrace)
145
- end
146
-
147
132
  attr_writer :logger
148
133
 
149
134
  def logger
@@ -3,7 +3,7 @@ module Mocha
3
3
  # @abstract Subclass and implement +#matches?+ and +#mocha_inspect+ to define a custom matcher. Also add a suitably named instance method to {ParameterMatchers} to build an instance of the new matcher c.f. {#equals}.
4
4
  class Base
5
5
  # @private
6
- def to_matcher
6
+ def to_matcher(_expectation = nil)
7
7
  self
8
8
  end
9
9
 
@@ -1,4 +1,3 @@
1
- require 'mocha/deprecation'
2
1
  require 'mocha/parameter_matchers/base'
3
2
  require 'uri'
4
3
  require 'cgi'
@@ -42,20 +42,10 @@ module Mocha
42
42
  #
43
43
  def has_entry(*options) # rubocop:disable Naming/PredicateName
44
44
  case options.length
45
+ when 0
46
+ raise ArgumentError, 'No arguments. Expecting at least one.'
45
47
  when 1
46
- case options[0]
47
- when Hash
48
- case options[0].length
49
- when 0
50
- raise ArgumentError, 'Argument has no entries.'
51
- when 1
52
- key, value = options[0].first
53
- else
54
- raise ArgumentError, 'Argument has multiple entries. Use Mocha::ParameterMatchers#has_entries instead.'
55
- end
56
- else
57
- raise ArgumentError, 'Argument is not a Hash.'
58
- end
48
+ key, value = parse_option(options[0])
59
49
  when 2
60
50
  key, value = options
61
51
  else
@@ -85,5 +75,24 @@ module Mocha
85
75
  "has_entry(#{@key.mocha_inspect} => #{@value.mocha_inspect})"
86
76
  end
87
77
  end
78
+
79
+ private
80
+
81
+ # @private
82
+ def parse_option(option)
83
+ case option
84
+ when Hash
85
+ case option.length
86
+ when 0
87
+ raise ArgumentError, 'Argument has no entries.'
88
+ when 1
89
+ option.first
90
+ else
91
+ raise ArgumentError, 'Argument has multiple entries. Use Mocha::ParameterMatchers#has_entries instead.'
92
+ end
93
+ else
94
+ raise ArgumentError, 'Argument is not a Hash.'
95
+ end
96
+ end
88
97
  end
89
98
  end
@@ -0,0 +1,53 @@
1
+ require 'mocha/parameter_matchers/base'
2
+
3
+ module Mocha
4
+ module ParameterMatchers
5
+ # Matches +Hash+ containing +keys+.
6
+ #
7
+ # @param [*Array<Object>] keys expected keys.
8
+ # @return [HasKeys] parameter matcher.
9
+ #
10
+ # @see Expectation#with
11
+ #
12
+ # @example Actual parameter contains entry with expected keys.
13
+ # object = mock()
14
+ # object.expects(:method_1).with(has_keys(:key_1, :key_2))
15
+ # object.method_1(:key_1 => 1, :key_2 => 2, :key_3 => 3)
16
+ # # no error raised
17
+ #
18
+ # @example Actual parameter does not contain all expected keys.
19
+ # object = mock()
20
+ # object.expects(:method_1).with(has_keys(:key_1, :key_2))
21
+ # object.method_1(:key_2 => 2)
22
+ # # error raised, because method_1 was not called with Hash containing key: :key_1
23
+ #
24
+ def has_keys(*keys) # rubocop:disable Naming/PredicateName
25
+ HasKeys.new(*keys)
26
+ end
27
+
28
+ # Parameter matcher which matches when actual parameter contains +Hash+ with all expected keys.
29
+ class HasKeys < Base
30
+ # @private
31
+ def initialize(*keys)
32
+ raise ArgumentError, 'No arguments. Expecting at least one.' if keys.empty?
33
+
34
+ @keys = keys
35
+ end
36
+
37
+ # @private
38
+ def matches?(available_parameters)
39
+ parameter = available_parameters.shift
40
+ return false unless parameter.respond_to?(:keys)
41
+
42
+ @keys.map(&:to_matcher).all? do |matcher|
43
+ parameter.keys.any? { |key| matcher.matches?([key]) }
44
+ end
45
+ end
46
+
47
+ # @private
48
+ def mocha_inspect
49
+ "has_keys(#{@keys.mocha_inspect(false)})"
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,11 +1,12 @@
1
1
  require 'mocha/parameter_matchers/equals'
2
+ require 'mocha/parameter_matchers/positional_or_keyword_hash'
2
3
 
3
4
  module Mocha
4
5
  module ParameterMatchers
5
6
  # @private
6
7
  module InstanceMethods
7
8
  # @private
8
- def to_matcher
9
+ def to_matcher(_expectation = nil)
9
10
  Mocha::ParameterMatchers::Equals.new(self)
10
11
  end
11
12
  end
@@ -16,3 +17,11 @@ end
16
17
  class Object
17
18
  include Mocha::ParameterMatchers::InstanceMethods
18
19
  end
20
+
21
+ # @private
22
+ class Hash
23
+ # @private
24
+ def to_matcher(expectation = nil)
25
+ Mocha::ParameterMatchers::PositionalOrKeywordHash.new(self, expectation)
26
+ end
27
+ end
@@ -0,0 +1,64 @@
1
+ require 'mocha/configuration'
2
+ require 'mocha/deprecation'
3
+ require 'mocha/parameter_matchers/base'
4
+
5
+ module Mocha
6
+ module ParameterMatchers
7
+ # @private
8
+ class PositionalOrKeywordHash < Base
9
+ def initialize(value, expectation)
10
+ @value = value
11
+ @expectation = expectation
12
+ end
13
+
14
+ def matches?(available_parameters)
15
+ parameter, is_last_parameter = extract_parameter(available_parameters)
16
+ return false unless parameter == @value
17
+
18
+ if is_last_parameter && !same_type_of_hash?(parameter, @value)
19
+ return false if Mocha.configuration.strict_keyword_argument_matching?
20
+
21
+ deprecation_warning(parameter, @value) if Mocha::RUBY_V27_PLUS
22
+ end
23
+
24
+ true
25
+ end
26
+
27
+ def mocha_inspect
28
+ @value.mocha_inspect
29
+ end
30
+
31
+ private
32
+
33
+ def extract_parameter(available_parameters)
34
+ [available_parameters.shift, available_parameters.empty?]
35
+ end
36
+
37
+ def same_type_of_hash?(actual, expected)
38
+ ruby2_keywords_hash?(actual) == ruby2_keywords_hash?(expected)
39
+ end
40
+
41
+ def deprecation_warning(actual, expected)
42
+ details1 = "Expectation #{expectation_definition} expected #{hash_type(expected)} (#{expected.mocha_inspect}),".squeeze(' ')
43
+ details2 = "but received #{hash_type(actual)} (#{actual.mocha_inspect})."
44
+ sentence1 = 'These will stop matching when strict keyword argument matching is enabled.'
45
+ sentence2 = 'See the documentation for Mocha::Configuration#strict_keyword_argument_matching=.'
46
+ Deprecation.warning([details1, details2, sentence1, sentence2].join(' '))
47
+ end
48
+
49
+ def hash_type(hash)
50
+ ruby2_keywords_hash?(hash) ? 'keyword arguments' : 'positional hash'
51
+ end
52
+
53
+ def ruby2_keywords_hash?(hash)
54
+ hash.is_a?(Hash) && ::Hash.ruby2_keywords_hash?(hash)
55
+ end
56
+
57
+ def expectation_definition
58
+ return nil unless @expectation
59
+
60
+ "defined at #{@expectation.definition_location}"
61
+ end
62
+ end
63
+ end
64
+ end
@@ -13,6 +13,7 @@ require 'mocha/parameter_matchers/equals'
13
13
  require 'mocha/parameter_matchers/has_entry'
14
14
  require 'mocha/parameter_matchers/has_entries'
15
15
  require 'mocha/parameter_matchers/has_key'
16
+ require 'mocha/parameter_matchers/has_keys'
16
17
  require 'mocha/parameter_matchers/has_value'
17
18
  require 'mocha/parameter_matchers/includes'
18
19
  require 'mocha/parameter_matchers/instance_of'
@@ -3,8 +3,9 @@ require 'mocha/parameter_matchers'
3
3
 
4
4
  module Mocha
5
5
  class ParametersMatcher
6
- def initialize(expected_parameters = [ParameterMatchers::AnyParameters.new], &matching_block)
6
+ def initialize(expected_parameters = [ParameterMatchers::AnyParameters.new], expectation = nil, &matching_block)
7
7
  @expected_parameters = expected_parameters
8
+ @expectation = expectation
8
9
  @matching_block = matching_block
9
10
  end
10
11
 
@@ -23,12 +24,11 @@ module Mocha
23
24
  def mocha_inspect
24
25
  signature = matchers.mocha_inspect
25
26
  signature = signature.gsub(/^\[|\]$/, '')
26
- signature = signature.gsub(/^\{|\}$/, '') if matchers.length == 1
27
27
  "(#{signature})"
28
28
  end
29
29
 
30
30
  def matchers
31
- @expected_parameters.map(&:to_matcher)
31
+ @expected_parameters.map { |p| p.to_matcher(@expectation) }
32
32
  end
33
33
  end
34
34
  end
@@ -1,4 +1,3 @@
1
1
  module Mocha
2
- PRE_RUBY_V19 = Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('1.9')
3
- RUBY_V2_PLUS = Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2')
2
+ RUBY_V27_PLUS = Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.7')
4
3
  end