mocha 1.8.0 → 1.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +1 -0
- data/.rubocop.yml +3 -0
- data/.rubocop_todo.yml +7 -30
- data/.yardopts +1 -0
- data/README.md +40 -13
- data/RELEASE.md +97 -0
- data/Rakefile +10 -7
- data/bin/build-matrix +1 -2
- data/docs/CNAME +1 -1
- data/docs/Mocha.html +132 -5
- data/docs/Mocha/API.html +437 -206
- data/docs/Mocha/ClassMethods.html +13 -16
- data/docs/Mocha/Configuration.html +1126 -227
- data/docs/Mocha/Expectation.html +420 -267
- data/docs/Mocha/ExpectationError.html +5 -10
- data/docs/Mocha/ExpectationErrorFactory.html +9 -18
- data/docs/Mocha/Hooks.html +12 -27
- data/docs/Mocha/Integration.html +3 -3
- data/docs/Mocha/Integration/MiniTest.html +3 -3
- data/docs/Mocha/Integration/MiniTest/Adapter.html +5 -6
- data/docs/Mocha/Integration/TestUnit.html +3 -3
- data/docs/Mocha/Integration/TestUnit/Adapter.html +5 -6
- data/docs/Mocha/Mock.html +202 -162
- data/docs/Mocha/ObjectMethods.html +121 -68
- data/docs/Mocha/ParameterMatchers.html +21 -109
- data/docs/Mocha/ParameterMatchers/AllOf.html +4 -5
- data/docs/Mocha/ParameterMatchers/AnyOf.html +4 -5
- data/docs/Mocha/ParameterMatchers/AnyParameters.html +3 -3
- data/docs/Mocha/ParameterMatchers/Anything.html +3 -3
- data/docs/Mocha/ParameterMatchers/Base.html +8 -15
- data/docs/Mocha/ParameterMatchers/Equals.html +4 -5
- data/docs/Mocha/ParameterMatchers/EquivalentUri.html +3 -3
- data/docs/Mocha/ParameterMatchers/HasEntries.html +4 -5
- data/docs/Mocha/ParameterMatchers/HasEntry.html +4 -5
- data/docs/Mocha/ParameterMatchers/HasKey.html +4 -5
- data/docs/Mocha/ParameterMatchers/HasValue.html +4 -5
- data/docs/Mocha/ParameterMatchers/Includes.html +4 -5
- data/docs/Mocha/ParameterMatchers/InstanceOf.html +4 -5
- data/docs/Mocha/ParameterMatchers/IsA.html +3 -3
- data/docs/Mocha/ParameterMatchers/KindOf.html +4 -5
- data/docs/Mocha/ParameterMatchers/Not.html +4 -5
- data/docs/Mocha/ParameterMatchers/Optionally.html +3 -3
- data/docs/Mocha/ParameterMatchers/RegexpMatches.html +4 -5
- data/docs/Mocha/ParameterMatchers/RespondsWith.html +4 -5
- data/docs/Mocha/ParameterMatchers/YamlEquivalent.html +4 -5
- data/docs/Mocha/Sequence.html +3 -3
- data/docs/Mocha/StateMachine.html +13 -25
- data/docs/Mocha/StateMachine/State.html +4 -5
- data/docs/Mocha/StateMachine/StatePredicate.html +4 -5
- data/docs/Mocha/StubbingError.html +3 -3
- data/docs/_index.html +4 -22
- data/docs/class_list.html +1 -1
- data/docs/file.COPYING.html +3 -3
- data/docs/file.MIT-LICENSE.html +3 -3
- data/docs/file.README.html +46 -16
- data/docs/file.RELEASE.html +130 -3
- data/docs/frames.html +1 -1
- data/docs/index.html +46 -16
- data/docs/js/app.js +11 -0
- data/docs/method_list.html +117 -37
- data/docs/top-level-namespace.html +3 -3
- data/gemfiles/Gemfile.minitest.5.11.3 +7 -0
- data/init.rb +1 -3
- data/lib/mocha.rb +8 -0
- data/lib/mocha/any_instance_method.rb +11 -53
- data/lib/mocha/api.rb +120 -56
- data/lib/mocha/block_matcher.rb +31 -0
- data/lib/mocha/cardinality.rb +26 -11
- data/lib/mocha/class_methods.rb +17 -15
- data/lib/mocha/configuration.rb +351 -67
- data/lib/mocha/deprecation.rb +2 -1
- data/lib/mocha/detection/test_unit.rb +1 -3
- data/lib/mocha/exception_raiser.rb +2 -1
- data/lib/mocha/expectation.rb +102 -63
- data/lib/mocha/expectation_error.rb +1 -3
- data/lib/mocha/expectation_list.rb +6 -6
- data/lib/mocha/inspect.rb +28 -26
- data/lib/mocha/instance_method.rb +19 -2
- data/lib/mocha/integration.rb +1 -3
- data/lib/mocha/integration/mini_test.rb +7 -0
- data/lib/mocha/integration/test_unit.rb +7 -0
- data/lib/mocha/invocation.rb +77 -0
- data/lib/mocha/macos_version.rb +5 -0
- data/lib/mocha/minitest.rb +6 -1
- data/lib/mocha/mock.rb +46 -31
- data/lib/mocha/mockery.rb +25 -61
- data/lib/mocha/names.rb +1 -1
- data/lib/mocha/object_methods.rb +13 -19
- data/lib/mocha/parameter_matchers.rb +1 -1
- data/lib/mocha/parameter_matchers/all_of.rb +1 -1
- data/lib/mocha/parameter_matchers/any_of.rb +1 -1
- data/lib/mocha/parameter_matchers/equivalent_uri.rb +0 -9
- data/lib/mocha/parameter_matchers/includes.rb +2 -0
- data/lib/mocha/parameter_matchers/instance_methods.rb +18 -0
- data/lib/mocha/raised_exception.rb +11 -0
- data/lib/mocha/return_values.rb +3 -3
- data/lib/mocha/setup.rb +5 -0
- data/lib/mocha/single_return_value.rb +2 -1
- data/lib/mocha/singleton_class.rb +9 -0
- data/lib/mocha/stubbed_method.rb +127 -0
- data/lib/mocha/test_unit.rb +6 -1
- data/lib/mocha/thrower.rb +2 -1
- data/lib/mocha/thrown_object.rb +12 -0
- data/lib/mocha/version.rb +1 -1
- data/lib/mocha/yield_parameters.rb +5 -11
- data/mocha.gemspec +1 -3
- data/test/acceptance/acceptance_test_helper.rb +7 -0
- data/test/acceptance/bug_18914_test.rb +0 -1
- data/test/acceptance/bug_21465_test.rb +0 -1
- data/test/acceptance/bug_21563_test.rb +0 -1
- data/test/acceptance/display_matching_invocations_alongside_expectations_test.rb +69 -0
- data/test/acceptance/exception_rescue_test.rb +1 -2
- data/test/acceptance/expectations_on_multiple_methods_test.rb +0 -1
- data/test/acceptance/expected_invocation_count_test.rb +2 -3
- data/test/acceptance/failure_messages_test.rb +16 -1
- data/test/acceptance/issue_272_test.rb +1 -2
- data/test/acceptance/issue_65_test.rb +0 -1
- data/test/acceptance/issue_70_test.rb +0 -1
- data/test/acceptance/mocha_example_test.rb +0 -1
- data/test/acceptance/mocha_test_result_test.rb +0 -1
- data/test/acceptance/mock_built_with_first_argument_type_being_string_test.rb +99 -0
- data/test/acceptance/mock_test.rb +47 -6
- data/test/acceptance/mocked_methods_dispatch_test.rb +0 -1
- data/test/acceptance/multiple_expectations_failure_message_test.rb +0 -1
- data/test/acceptance/multiple_yielding_test.rb +56 -0
- data/test/acceptance/optional_parameters_test.rb +0 -1
- data/test/acceptance/parameter_matcher_test.rb +0 -1
- data/test/acceptance/partial_mocks_test.rb +0 -1
- data/test/acceptance/prepend_test.rb +0 -1
- data/test/acceptance/prevent_use_of_mocha_outside_test_test.rb +0 -1
- data/test/acceptance/raise_exception_test.rb +0 -1
- data/test/acceptance/return_value_test.rb +0 -1
- data/test/acceptance/sequence_test.rb +0 -1
- data/test/acceptance/states_test.rb +0 -1
- data/test/acceptance/stub_any_instance_method_defined_on_superclass_test.rb +1 -2
- data/test/acceptance/stub_any_instance_method_test.rb +20 -1
- data/test/acceptance/stub_class_method_defined_on_active_record_association_proxy_test.rb +0 -1
- data/test/acceptance/stub_class_method_defined_on_class_test.rb +0 -1
- data/test/acceptance/stub_class_method_defined_on_module_test.rb +0 -1
- data/test/acceptance/stub_class_method_defined_on_superclass_test.rb +1 -2
- data/test/acceptance/stub_everything_test.rb +0 -1
- data/test/acceptance/stub_instance_method_defined_on_active_record_association_proxy_test.rb +0 -1
- data/test/acceptance/stub_instance_method_defined_on_class_and_aliased_test.rb +0 -1
- data/test/acceptance/stub_instance_method_defined_on_class_test.rb +0 -1
- data/test/acceptance/stub_instance_method_defined_on_kernel_module_test.rb +0 -1
- data/test/acceptance/stub_instance_method_defined_on_module_test.rb +0 -1
- data/test/acceptance/stub_instance_method_defined_on_object_class_test.rb +0 -1
- data/test/acceptance/stub_instance_method_defined_on_singleton_class_test.rb +0 -1
- data/test/acceptance/stub_instance_method_defined_on_superclass_test.rb +0 -1
- data/test/acceptance/stub_method_defined_on_module_and_aliased_test.rb +0 -1
- data/test/acceptance/stub_module_method_test.rb +0 -1
- data/test/acceptance/stub_test.rb +0 -1
- data/test/acceptance/stubba_example_test.rb +0 -1
- data/test/acceptance/stubba_test_result_test.rb +0 -1
- data/test/acceptance/stubbing_error_backtrace_test.rb +4 -5
- data/test/acceptance/stubbing_frozen_object_test.rb +0 -1
- data/test/acceptance/stubbing_method_accepting_block_parameter_test.rb +0 -1
- data/test/acceptance/stubbing_method_unnecessarily_test.rb +5 -5
- data/test/acceptance/stubbing_nil_test.rb +5 -5
- data/test/acceptance/stubbing_non_existent_any_instance_method_test.rb +27 -11
- data/test/acceptance/stubbing_non_existent_class_method_test.rb +11 -11
- data/test/acceptance/stubbing_non_existent_instance_method_test.rb +11 -11
- data/test/acceptance/stubbing_non_public_any_instance_method_test.rb +8 -8
- data/test/acceptance/stubbing_non_public_class_method_test.rb +9 -9
- data/test/acceptance/stubbing_non_public_instance_method_test.rb +9 -9
- data/test/acceptance/stubbing_on_non_mock_object_test.rb +5 -5
- data/test/acceptance/stubbing_same_class_method_on_parent_and_child_classes_test.rb +0 -1
- data/test/acceptance/throw_test.rb +0 -1
- data/test/acceptance/unexpected_invocation_test.rb +0 -1
- data/test/acceptance/unstubbing_test.rb +0 -1
- data/test/acceptance/yielding_test.rb +78 -0
- data/test/integration/shared_tests.rb +5 -3
- data/test/method_definer.rb +11 -17
- data/test/test_runner.rb +2 -0
- data/test/unit/any_instance_method_test.rb +60 -35
- data/test/unit/cardinality_test.rb +41 -23
- data/test/unit/central_test.rb +0 -1
- data/test/unit/class_methods_test.rb +1 -1
- data/test/unit/configuration_test.rb +12 -12
- data/test/unit/exception_raiser_test.rb +10 -5
- data/test/unit/expectation_list_test.rb +13 -11
- data/test/unit/expectation_test.rb +117 -103
- data/test/unit/instance_method_test.rb +282 -0
- data/test/unit/mock_test.rb +28 -19
- data/test/unit/mockery_test.rb +8 -11
- data/test/unit/module_methods_test.rb +2 -3
- data/test/unit/object_inspect_test.rb +6 -4
- data/test/unit/object_methods_test.rb +3 -2
- data/test/unit/parameter_matchers/equivalent_uri_test.rb +0 -9
- data/test/unit/parameter_matchers/has_entries_test.rb +1 -1
- data/test/unit/parameter_matchers/has_entry_test.rb +1 -1
- data/test/unit/parameter_matchers/has_key_test.rb +1 -1
- data/test/unit/parameter_matchers/has_value_test.rb +1 -1
- data/test/unit/parameter_matchers/includes_test.rb +1 -1
- data/test/unit/parameter_matchers/responds_with_test.rb +1 -1
- data/test/unit/return_values_test.rb +25 -20
- data/test/unit/single_return_value_test.rb +6 -1
- data/test/unit/thrower_test.rb +7 -2
- data/test/unit/yield_parameters_test.rb +35 -53
- metadata +18 -35
- data/docs/Mocha/UnexpectedInvocation.html +0 -140
- data/lib/mocha/class_method.rb +0 -113
- data/lib/mocha/mini_test.rb +0 -5
- data/lib/mocha/module_method.rb +0 -6
- data/lib/mocha/module_methods.rb +0 -10
- data/lib/mocha/multiple_yields.rb +0 -15
- data/lib/mocha/no_yields.rb +0 -5
- data/lib/mocha/parameter_matchers/object.rb +0 -15
- data/lib/mocha/single_yield.rb +0 -13
- data/lib/mocha/standalone.rb +0 -4
- data/lib/mocha/unexpected_invocation.rb +0 -24
- data/lib/mocha_standalone.rb +0 -4
- data/test/acceptance/mock_with_initializer_block_test.rb +0 -56
- data/test/unit/class_method_test.rb +0 -254
- data/test/unit/multiple_yields_test.rb +0 -16
- data/test/unit/no_yields_test.rb +0 -16
- 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
|
data/lib/mocha/minitest.rb
CHANGED
data/lib/mocha/mock.rb
CHANGED
@@ -1,21 +1,27 @@
|
|
1
|
-
require '
|
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
|
-
#
|
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
|
-
# @
|
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
|
-
#
|
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
|
-
# @
|
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
|
-
#
|
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
|
159
|
+
# Removes the specified stubbed methods (added by calls to {#expects} or {#stubs}) and all expectations associated with them.
|
154
160
|
#
|
155
|
-
# @param [Symbol]
|
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
|
-
|
164
|
-
|
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
|
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
|
-
|
299
|
-
|
300
|
-
|
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 =
|
303
|
-
matching_expectation.invoke(
|
304
|
-
message = @unexpected_invocation.
|
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.
|
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
|
-
|
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
|
data/lib/mocha/mockery.rb
CHANGED
@@ -62,20 +62,20 @@ module Mocha
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
def named_mock(name
|
66
|
-
add_mock(Mock.new(self, Name.new(name)
|
65
|
+
def named_mock(name)
|
66
|
+
add_mock(Mock.new(self, Name.new(name)))
|
67
67
|
end
|
68
68
|
|
69
|
-
def unnamed_mock
|
70
|
-
add_mock(Mock.new(self
|
69
|
+
def unnamed_mock
|
70
|
+
add_mock(Mock.new(self))
|
71
71
|
end
|
72
72
|
|
73
|
-
def mock_impersonating(object
|
74
|
-
add_mock(Mock.new(self, ImpersonatingName.new(object), ObjectReceiver.new(object)
|
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
|
78
|
-
add_mock(Mock.new(self, ImpersonatingAnyInstanceName.new(klass), AnyInstanceReceiver.new(klass)
|
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
|
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
|
-
|
131
|
-
|
132
|
-
|
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
|
-
|
146
|
-
|
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
|
-
|
162
|
-
|
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
|
-
|
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
|
data/lib/mocha/names.rb
CHANGED
data/lib/mocha/object_methods.rb
CHANGED
@@ -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
|
-
# @
|
43
|
-
# @
|
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
|
-
#
|
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
|
-
# @
|
92
|
-
# @
|
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
|
-
#
|
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
|