mocha 1.8.0 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (218) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.rubocop.yml +3 -0
  4. data/.rubocop_todo.yml +7 -30
  5. data/.yardopts +1 -0
  6. data/README.md +40 -13
  7. data/RELEASE.md +97 -0
  8. data/Rakefile +10 -7
  9. data/bin/build-matrix +1 -2
  10. data/docs/CNAME +1 -1
  11. data/docs/Mocha.html +132 -5
  12. data/docs/Mocha/API.html +437 -206
  13. data/docs/Mocha/ClassMethods.html +13 -16
  14. data/docs/Mocha/Configuration.html +1126 -227
  15. data/docs/Mocha/Expectation.html +420 -267
  16. data/docs/Mocha/ExpectationError.html +5 -10
  17. data/docs/Mocha/ExpectationErrorFactory.html +9 -18
  18. data/docs/Mocha/Hooks.html +12 -27
  19. data/docs/Mocha/Integration.html +3 -3
  20. data/docs/Mocha/Integration/MiniTest.html +3 -3
  21. data/docs/Mocha/Integration/MiniTest/Adapter.html +5 -6
  22. data/docs/Mocha/Integration/TestUnit.html +3 -3
  23. data/docs/Mocha/Integration/TestUnit/Adapter.html +5 -6
  24. data/docs/Mocha/Mock.html +202 -162
  25. data/docs/Mocha/ObjectMethods.html +121 -68
  26. data/docs/Mocha/ParameterMatchers.html +21 -109
  27. data/docs/Mocha/ParameterMatchers/AllOf.html +4 -5
  28. data/docs/Mocha/ParameterMatchers/AnyOf.html +4 -5
  29. data/docs/Mocha/ParameterMatchers/AnyParameters.html +3 -3
  30. data/docs/Mocha/ParameterMatchers/Anything.html +3 -3
  31. data/docs/Mocha/ParameterMatchers/Base.html +8 -15
  32. data/docs/Mocha/ParameterMatchers/Equals.html +4 -5
  33. data/docs/Mocha/ParameterMatchers/EquivalentUri.html +3 -3
  34. data/docs/Mocha/ParameterMatchers/HasEntries.html +4 -5
  35. data/docs/Mocha/ParameterMatchers/HasEntry.html +4 -5
  36. data/docs/Mocha/ParameterMatchers/HasKey.html +4 -5
  37. data/docs/Mocha/ParameterMatchers/HasValue.html +4 -5
  38. data/docs/Mocha/ParameterMatchers/Includes.html +4 -5
  39. data/docs/Mocha/ParameterMatchers/InstanceOf.html +4 -5
  40. data/docs/Mocha/ParameterMatchers/IsA.html +3 -3
  41. data/docs/Mocha/ParameterMatchers/KindOf.html +4 -5
  42. data/docs/Mocha/ParameterMatchers/Not.html +4 -5
  43. data/docs/Mocha/ParameterMatchers/Optionally.html +3 -3
  44. data/docs/Mocha/ParameterMatchers/RegexpMatches.html +4 -5
  45. data/docs/Mocha/ParameterMatchers/RespondsWith.html +4 -5
  46. data/docs/Mocha/ParameterMatchers/YamlEquivalent.html +4 -5
  47. data/docs/Mocha/Sequence.html +3 -3
  48. data/docs/Mocha/StateMachine.html +13 -25
  49. data/docs/Mocha/StateMachine/State.html +4 -5
  50. data/docs/Mocha/StateMachine/StatePredicate.html +4 -5
  51. data/docs/Mocha/StubbingError.html +3 -3
  52. data/docs/_index.html +4 -22
  53. data/docs/class_list.html +1 -1
  54. data/docs/file.COPYING.html +3 -3
  55. data/docs/file.MIT-LICENSE.html +3 -3
  56. data/docs/file.README.html +46 -16
  57. data/docs/file.RELEASE.html +130 -3
  58. data/docs/frames.html +1 -1
  59. data/docs/index.html +46 -16
  60. data/docs/js/app.js +11 -0
  61. data/docs/method_list.html +117 -37
  62. data/docs/top-level-namespace.html +3 -3
  63. data/gemfiles/Gemfile.minitest.5.11.3 +7 -0
  64. data/init.rb +1 -3
  65. data/lib/mocha.rb +8 -0
  66. data/lib/mocha/any_instance_method.rb +11 -53
  67. data/lib/mocha/api.rb +120 -56
  68. data/lib/mocha/block_matcher.rb +31 -0
  69. data/lib/mocha/cardinality.rb +26 -11
  70. data/lib/mocha/class_methods.rb +17 -15
  71. data/lib/mocha/configuration.rb +351 -67
  72. data/lib/mocha/deprecation.rb +2 -1
  73. data/lib/mocha/detection/test_unit.rb +1 -3
  74. data/lib/mocha/exception_raiser.rb +2 -1
  75. data/lib/mocha/expectation.rb +102 -63
  76. data/lib/mocha/expectation_error.rb +1 -3
  77. data/lib/mocha/expectation_list.rb +6 -6
  78. data/lib/mocha/inspect.rb +28 -26
  79. data/lib/mocha/instance_method.rb +19 -2
  80. data/lib/mocha/integration.rb +1 -3
  81. data/lib/mocha/integration/mini_test.rb +7 -0
  82. data/lib/mocha/integration/test_unit.rb +7 -0
  83. data/lib/mocha/invocation.rb +77 -0
  84. data/lib/mocha/macos_version.rb +5 -0
  85. data/lib/mocha/minitest.rb +6 -1
  86. data/lib/mocha/mock.rb +46 -31
  87. data/lib/mocha/mockery.rb +25 -61
  88. data/lib/mocha/names.rb +1 -1
  89. data/lib/mocha/object_methods.rb +13 -19
  90. data/lib/mocha/parameter_matchers.rb +1 -1
  91. data/lib/mocha/parameter_matchers/all_of.rb +1 -1
  92. data/lib/mocha/parameter_matchers/any_of.rb +1 -1
  93. data/lib/mocha/parameter_matchers/equivalent_uri.rb +0 -9
  94. data/lib/mocha/parameter_matchers/includes.rb +2 -0
  95. data/lib/mocha/parameter_matchers/instance_methods.rb +18 -0
  96. data/lib/mocha/raised_exception.rb +11 -0
  97. data/lib/mocha/return_values.rb +3 -3
  98. data/lib/mocha/setup.rb +5 -0
  99. data/lib/mocha/single_return_value.rb +2 -1
  100. data/lib/mocha/singleton_class.rb +9 -0
  101. data/lib/mocha/stubbed_method.rb +127 -0
  102. data/lib/mocha/test_unit.rb +6 -1
  103. data/lib/mocha/thrower.rb +2 -1
  104. data/lib/mocha/thrown_object.rb +12 -0
  105. data/lib/mocha/version.rb +1 -1
  106. data/lib/mocha/yield_parameters.rb +5 -11
  107. data/mocha.gemspec +1 -3
  108. data/test/acceptance/acceptance_test_helper.rb +7 -0
  109. data/test/acceptance/bug_18914_test.rb +0 -1
  110. data/test/acceptance/bug_21465_test.rb +0 -1
  111. data/test/acceptance/bug_21563_test.rb +0 -1
  112. data/test/acceptance/display_matching_invocations_alongside_expectations_test.rb +69 -0
  113. data/test/acceptance/exception_rescue_test.rb +1 -2
  114. data/test/acceptance/expectations_on_multiple_methods_test.rb +0 -1
  115. data/test/acceptance/expected_invocation_count_test.rb +2 -3
  116. data/test/acceptance/failure_messages_test.rb +16 -1
  117. data/test/acceptance/issue_272_test.rb +1 -2
  118. data/test/acceptance/issue_65_test.rb +0 -1
  119. data/test/acceptance/issue_70_test.rb +0 -1
  120. data/test/acceptance/mocha_example_test.rb +0 -1
  121. data/test/acceptance/mocha_test_result_test.rb +0 -1
  122. data/test/acceptance/mock_built_with_first_argument_type_being_string_test.rb +99 -0
  123. data/test/acceptance/mock_test.rb +47 -6
  124. data/test/acceptance/mocked_methods_dispatch_test.rb +0 -1
  125. data/test/acceptance/multiple_expectations_failure_message_test.rb +0 -1
  126. data/test/acceptance/multiple_yielding_test.rb +56 -0
  127. data/test/acceptance/optional_parameters_test.rb +0 -1
  128. data/test/acceptance/parameter_matcher_test.rb +0 -1
  129. data/test/acceptance/partial_mocks_test.rb +0 -1
  130. data/test/acceptance/prepend_test.rb +0 -1
  131. data/test/acceptance/prevent_use_of_mocha_outside_test_test.rb +0 -1
  132. data/test/acceptance/raise_exception_test.rb +0 -1
  133. data/test/acceptance/return_value_test.rb +0 -1
  134. data/test/acceptance/sequence_test.rb +0 -1
  135. data/test/acceptance/states_test.rb +0 -1
  136. data/test/acceptance/stub_any_instance_method_defined_on_superclass_test.rb +1 -2
  137. data/test/acceptance/stub_any_instance_method_test.rb +20 -1
  138. data/test/acceptance/stub_class_method_defined_on_active_record_association_proxy_test.rb +0 -1
  139. data/test/acceptance/stub_class_method_defined_on_class_test.rb +0 -1
  140. data/test/acceptance/stub_class_method_defined_on_module_test.rb +0 -1
  141. data/test/acceptance/stub_class_method_defined_on_superclass_test.rb +1 -2
  142. data/test/acceptance/stub_everything_test.rb +0 -1
  143. data/test/acceptance/stub_instance_method_defined_on_active_record_association_proxy_test.rb +0 -1
  144. data/test/acceptance/stub_instance_method_defined_on_class_and_aliased_test.rb +0 -1
  145. data/test/acceptance/stub_instance_method_defined_on_class_test.rb +0 -1
  146. data/test/acceptance/stub_instance_method_defined_on_kernel_module_test.rb +0 -1
  147. data/test/acceptance/stub_instance_method_defined_on_module_test.rb +0 -1
  148. data/test/acceptance/stub_instance_method_defined_on_object_class_test.rb +0 -1
  149. data/test/acceptance/stub_instance_method_defined_on_singleton_class_test.rb +0 -1
  150. data/test/acceptance/stub_instance_method_defined_on_superclass_test.rb +0 -1
  151. data/test/acceptance/stub_method_defined_on_module_and_aliased_test.rb +0 -1
  152. data/test/acceptance/stub_module_method_test.rb +0 -1
  153. data/test/acceptance/stub_test.rb +0 -1
  154. data/test/acceptance/stubba_example_test.rb +0 -1
  155. data/test/acceptance/stubba_test_result_test.rb +0 -1
  156. data/test/acceptance/stubbing_error_backtrace_test.rb +4 -5
  157. data/test/acceptance/stubbing_frozen_object_test.rb +0 -1
  158. data/test/acceptance/stubbing_method_accepting_block_parameter_test.rb +0 -1
  159. data/test/acceptance/stubbing_method_unnecessarily_test.rb +5 -5
  160. data/test/acceptance/stubbing_nil_test.rb +5 -5
  161. data/test/acceptance/stubbing_non_existent_any_instance_method_test.rb +27 -11
  162. data/test/acceptance/stubbing_non_existent_class_method_test.rb +11 -11
  163. data/test/acceptance/stubbing_non_existent_instance_method_test.rb +11 -11
  164. data/test/acceptance/stubbing_non_public_any_instance_method_test.rb +8 -8
  165. data/test/acceptance/stubbing_non_public_class_method_test.rb +9 -9
  166. data/test/acceptance/stubbing_non_public_instance_method_test.rb +9 -9
  167. data/test/acceptance/stubbing_on_non_mock_object_test.rb +5 -5
  168. data/test/acceptance/stubbing_same_class_method_on_parent_and_child_classes_test.rb +0 -1
  169. data/test/acceptance/throw_test.rb +0 -1
  170. data/test/acceptance/unexpected_invocation_test.rb +0 -1
  171. data/test/acceptance/unstubbing_test.rb +0 -1
  172. data/test/acceptance/yielding_test.rb +78 -0
  173. data/test/integration/shared_tests.rb +5 -3
  174. data/test/method_definer.rb +11 -17
  175. data/test/test_runner.rb +2 -0
  176. data/test/unit/any_instance_method_test.rb +60 -35
  177. data/test/unit/cardinality_test.rb +41 -23
  178. data/test/unit/central_test.rb +0 -1
  179. data/test/unit/class_methods_test.rb +1 -1
  180. data/test/unit/configuration_test.rb +12 -12
  181. data/test/unit/exception_raiser_test.rb +10 -5
  182. data/test/unit/expectation_list_test.rb +13 -11
  183. data/test/unit/expectation_test.rb +117 -103
  184. data/test/unit/instance_method_test.rb +282 -0
  185. data/test/unit/mock_test.rb +28 -19
  186. data/test/unit/mockery_test.rb +8 -11
  187. data/test/unit/module_methods_test.rb +2 -3
  188. data/test/unit/object_inspect_test.rb +6 -4
  189. data/test/unit/object_methods_test.rb +3 -2
  190. data/test/unit/parameter_matchers/equivalent_uri_test.rb +0 -9
  191. data/test/unit/parameter_matchers/has_entries_test.rb +1 -1
  192. data/test/unit/parameter_matchers/has_entry_test.rb +1 -1
  193. data/test/unit/parameter_matchers/has_key_test.rb +1 -1
  194. data/test/unit/parameter_matchers/has_value_test.rb +1 -1
  195. data/test/unit/parameter_matchers/includes_test.rb +1 -1
  196. data/test/unit/parameter_matchers/responds_with_test.rb +1 -1
  197. data/test/unit/return_values_test.rb +25 -20
  198. data/test/unit/single_return_value_test.rb +6 -1
  199. data/test/unit/thrower_test.rb +7 -2
  200. data/test/unit/yield_parameters_test.rb +35 -53
  201. metadata +18 -35
  202. data/docs/Mocha/UnexpectedInvocation.html +0 -140
  203. data/lib/mocha/class_method.rb +0 -113
  204. data/lib/mocha/mini_test.rb +0 -5
  205. data/lib/mocha/module_method.rb +0 -6
  206. data/lib/mocha/module_methods.rb +0 -10
  207. data/lib/mocha/multiple_yields.rb +0 -15
  208. data/lib/mocha/no_yields.rb +0 -5
  209. data/lib/mocha/parameter_matchers/object.rb +0 -15
  210. data/lib/mocha/single_yield.rb +0 -13
  211. data/lib/mocha/standalone.rb +0 -4
  212. data/lib/mocha/unexpected_invocation.rb +0 -24
  213. data/lib/mocha_standalone.rb +0 -4
  214. data/test/acceptance/mock_with_initializer_block_test.rb +0 -56
  215. data/test/unit/class_method_test.rb +0 -254
  216. data/test/unit/multiple_yields_test.rb +0 -16
  217. data/test/unit/no_yields_test.rb +0 -16
  218. data/test/unit/single_yield_test.rb +0 -16
@@ -14,6 +14,8 @@ require 'mocha/integration/mini_test/version_2110_to_2111'
14
14
  require 'mocha/integration/mini_test/version_2112_to_320'
15
15
  require 'mocha/integration/mini_test/adapter'
16
16
 
17
+ require 'mocha/deprecation'
18
+
17
19
  module Mocha
18
20
  module Integration
19
21
  module MiniTest
@@ -39,6 +41,11 @@ module Mocha
39
41
 
40
42
  target = Detection::MiniTest.testcase
41
43
  unless target < integration_module
44
+ unless integration_module == MiniTest::Adapter
45
+ Deprecation.warning(
46
+ 'Versions of minitest earlier than v3.3.0 will not be supported in future versions of Mocha.'
47
+ )
48
+ end
42
49
  Debug.puts "Applying #{integration_module.description}"
43
50
  target.send(:include, integration_module)
44
51
  end
@@ -11,6 +11,8 @@ require 'mocha/integration/test_unit/gem_version_203_to_220'
11
11
  require 'mocha/integration/test_unit/gem_version_230_to_250'
12
12
  require 'mocha/integration/test_unit/adapter'
13
13
 
14
+ require 'mocha/deprecation'
15
+
14
16
  module Mocha
15
17
  module Integration
16
18
  module TestUnit
@@ -34,6 +36,11 @@ module Mocha
34
36
  ].detect { |m| m.applicable_to?(test_unit_version, ruby_version) }
35
37
 
36
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
37
44
  Debug.puts "Applying #{integration_module.description}"
38
45
  ::Test::Unit::TestCase.send(:include, integration_module)
39
46
  end
@@ -0,0 +1,77 @@
1
+ require 'mocha/parameters_matcher'
2
+ require 'mocha/raised_exception'
3
+ require 'mocha/return_values'
4
+ require 'mocha/thrown_object'
5
+ require 'mocha/yield_parameters'
6
+ require 'mocha/configuration'
7
+ require 'mocha/deprecation'
8
+
9
+ module Mocha
10
+ class Invocation
11
+ attr_reader :method_name, :block
12
+
13
+ def initialize(mock, method_name, *arguments, &block)
14
+ @mock = mock
15
+ @method_name = method_name
16
+ @arguments = arguments
17
+ @block = block
18
+ @yields = []
19
+ @result = nil
20
+ end
21
+
22
+ def call(yield_parameters = YieldParameters.new, return_values = ReturnValues.new)
23
+ yield_parameters.next_invocation.each do |yield_args|
24
+ @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
37
+ end
38
+ return_values.next(self)
39
+ end
40
+
41
+ def returned(value)
42
+ @result = value
43
+ end
44
+
45
+ def raised(exception)
46
+ @result = RaisedException.new(exception)
47
+ end
48
+
49
+ def threw(tag, value)
50
+ @result = ThrownObject.new(tag, value)
51
+ end
52
+
53
+ def arguments
54
+ @arguments.dup
55
+ end
56
+
57
+ def call_description
58
+ description = "#{@mock.mocha_inspect}.#{@method_name}#{ParametersMatcher.new(@arguments).mocha_inspect}"
59
+ description << ' { ... }' unless @block.nil?
60
+ description
61
+ end
62
+
63
+ def short_call_description
64
+ "#{@method_name}(#{@arguments.join(', ')})"
65
+ end
66
+
67
+ def result_description
68
+ desc = "# => #{@result.mocha_inspect}"
69
+ desc << " after yielding #{@yields.map(&:mocha_inspect).join(', then ')}" if @yields.any?
70
+ desc
71
+ end
72
+
73
+ def full_description
74
+ "\n - #{call_description} #{result_description}"
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,5 @@
1
+ module Mocha
2
+ MACOS = /darwin/.match(RUBY_PLATFORM)
3
+ MACOS_VERSION = MACOS && /darwin(\d+)/.match(RUBY_PLATFORM)[1].to_i
4
+ MACOS_MOJAVE_VERSION = 18
5
+ end
@@ -1,3 +1,8 @@
1
1
  require 'mocha/integration/mini_test'
2
+ require 'mocha/deprecation'
2
3
 
3
- Mocha::Integration::MiniTest.activate
4
+ unless Mocha::Integration::MiniTest.activate
5
+ Mocha::Deprecation.warning(
6
+ "MiniTest must be loaded *before* `require 'mocha/minitest'`."
7
+ )
8
+ end
@@ -1,21 +1,27 @@
1
- require 'metaclass'
1
+ require 'mocha/singleton_class'
2
2
  require 'mocha/expectation'
3
3
  require 'mocha/expectation_list'
4
+ require 'mocha/invocation'
4
5
  require 'mocha/names'
5
6
  require 'mocha/receivers'
6
7
  require 'mocha/method_matcher'
7
8
  require 'mocha/parameters_matcher'
8
- require 'mocha/unexpected_invocation'
9
9
  require 'mocha/argument_iterator'
10
10
  require 'mocha/expectation_error_factory'
11
- require 'mocha/deprecation'
12
11
  require 'mocha/ruby_version'
13
12
 
14
13
  module Mocha
15
14
  # Traditional mock object.
16
15
  #
17
- # All methods return an {Expectation} which can be further modified by
18
- # methods on {Expectation}.
16
+ # {expects} and {stubs} return an {Expectation} which can be further modified
17
+ # by methods on {Expectation}.
18
+ #
19
+ # {responds_like} and {responds_like_instance_of} both return a {Mock}, and
20
+ # can therefore, be chained to the original creation methods in {API}.
21
+ # They force the mock to indicate what it is supposed to be mocking, thus
22
+ # making it a safer verifying mock. They check that the underlying +responder+
23
+ # will actually respond to the methods being stubbed, throwing a
24
+ # +NoMethodError+ upon invocation otherwise.
19
25
  #
20
26
  # Stubs and expectations are basically the same thing. A stub is just an
21
27
  # expectation of zero or more invocations. The {#stubs} method is syntactic
@@ -70,12 +76,12 @@ module Mocha
70
76
  class Mock
71
77
  # Adds an expectation that the specified method must be called exactly once with any parameters.
72
78
  #
73
- # @param [Symbol,String] method_name name of expected method
74
- # @param [Hash] expected_methods_vs_return_values expected method name symbols as keys and corresponding return values as values - these expectations are setup as if {#expects} were called multiple times.
79
+ # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}.
75
80
  #
76
81
  # @overload def expects(method_name)
82
+ # @param [Symbol,String] method_name name of expected method
77
83
  # @overload def expects(expected_methods_vs_return_values)
78
- # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}.
84
+ # @param [Hash] expected_methods_vs_return_values expected method name symbols as keys and corresponding return values as values - these expectations are setup as if {#expects} were called multiple times.
79
85
  #
80
86
  # @example Expected method invoked once so no error raised
81
87
  # object = mock()
@@ -115,12 +121,12 @@ module Mocha
115
121
 
116
122
  # Adds an expectation that the specified method may be called any number of times with any parameters.
117
123
  #
118
- # @param [Symbol,String] method_name name of stubbed method
119
- # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {#stubs} were called multiple times.
124
+ # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}.
120
125
  #
121
126
  # @overload def stubs(method_name)
127
+ # @param [Symbol,String] method_name name of stubbed method
122
128
  # @overload def stubs(stubbed_methods_vs_return_values)
123
- # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}.
129
+ # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {#stubs} were called multiple times.
124
130
  #
125
131
  # @example No error raised however many times stubbed method is invoked
126
132
  # object = mock()
@@ -150,9 +156,9 @@ module Mocha
150
156
  end
151
157
  end
152
158
 
153
- # Removes the specified stubbed method (added by calls to {#expects} or {#stubs}) and all expectations associated with it.
159
+ # Removes the specified stubbed methods (added by calls to {#expects} or {#stubs}) and all expectations associated with them.
154
160
  #
155
- # @param [Symbol] method_name name of method to unstub.
161
+ # @param [Array<Symbol>] method_names names of methods to unstub.
156
162
  #
157
163
  # @example Invoking an unstubbed method causes error to be raised
158
164
  # object = mock('mock') do
@@ -160,8 +166,18 @@ module Mocha
160
166
  # object.stubbed_method # => :result_one
161
167
  # object.unstub(:stubbed_method)
162
168
  # object.stubbed_method # => unexpected invocation: #<Mock:mock>.stubbed_method()
163
- def unstub(method_name)
164
- @expectations.remove_all_matching_method(method_name)
169
+ #
170
+ # @example Unstubbing multiple methods.
171
+ # multiplier.unstub(:double, :triple)
172
+ #
173
+ # # exactly equivalent to
174
+ #
175
+ # multiplier.unstub(:double)
176
+ # multiplier.unstub(:triple)
177
+ def unstub(*method_names)
178
+ method_names.each do |method_name|
179
+ @expectations.remove_all_matching_method(method_name)
180
+ end
165
181
  end
166
182
 
167
183
  # Constrains the {Mock} instance so that it can only expect or stub methods to which +responder+ responds. The constraint is only applied at method invocation time.
@@ -251,7 +267,7 @@ module Mocha
251
267
  end
252
268
 
253
269
  # @private
254
- def initialize(mockery, name = nil, receiver = nil, &block)
270
+ def initialize(mockery, name = nil, receiver = nil)
255
271
  @mockery = mockery
256
272
  @name = name || DefaultName.new(self)
257
273
  @receiver = receiver || DefaultReceiver.new(self)
@@ -259,9 +275,6 @@ module Mocha
259
275
  @everything_stubbed = false
260
276
  @responder = nil
261
277
  @unexpected_invocation = nil
262
- return unless block
263
- Deprecation.warning('Passing a block is deprecated. Use Object#tap or define stubs/expectations with an explicit receiver instead.')
264
- instance_eval(&block)
265
278
  end
266
279
 
267
280
  # @private
@@ -271,6 +284,8 @@ module Mocha
271
284
 
272
285
  alias_method :__stubs__, :stubs
273
286
 
287
+ alias_method :__singleton_class__, :singleton_class
288
+
274
289
  alias_method :quacks_like, :responds_like
275
290
  alias_method :quacks_like_instance_of, :responds_like_instance_of
276
291
 
@@ -290,26 +305,26 @@ module Mocha
290
305
  end
291
306
 
292
307
  # @private
293
- # rubocop:disable Style/MethodMissingSuper
308
+ # rubocop:disable Style/MethodMissingSuper,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
294
309
  def method_missing(symbol, *arguments, &block)
295
310
  if @responder && !@responder.respond_to?(symbol)
296
311
  raise NoMethodError, "undefined method `#{symbol}' for #{mocha_inspect} which responds like #{@responder.mocha_inspect}"
297
312
  end
298
- if (matching_expectation_allowing_invocation = all_expectations.match_allowing_invocation(symbol, *arguments))
299
- matching_expectation_allowing_invocation.invoke(&block)
300
- elsif (matching_expectation = all_expectations.match(symbol, *arguments)) || (!matching_expectation && !@everything_stubbed)
313
+ invocation = Invocation.new(self, symbol, *arguments, &block)
314
+ if (matching_expectation_allowing_invocation = all_expectations.match_allowing_invocation(invocation))
315
+ matching_expectation_allowing_invocation.invoke(invocation)
316
+ elsif (matching_expectation = all_expectations.match(invocation)) || (!matching_expectation && !@everything_stubbed)
301
317
  if @unexpected_invocation.nil?
302
- @unexpected_invocation = UnexpectedInvocation.new(self, symbol, *arguments)
303
- matching_expectation.invoke(&block) if matching_expectation
304
- message = @unexpected_invocation.full_description
305
- message << @mockery.mocha_inspect
318
+ @unexpected_invocation = invocation
319
+ matching_expectation.invoke(invocation) if matching_expectation
320
+ message = "#{@unexpected_invocation.call_description}\n#{@mockery.mocha_inspect}"
306
321
  else
307
- message = @unexpected_invocation.short_description
322
+ message = @unexpected_invocation.short_call_description
308
323
  end
309
- raise ExpectationErrorFactory.build(message, caller)
324
+ raise ExpectationErrorFactory.build("unexpected invocation: #{message}", caller)
310
325
  end
311
326
  end
312
- # rubocop:enable Style/MethodMissingSuper
327
+ # rubocop:enable Style/MethodMissingSuper,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
313
328
 
314
329
  # @private
315
330
  def respond_to_missing?(symbol, include_private = false)
@@ -348,7 +363,7 @@ module Mocha
348
363
 
349
364
  # @private
350
365
  def ensure_method_not_already_defined(method_name)
351
- __metaclass__.send(:undef_method, method_name) if __metaclass__.method_defined?(method_name) || __metaclass__.private_method_defined?(method_name)
366
+ __singleton_class__.send(:undef_method, method_name) if __singleton_class__.method_defined?(method_name) || __singleton_class__.private_method_defined?(method_name)
352
367
  end
353
368
 
354
369
  # @private
@@ -62,20 +62,20 @@ module Mocha
62
62
  end
63
63
  end
64
64
 
65
- def named_mock(name, &block)
66
- add_mock(Mock.new(self, Name.new(name), &block))
65
+ def named_mock(name)
66
+ add_mock(Mock.new(self, Name.new(name)))
67
67
  end
68
68
 
69
- def unnamed_mock(&block)
70
- add_mock(Mock.new(self, &block))
69
+ def unnamed_mock
70
+ add_mock(Mock.new(self))
71
71
  end
72
72
 
73
- def mock_impersonating(object, &block)
74
- add_mock(Mock.new(self, ImpersonatingName.new(object), ObjectReceiver.new(object), &block))
73
+ def mock_impersonating(object)
74
+ add_mock(Mock.new(self, ImpersonatingName.new(object), ObjectReceiver.new(object)))
75
75
  end
76
76
 
77
- def mock_impersonating_any_instance_of(klass, &block)
78
- add_mock(Mock.new(self, ImpersonatingAnyInstanceName.new(klass), AnyInstanceReceiver.new(klass), &block))
77
+ def mock_impersonating_any_instance_of(klass)
78
+ add_mock(Mock.new(self, ImpersonatingAnyInstanceName.new(klass), AnyInstanceReceiver.new(klass)))
79
79
  end
80
80
 
81
81
  def new_state_machine(name)
@@ -93,7 +93,7 @@ module Mocha
93
93
  raise ExpectationErrorFactory.build(message, backtrace)
94
94
  end
95
95
  expectations.each do |e|
96
- unless Mocha::Configuration.allow?(:stubbing_method_unnecessarily)
96
+ unless Mocha.configuration.stubbing_method_unnecessarily == :allow
97
97
  next if e.used?
98
98
  on_stubbing_method_unnecessarily(e)
99
99
  end
@@ -127,63 +127,19 @@ module Mocha
127
127
 
128
128
  def on_stubbing(object, method)
129
129
  method = PRE_RUBY_V19 ? method.to_s : method.to_sym
130
- unless Mocha::Configuration.allow?(:stubbing_non_existent_method)
131
- unless object.method_exists?(method, true)
132
- on_stubbing_non_existent_method(object, method)
133
- end
134
- end
135
- unless Mocha::Configuration.allow?(:stubbing_non_public_method)
136
- if object.method_exists?(method, false)
137
- on_stubbing_non_public_method(object, method)
138
- end
139
- end
140
- unless Mocha::Configuration.allow?(:stubbing_method_on_nil)
141
- if object.nil?
142
- on_stubbing_method_on_nil(object, method)
143
- end
130
+ method_signature = "#{object.mocha_inspect}.#{method}"
131
+ check(:stubbing_non_existent_method, 'non-existent method', method_signature) do
132
+ !(object.stubba_class.__method_exists__?(method, true) || object.respond_to?(method.to_sym))
144
133
  end
145
- return if Mocha::Configuration.allow?(:stubbing_method_on_non_mock_object)
146
- on_stubbing_method_on_non_mock_object(object, method)
147
- end
148
-
149
- def on_stubbing_non_existent_method(object, method)
150
- if Mocha::Configuration.prevent?(:stubbing_non_existent_method)
151
- raise StubbingError.new("stubbing non-existent method: #{object.mocha_inspect}.#{method}", caller)
152
- end
153
- return unless Mocha::Configuration.warn_when?(:stubbing_non_existent_method)
154
- logger.warn "stubbing non-existent method: #{object.mocha_inspect}.#{method}"
155
- end
156
-
157
- def on_stubbing_non_public_method(object, method)
158
- if Mocha::Configuration.prevent?(:stubbing_non_public_method)
159
- raise StubbingError.new("stubbing non-public method: #{object.mocha_inspect}.#{method}", caller)
134
+ check(:stubbing_non_public_method, 'non-public method', method_signature) do
135
+ object.stubba_class.__method_exists__?(method, false)
160
136
  end
161
- return unless Mocha::Configuration.warn_when?(:stubbing_non_public_method)
162
- logger.warn "stubbing non-public method: #{object.mocha_inspect}.#{method}"
163
- end
164
-
165
- def on_stubbing_method_on_nil(object, method)
166
- if Mocha::Configuration.prevent?(:stubbing_method_on_nil)
167
- raise StubbingError.new("stubbing method on nil: #{object.mocha_inspect}.#{method}", caller)
168
- end
169
- return unless Mocha::Configuration.warn_when?(:stubbing_method_on_nil)
170
- logger.warn "stubbing method on nil: #{object.mocha_inspect}.#{method}"
171
- end
172
-
173
- def on_stubbing_method_on_non_mock_object(object, method)
174
- if Mocha::Configuration.prevent?(:stubbing_method_on_non_mock_object)
175
- raise StubbingError.new("stubbing method on non-mock object: #{object.mocha_inspect}.#{method}", caller)
176
- end
177
- return unless Mocha::Configuration.warn_when?(:stubbing_method_on_non_mock_object)
178
- logger.warn "stubbing method on non-mock object: #{object.mocha_inspect}.#{method}"
137
+ check(:stubbing_method_on_nil, 'method on nil', method_signature) { object.nil? }
138
+ check(:stubbing_method_on_non_mock_object, 'method on non-mock object', method_signature)
179
139
  end
180
140
 
181
141
  def on_stubbing_method_unnecessarily(expectation)
182
- if Mocha::Configuration.prevent?(:stubbing_method_unnecessarily)
183
- raise StubbingError.new("stubbing method unnecessarily: #{expectation.method_signature}", expectation.backtrace)
184
- end
185
- return unless Mocha::Configuration.warn_when?(:stubbing_method_unnecessarily)
186
- logger.warn "stubbing method unnecessarily: #{expectation.method_signature}"
142
+ check(:stubbing_method_unnecessarily, 'method unnecessarily', expectation.method_signature, expectation.backtrace)
187
143
  end
188
144
 
189
145
  attr_writer :logger
@@ -194,6 +150,14 @@ module Mocha
194
150
 
195
151
  private
196
152
 
153
+ def check(action, description, method_signature, backtrace = caller)
154
+ treatment = Mocha.configuration.send(action)
155
+ return if (treatment == :allow) || (block_given? && !yield)
156
+ message = "stubbing #{description}: #{method_signature}"
157
+ raise StubbingError.new(message, backtrace) if treatment == :prevent
158
+ logger.warn(message) if treatment == :warn
159
+ end
160
+
197
161
  def expectations
198
162
  mocks.map { |mock| mock.__expectations__.to_a }.flatten
199
163
  end
@@ -21,7 +21,7 @@ module Mocha
21
21
 
22
22
  class Name
23
23
  def initialize(name)
24
- @name = name
24
+ @name = name.to_s
25
25
  end
26
26
 
27
27
  def mocha_inspect
@@ -35,17 +35,22 @@ module Mocha
35
35
  self
36
36
  end
37
37
 
38
+ # @private
39
+ def stubba_class
40
+ singleton_class
41
+ end
42
+
38
43
  # Adds an expectation that the specified method must be called exactly once with any parameters.
39
44
  #
40
45
  # The original implementation of the method is replaced during the test and then restored at the end of the test. The temporary replacement method has the same visibility as the original method.
41
46
  #
42
- # @param [Symbol,String] method_name name of expected method
43
- # @param [Hash] expected_methods_vs_return_values expected method name symbols as keys and corresponding return values as values - these expectations are setup as if {#expects} were called multiple times.
47
+ # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}.
48
+ # @raise [StubbingError] if attempting to stub method which is not allowed.
44
49
  #
45
50
  # @overload def expects(method_name)
51
+ # @param [Symbol,String] method_name name of expected method
46
52
  # @overload def expects(expected_methods_vs_return_values)
47
- # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}.
48
- # @raise [StubbingError] if attempting to stub method which is not allowed.
53
+ # @param [Hash] expected_methods_vs_return_values expected method name symbols as keys and corresponding return values as values - these expectations are setup as if {#expects} were called multiple times.
49
54
  #
50
55
  # @example Setting up an expectation on a non-mock object.
51
56
  # product = Product.new
@@ -88,13 +93,13 @@ module Mocha
88
93
  #
89
94
  # The original implementation of the method is replaced during the test and then restored at the end of the test. The temporary replacement method has the same visibility as the original method.
90
95
  #
91
- # @param [Symbol,String] method_name name of stubbed method
92
- # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {#stubs} were called multiple times.
96
+ # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}.
97
+ # @raise [StubbingError] if attempting to stub method which is not allowed.
93
98
  #
94
99
  # @overload def stubs(method_name)
100
+ # @param [Symbol,String] method_name name of stubbed method
95
101
  # @overload def stubs(stubbed_methods_vs_return_values)
96
- # @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}.
97
- # @raise [StubbingError] if attempting to stub method which is not allowed.
102
+ # @param [Hash] stubbed_methods_vs_return_values stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if {#stubs} were called multiple times.
98
103
  #
99
104
  # @example Setting up a stubbed methods on a non-mock object.
100
105
  # product = Product.new
@@ -160,16 +165,5 @@ module Mocha
160
165
  mockery.stubba.unstub(method)
161
166
  end
162
167
  end
163
-
164
- # @private
165
- def method_exists?(method, include_public_methods = true)
166
- if include_public_methods
167
- return true if public_methods(true).include?(method)
168
- return true if respond_to?(method.to_sym)
169
- end
170
- return true if protected_methods(true).include?(method)
171
- return true if private_methods(true).include?(method)
172
- false
173
- end
174
168
  end
175
169
  end