mocha 1.2.1 → 1.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/FUNDING.yml +1 -0
- data/.rubocop.yml +61 -0
- data/.rubocop_todo.yml +27 -0
- data/.yardopts +1 -0
- data/CONTRIBUTING.md +4 -9
- data/Gemfile +29 -0
- data/README.md +104 -106
- data/RELEASE.md +277 -1
- data/Rakefile +46 -44
- data/gemfiles/Gemfile.minitest.latest +1 -0
- data/gemfiles/Gemfile.test-unit.latest +2 -5
- data/init.rb +1 -3
- data/lib/mocha/any_instance_method.rb +9 -62
- data/lib/mocha/api.rb +144 -68
- data/lib/mocha/argument_iterator.rb +4 -8
- data/lib/mocha/backtrace_filter.rb +1 -5
- data/lib/mocha/block_matcher.rb +31 -0
- data/lib/mocha/cardinality.rb +60 -49
- data/lib/mocha/central.rb +21 -12
- data/lib/mocha/change_state_side_effect.rb +0 -4
- data/lib/mocha/class_methods.rb +19 -21
- data/lib/mocha/configuration.rb +372 -18
- data/lib/mocha/debug.rb +3 -2
- data/lib/mocha/deprecation.rb +8 -11
- data/lib/mocha/detection/mini_test.rb +0 -2
- data/lib/mocha/detection/test_unit.rb +3 -5
- data/lib/mocha/error_with_filtered_backtrace.rb +13 -0
- data/lib/mocha/exception_raiser.rb +4 -6
- data/lib/mocha/expectation.rb +125 -89
- data/lib/mocha/expectation_error.rb +1 -1
- data/lib/mocha/expectation_error_factory.rb +0 -1
- data/lib/mocha/expectation_list.rb +7 -11
- data/lib/mocha/hooks.rb +1 -3
- data/lib/mocha/in_state_ordering_constraint.rb +0 -4
- data/lib/mocha/inspect.rb +30 -38
- data/lib/mocha/instance_method.rb +11 -8
- data/lib/mocha/integration/mini_test/adapter.rb +2 -4
- data/lib/mocha/integration/mini_test/exception_translation.rb +1 -1
- data/lib/mocha/integration/mini_test/nothing.rb +4 -4
- data/lib/mocha/integration/mini_test/version_13.rb +4 -1
- data/lib/mocha/integration/mini_test/version_140.rb +4 -1
- data/lib/mocha/integration/mini_test/version_141.rb +4 -1
- data/lib/mocha/integration/mini_test/version_142_to_172.rb +4 -1
- data/lib/mocha/integration/mini_test/version_200.rb +4 -1
- data/lib/mocha/integration/mini_test/version_201_to_222.rb +4 -1
- data/lib/mocha/integration/mini_test/version_2110_to_2111.rb +4 -1
- data/lib/mocha/integration/mini_test/version_2112_to_320.rb +4 -1
- data/lib/mocha/integration/mini_test/version_230_to_2101.rb +4 -1
- data/lib/mocha/integration/mini_test.rb +7 -0
- data/lib/mocha/integration/monkey_patcher.rb +5 -7
- data/lib/mocha/integration/test_unit/adapter.rb +5 -6
- data/lib/mocha/integration/test_unit/gem_version_200.rb +5 -2
- data/lib/mocha/integration/test_unit/gem_version_201_to_202.rb +5 -2
- data/lib/mocha/integration/test_unit/gem_version_203_to_220.rb +5 -2
- data/lib/mocha/integration/test_unit/gem_version_230_to_250.rb +5 -2
- data/lib/mocha/integration/test_unit/nothing.rb +4 -4
- data/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb +4 -1
- data/lib/mocha/integration/test_unit.rb +7 -2
- data/lib/mocha/integration.rb +2 -5
- data/lib/mocha/invocation.rb +86 -0
- data/lib/mocha/is_a.rb +0 -2
- data/lib/mocha/logger.rb +0 -4
- data/lib/mocha/macos_version.rb +5 -0
- data/lib/mocha/method_matcher.rb +1 -5
- data/lib/mocha/minitest.rb +9 -0
- data/lib/mocha/mock.rb +102 -58
- data/lib/mocha/mockery.rb +70 -99
- data/lib/mocha/names.rb +2 -12
- data/lib/mocha/not_initialized_error.rb +7 -0
- data/lib/mocha/object_methods.rb +25 -31
- data/lib/mocha/parameter_matchers/all_of.rb +2 -8
- data/lib/mocha/parameter_matchers/any_of.rb +2 -8
- data/lib/mocha/parameter_matchers/any_parameters.rb +3 -9
- data/lib/mocha/parameter_matchers/anything.rb +2 -8
- data/lib/mocha/parameter_matchers/base.rb +6 -12
- data/lib/mocha/parameter_matchers/equals.rb +0 -6
- data/lib/mocha/parameter_matchers/{query_string.rb → equivalent_uri.rb} +15 -15
- data/lib/mocha/parameter_matchers/has_entries.rb +2 -7
- data/lib/mocha/parameter_matchers/has_entry.rb +26 -21
- data/lib/mocha/parameter_matchers/has_key.rb +2 -7
- data/lib/mocha/parameter_matchers/has_keys.rb +53 -0
- data/lib/mocha/parameter_matchers/has_value.rb +2 -7
- data/lib/mocha/parameter_matchers/includes.rb +6 -7
- data/lib/mocha/parameter_matchers/instance_methods.rb +18 -0
- data/lib/mocha/parameter_matchers/instance_of.rb +0 -6
- data/lib/mocha/parameter_matchers/is_a.rb +2 -7
- data/lib/mocha/parameter_matchers/kind_of.rb +2 -6
- data/lib/mocha/parameter_matchers/not.rb +2 -7
- data/lib/mocha/parameter_matchers/optionally.rb +4 -10
- data/lib/mocha/parameter_matchers/regexp_matches.rb +0 -6
- data/lib/mocha/parameter_matchers/responds_with.rb +3 -8
- data/lib/mocha/parameter_matchers/yaml_equivalent.rb +2 -6
- data/lib/mocha/parameter_matchers.rb +3 -4
- data/lib/mocha/parameters_matcher.rb +6 -9
- data/lib/mocha/raised_exception.rb +11 -0
- data/lib/mocha/receivers.rb +10 -14
- data/lib/mocha/return_values.rb +4 -8
- data/lib/mocha/ruby_version.rb +8 -1
- data/lib/mocha/sequence.rb +4 -9
- data/lib/mocha/setup.rb +5 -0
- data/lib/mocha/single_return_value.rb +2 -5
- data/lib/mocha/state_machine.rb +33 -46
- data/lib/mocha/stubbed_method.rb +124 -0
- data/lib/mocha/stubbing_error.rb +2 -13
- data/lib/mocha/test_unit.rb +8 -2
- data/lib/mocha/thrower.rb +4 -6
- data/lib/mocha/thrown_object.rb +12 -0
- data/lib/mocha/version.rb +1 -1
- data/lib/mocha/yield_parameters.rb +7 -17
- data/mocha.gemspec +14 -65
- data/yard-templates/default/layout/html/google_analytics.erb +6 -9
- data/yard-templates/default/layout/html/setup.rb +2 -3
- metadata +25 -247
- data/bin/build-matrix +0 -70
- data/gemfiles/Gemfile.minitest.1.3.0 +0 -7
- data/gemfiles/Gemfile.minitest.1.4.0 +0 -7
- data/gemfiles/Gemfile.minitest.1.4.1 +0 -7
- data/gemfiles/Gemfile.minitest.1.4.2 +0 -7
- data/gemfiles/Gemfile.minitest.2.0.0 +0 -7
- data/gemfiles/Gemfile.minitest.2.0.1 +0 -7
- data/gemfiles/Gemfile.minitest.2.11.0 +0 -7
- data/gemfiles/Gemfile.minitest.2.11.2 +0 -7
- data/gemfiles/Gemfile.minitest.2.3.0 +0 -7
- data/gemfiles/Gemfile.test-unit.2.0.0 +0 -7
- data/gemfiles/Gemfile.test-unit.2.0.1 +0 -7
- data/gemfiles/Gemfile.test-unit.2.0.3 +0 -7
- data/lib/mocha/class_method.rb +0 -119
- data/lib/mocha/integration/test_unit/ruby_version_185_and_below.rb +0 -58
- data/lib/mocha/mini_test.rb +0 -3
- data/lib/mocha/module_method.rb +0 -16
- data/lib/mocha/module_methods.rb +0 -14
- data/lib/mocha/multiple_yields.rb +0 -20
- data/lib/mocha/no_yields.rb +0 -11
- data/lib/mocha/parameter_matchers/object.rb +0 -17
- data/lib/mocha/pretty_parameters.rb +0 -28
- data/lib/mocha/single_yield.rb +0 -18
- data/lib/mocha/standalone.rb +0 -4
- data/lib/mocha/unexpected_invocation.rb +0 -26
- data/lib/mocha_standalone.rb +0 -4
- data/test/acceptance/acceptance_test_helper.rb +0 -41
- data/test/acceptance/bug_18914_test.rb +0 -43
- data/test/acceptance/bug_21465_test.rb +0 -34
- data/test/acceptance/bug_21563_test.rb +0 -25
- data/test/acceptance/exception_rescue_test.rb +0 -55
- data/test/acceptance/expectations_on_multiple_methods_test.rb +0 -55
- data/test/acceptance/expected_invocation_count_test.rb +0 -232
- data/test/acceptance/failure_messages_test.rb +0 -64
- data/test/acceptance/issue_272_test.rb +0 -52
- data/test/acceptance/issue_65_test.rb +0 -63
- data/test/acceptance/issue_70_test.rb +0 -55
- data/test/acceptance/mocha_example_test.rb +0 -98
- data/test/acceptance/mocha_test_result_test.rb +0 -84
- data/test/acceptance/mock_test.rb +0 -100
- data/test/acceptance/mock_with_initializer_block_test.rb +0 -51
- data/test/acceptance/mocked_methods_dispatch_test.rb +0 -78
- data/test/acceptance/multiple_expectations_failure_message_test.rb +0 -68
- data/test/acceptance/optional_parameters_test.rb +0 -70
- data/test/acceptance/parameter_matcher_test.rb +0 -337
- data/test/acceptance/partial_mocks_test.rb +0 -47
- data/test/acceptance/prepend_test.rb +0 -89
- data/test/acceptance/raise_exception_test.rb +0 -39
- data/test/acceptance/return_value_test.rb +0 -52
- data/test/acceptance/sequence_test.rb +0 -192
- data/test/acceptance/states_test.rb +0 -70
- data/test/acceptance/stub_any_instance_method_defined_on_superclass_test.rb +0 -34
- data/test/acceptance/stub_any_instance_method_test.rb +0 -280
- data/test/acceptance/stub_class_method_defined_on_active_record_association_proxy_test.rb +0 -106
- data/test/acceptance/stub_class_method_defined_on_class_test.rb +0 -78
- data/test/acceptance/stub_class_method_defined_on_module_test.rb +0 -75
- data/test/acceptance/stub_class_method_defined_on_superclass_test.rb +0 -112
- data/test/acceptance/stub_everything_test.rb +0 -56
- data/test/acceptance/stub_instance_method_defined_on_active_record_association_proxy_test.rb +0 -93
- data/test/acceptance/stub_instance_method_defined_on_class_and_aliased_test.rb +0 -69
- data/test/acceptance/stub_instance_method_defined_on_class_test.rb +0 -69
- data/test/acceptance/stub_instance_method_defined_on_kernel_module_test.rb +0 -75
- data/test/acceptance/stub_instance_method_defined_on_module_test.rb +0 -78
- data/test/acceptance/stub_instance_method_defined_on_object_class_test.rb +0 -75
- data/test/acceptance/stub_instance_method_defined_on_singleton_class_test.rb +0 -70
- data/test/acceptance/stub_instance_method_defined_on_superclass_test.rb +0 -72
- data/test/acceptance/stub_method_defined_on_module_and_aliased_test.rb +0 -39
- data/test/acceptance/stub_module_method_test.rb +0 -163
- data/test/acceptance/stub_test.rb +0 -52
- data/test/acceptance/stubba_example_test.rb +0 -102
- data/test/acceptance/stubba_test_result_test.rb +0 -66
- data/test/acceptance/stubbing_error_backtrace_test.rb +0 -64
- data/test/acceptance/stubbing_frozen_object_test.rb +0 -88
- data/test/acceptance/stubbing_method_accepting_block_parameter_test.rb +0 -48
- data/test/acceptance/stubbing_method_unnecessarily_test.rb +0 -65
- data/test/acceptance/stubbing_nil_test.rb +0 -61
- data/test/acceptance/stubbing_non_existent_any_instance_method_test.rb +0 -143
- data/test/acceptance/stubbing_non_existent_class_method_test.rb +0 -157
- data/test/acceptance/stubbing_non_existent_instance_method_test.rb +0 -147
- data/test/acceptance/stubbing_non_public_any_instance_method_test.rb +0 -130
- data/test/acceptance/stubbing_non_public_class_method_test.rb +0 -163
- data/test/acceptance/stubbing_non_public_instance_method_test.rb +0 -143
- data/test/acceptance/stubbing_on_non_mock_object_test.rb +0 -64
- data/test/acceptance/stubbing_same_class_method_on_parent_and_child_classes_test.rb +0 -35
- data/test/acceptance/throw_test.rb +0 -45
- data/test/acceptance/unexpected_invocation_test.rb +0 -25
- data/test/acceptance/unstubbing_test.rb +0 -168
- data/test/assertions.rb +0 -8
- data/test/deprecation_disabler.rb +0 -15
- data/test/execution_point.rb +0 -36
- data/test/integration/mini_test_test.rb +0 -8
- data/test/integration/shared_tests.rb +0 -174
- data/test/integration/test_unit_test.rb +0 -8
- data/test/method_definer.rb +0 -24
- data/test/mini_test_result.rb +0 -90
- data/test/minitest_result.rb +0 -49
- data/test/simple_counter.rb +0 -13
- data/test/test_helper.rb +0 -50
- data/test/test_runner.rb +0 -58
- data/test/test_unit_result.rb +0 -20
- data/test/unit/any_instance_method_test.rb +0 -134
- data/test/unit/array_inspect_test.rb +0 -16
- data/test/unit/backtrace_filter_test.rb +0 -19
- data/test/unit/cardinality_test.rb +0 -56
- data/test/unit/central_test.rb +0 -100
- data/test/unit/change_state_side_effect_test.rb +0 -41
- data/test/unit/class_method_test.rb +0 -225
- data/test/unit/class_methods_test.rb +0 -40
- data/test/unit/configuration_test.rb +0 -38
- data/test/unit/date_time_inspect_test.rb +0 -21
- data/test/unit/exception_raiser_test.rb +0 -42
- data/test/unit/expectation_list_test.rb +0 -82
- data/test/unit/expectation_test.rb +0 -497
- data/test/unit/hash_inspect_test.rb +0 -16
- data/test/unit/hooks_test.rb +0 -29
- data/test/unit/in_state_ordering_constraint_test.rb +0 -43
- data/test/unit/method_matcher_test.rb +0 -28
- data/test/unit/mock_test.rb +0 -342
- data/test/unit/mockery_test.rb +0 -151
- data/test/unit/module_methods_test.rb +0 -19
- data/test/unit/multiple_yields_test.rb +0 -18
- data/test/unit/no_yields_test.rb +0 -18
- data/test/unit/object_inspect_test.rb +0 -39
- data/test/unit/object_methods_test.rb +0 -46
- data/test/unit/parameter_matchers/all_of_test.rb +0 -26
- data/test/unit/parameter_matchers/any_of_test.rb +0 -26
- data/test/unit/parameter_matchers/anything_test.rb +0 -21
- data/test/unit/parameter_matchers/equals_test.rb +0 -25
- data/test/unit/parameter_matchers/has_entries_test.rb +0 -51
- data/test/unit/parameter_matchers/has_entry_test.rb +0 -129
- data/test/unit/parameter_matchers/has_key_test.rb +0 -55
- data/test/unit/parameter_matchers/has_value_test.rb +0 -57
- data/test/unit/parameter_matchers/includes_test.rb +0 -102
- data/test/unit/parameter_matchers/instance_of_test.rb +0 -25
- data/test/unit/parameter_matchers/is_a_test.rb +0 -25
- data/test/unit/parameter_matchers/kind_of_test.rb +0 -25
- data/test/unit/parameter_matchers/not_test.rb +0 -26
- data/test/unit/parameter_matchers/regexp_matches_test.rb +0 -46
- data/test/unit/parameter_matchers/responds_with_test.rb +0 -32
- data/test/unit/parameter_matchers/stub_matcher.rb +0 -27
- data/test/unit/parameter_matchers/yaml_equivalent_test.rb +0 -25
- data/test/unit/parameters_matcher_test.rb +0 -121
- data/test/unit/receivers_test.rb +0 -66
- data/test/unit/return_values_test.rb +0 -63
- data/test/unit/sequence_test.rb +0 -104
- data/test/unit/single_return_value_test.rb +0 -14
- data/test/unit/single_yield_test.rb +0 -18
- data/test/unit/state_machine_test.rb +0 -98
- data/test/unit/string_inspect_test.rb +0 -11
- data/test/unit/thrower_test.rb +0 -20
- data/test/unit/yield_parameters_test.rb +0 -93
@@ -0,0 +1,86 @@
|
|
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 = nil)
|
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}#{argument_description}"
|
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
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def argument_description
|
80
|
+
signature = arguments.mocha_inspect
|
81
|
+
signature = signature.gsub(/^\[|\]$/, '')
|
82
|
+
signature = signature.gsub(/^\{|\}$/, '') if arguments.length == 1
|
83
|
+
"(#{signature})"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/mocha/is_a.rb
CHANGED
data/lib/mocha/logger.rb
CHANGED
data/lib/mocha/method_matcher.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module Mocha
|
2
|
-
|
3
2
|
class MethodMatcher
|
4
|
-
|
5
3
|
attr_reader :expected_method_name
|
6
4
|
|
7
5
|
def initialize(expected_method_name)
|
@@ -13,9 +11,7 @@ module Mocha
|
|
13
11
|
end
|
14
12
|
|
15
13
|
def mocha_inspect
|
16
|
-
|
14
|
+
@expected_method_name.to_s
|
17
15
|
end
|
18
|
-
|
19
16
|
end
|
20
|
-
|
21
17
|
end
|
data/lib/mocha/mock.rb
CHANGED
@@ -1,20 +1,25 @@
|
|
1
|
-
require 'metaclass'
|
2
1
|
require 'mocha/expectation'
|
3
2
|
require 'mocha/expectation_list'
|
3
|
+
require 'mocha/invocation'
|
4
4
|
require 'mocha/names'
|
5
5
|
require 'mocha/receivers'
|
6
6
|
require 'mocha/method_matcher'
|
7
7
|
require 'mocha/parameters_matcher'
|
8
|
-
require 'mocha/unexpected_invocation'
|
9
8
|
require 'mocha/argument_iterator'
|
10
9
|
require 'mocha/expectation_error_factory'
|
11
10
|
|
12
11
|
module Mocha
|
13
|
-
|
14
12
|
# Traditional mock object.
|
15
13
|
#
|
16
|
-
#
|
17
|
-
# methods on {Expectation}.
|
14
|
+
# {expects} and {stubs} return an {Expectation} which can be further modified
|
15
|
+
# by methods on {Expectation}.
|
16
|
+
#
|
17
|
+
# {responds_like} and {responds_like_instance_of} both return a {Mock}, and
|
18
|
+
# can therefore, be chained to the original creation methods in {API}.
|
19
|
+
# They force the mock to indicate what it is supposed to be mocking, thus
|
20
|
+
# making it a safer verifying mock. They check that the underlying +responder+
|
21
|
+
# will actually respond to the methods being stubbed, throwing a
|
22
|
+
# +NoMethodError+ upon invocation otherwise.
|
18
23
|
#
|
19
24
|
# Stubs and expectations are basically the same thing. A stub is just an
|
20
25
|
# expectation of zero or more invocations. The {#stubs} method is syntactic
|
@@ -67,15 +72,14 @@ module Mocha
|
|
67
72
|
# different mock objects, use the {Expectation#in_sequence} method to
|
68
73
|
# explicitly define a total or partial ordering of invocations.
|
69
74
|
class Mock
|
70
|
-
|
71
75
|
# Adds an expectation that the specified method must be called exactly once with any parameters.
|
72
76
|
#
|
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.
|
77
|
+
# @return [Expectation] last-built expectation which can be further modified by methods on {Expectation}.
|
75
78
|
#
|
76
79
|
# @overload def expects(method_name)
|
80
|
+
# @param [Symbol,String] method_name name of expected method
|
77
81
|
# @overload def expects(expected_methods_vs_return_values)
|
78
|
-
#
|
82
|
+
# @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
83
|
#
|
80
84
|
# @example Expected method invoked once so no error raised
|
81
85
|
# object = mock()
|
@@ -103,24 +107,26 @@ module Mocha
|
|
103
107
|
# object.expects(:expected_method_one).returns(:result_one)
|
104
108
|
# object.expects(:expected_method_two).returns(:result_two)
|
105
109
|
def expects(method_name_or_hash, backtrace = nil)
|
110
|
+
expectation = nil
|
106
111
|
iterator = ArgumentIterator.new(method_name_or_hash)
|
107
|
-
iterator.each
|
112
|
+
iterator.each do |*args|
|
108
113
|
method_name = args.shift
|
109
114
|
ensure_method_not_already_defined(method_name)
|
110
115
|
expectation = Expectation.new(self, method_name, backtrace)
|
111
|
-
expectation.returns(args.shift)
|
116
|
+
expectation.returns(args.shift) unless args.empty?
|
112
117
|
@expectations.add(expectation)
|
113
|
-
|
118
|
+
end
|
119
|
+
expectation
|
114
120
|
end
|
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()
|
@@ -139,36 +145,48 @@ module Mocha
|
|
139
145
|
# object.stubs(:stubbed_method_one).returns(:result_one)
|
140
146
|
# object.stubs(:stubbed_method_two).returns(:result_two)
|
141
147
|
def stubs(method_name_or_hash, backtrace = nil)
|
148
|
+
expectation = nil
|
142
149
|
iterator = ArgumentIterator.new(method_name_or_hash)
|
143
|
-
iterator.each
|
150
|
+
iterator.each do |*args|
|
144
151
|
method_name = args.shift
|
145
152
|
ensure_method_not_already_defined(method_name)
|
146
153
|
expectation = Expectation.new(self, method_name, backtrace)
|
147
154
|
expectation.at_least(0)
|
148
|
-
expectation.returns(args.shift)
|
155
|
+
expectation.returns(args.shift) unless args.empty?
|
149
156
|
@expectations.add(expectation)
|
150
|
-
|
157
|
+
end
|
158
|
+
expectation
|
151
159
|
end
|
152
160
|
|
153
|
-
# Removes the specified stubbed
|
161
|
+
# Removes the specified stubbed methods (added by calls to {#expects} or {#stubs}) and all expectations associated with them.
|
154
162
|
#
|
155
|
-
# @param [Symbol]
|
163
|
+
# @param [Array<Symbol>] method_names names of methods to unstub.
|
156
164
|
#
|
157
165
|
# @example Invoking an unstubbed method causes error to be raised
|
158
|
-
# object = mock('mock')
|
166
|
+
# object = mock('mock')
|
159
167
|
# object.stubs(:stubbed_method).returns(:result_one)
|
160
168
|
# object.stubbed_method # => :result_one
|
161
169
|
# object.unstub(:stubbed_method)
|
162
170
|
# object.stubbed_method # => unexpected invocation: #<Mock:mock>.stubbed_method()
|
163
|
-
|
164
|
-
|
171
|
+
#
|
172
|
+
# @example Unstubbing multiple methods.
|
173
|
+
# multiplier.unstub(:double, :triple)
|
174
|
+
#
|
175
|
+
# # exactly equivalent to
|
176
|
+
#
|
177
|
+
# multiplier.unstub(:double)
|
178
|
+
# multiplier.unstub(:triple)
|
179
|
+
def unstub(*method_names)
|
180
|
+
method_names.each do |method_name|
|
181
|
+
@expectations.remove_all_matching_method(method_name)
|
182
|
+
end
|
165
183
|
end
|
166
184
|
|
167
|
-
# 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.
|
185
|
+
# Constrains the {Mock} instance so that it can only expect or stub methods to which +responder+ responds publicly. The constraint is only applied at method invocation time.
|
168
186
|
#
|
169
|
-
# A +NoMethodError+ will be raised if the +responder+ does not +#respond_to?+
|
187
|
+
# A +NoMethodError+ will be raised if the +responder+ does not publicly +#respond_to?+ the invoked method (even if the method has been expected or stubbed).
|
170
188
|
#
|
171
|
-
# The {Mock} instance will delegate its +#respond_to?+ method to the +responder+.
|
189
|
+
# The {Mock} instance will delegate its +#respond_to?+ method to the +responder+. However, the +include_all+ parameter is not passed through, so only public methods on the +responder+ will be considered.
|
172
190
|
#
|
173
191
|
# Note that the methods on +responder+ are never actually invoked.
|
174
192
|
#
|
@@ -218,11 +236,11 @@ module Mocha
|
|
218
236
|
self
|
219
237
|
end
|
220
238
|
|
221
|
-
# Constrains the {Mock} instance so that it can only expect or stub methods to which an instance of the +responder_class+ responds. The constraint is only applied at method invocation time. Note that the responder instance is instantiated using +Class#allocate+.
|
239
|
+
# Constrains the {Mock} instance so that it can only expect or stub methods to which an instance of the +responder_class+ responds publicly. The constraint is only applied at method invocation time. Note that the responder instance is instantiated using +Class#allocate+.
|
222
240
|
#
|
223
|
-
# A +NoMethodError+ will be raised if the responder instance does not +#respond_to?+
|
241
|
+
# A +NoMethodError+ will be raised if the responder instance does not publicly +#respond_to?+ the invoked method (even if the method has been expected or stubbed).
|
224
242
|
#
|
225
|
-
# The {Mock} instance will delegate its +#respond_to?+ method to the responder instance.
|
243
|
+
# The {Mock} instance will delegate its +#respond_to?+ method to the responder instance. However, the +include_all+ parameter is not passed through, so only public methods on the +responder+ will be considered.
|
226
244
|
#
|
227
245
|
# Note that the methods on the responder instance are never actually invoked.
|
228
246
|
#
|
@@ -251,7 +269,7 @@ module Mocha
|
|
251
269
|
end
|
252
270
|
|
253
271
|
# @private
|
254
|
-
def initialize(mockery, name = nil, receiver = nil
|
272
|
+
def initialize(mockery, name = nil, receiver = nil)
|
255
273
|
@mockery = mockery
|
256
274
|
@name = name || DefaultName.new(self)
|
257
275
|
@receiver = receiver || DefaultReceiver.new(self)
|
@@ -259,7 +277,7 @@ module Mocha
|
|
259
277
|
@everything_stubbed = false
|
260
278
|
@responder = nil
|
261
279
|
@unexpected_invocation = nil
|
262
|
-
|
280
|
+
@expired = false
|
263
281
|
end
|
264
282
|
|
265
283
|
# @private
|
@@ -269,6 +287,8 @@ module Mocha
|
|
269
287
|
|
270
288
|
alias_method :__stubs__, :stubs
|
271
289
|
|
290
|
+
alias_method :__singleton_class__, :singleton_class
|
291
|
+
|
272
292
|
alias_method :quacks_like, :responds_like
|
273
293
|
alias_method :quacks_like_instance_of, :responds_like_instance_of
|
274
294
|
|
@@ -288,35 +308,26 @@ module Mocha
|
|
288
308
|
end
|
289
309
|
|
290
310
|
# @private
|
291
|
-
def method_missing(symbol, *arguments, &block)
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
else
|
305
|
-
message = @unexpected_invocation.short_description
|
306
|
-
end
|
307
|
-
raise ExpectationErrorFactory.build(message, caller)
|
308
|
-
end
|
311
|
+
def method_missing(symbol, *arguments, &block) # rubocop:disable Style/MethodMissingSuper
|
312
|
+
handle_method_call(symbol, arguments, block)
|
313
|
+
end
|
314
|
+
|
315
|
+
# @private
|
316
|
+
def handle_method_call(symbol, arguments, block)
|
317
|
+
check_expiry
|
318
|
+
check_responder_responds_to(symbol)
|
319
|
+
invocation = Invocation.new(self, symbol, arguments, block)
|
320
|
+
if (matching_expectation_allowing_invocation = all_expectations.match_allowing_invocation(invocation))
|
321
|
+
matching_expectation_allowing_invocation.invoke(invocation)
|
322
|
+
elsif (matching_expectation = all_expectations.match(invocation)) || (!matching_expectation && !@everything_stubbed)
|
323
|
+
raise_unexpected_invocation_error(invocation, matching_expectation)
|
309
324
|
end
|
310
325
|
end
|
311
326
|
|
312
327
|
# @private
|
313
|
-
def
|
314
|
-
if @responder
|
315
|
-
|
316
|
-
@responder.respond_to?(symbol, include_private)
|
317
|
-
else
|
318
|
-
@responder.respond_to?(symbol)
|
319
|
-
end
|
328
|
+
def respond_to_missing?(symbol, _include_all)
|
329
|
+
if @responder
|
330
|
+
@responder.respond_to?(symbol)
|
320
331
|
else
|
321
332
|
@everything_stubbed || all_expectations.matches_method?(symbol)
|
322
333
|
end
|
@@ -327,6 +338,11 @@ module Mocha
|
|
327
338
|
@expectations.verified?(assertion_counter)
|
328
339
|
end
|
329
340
|
|
341
|
+
# @private
|
342
|
+
def __expire__
|
343
|
+
@expired = true
|
344
|
+
end
|
345
|
+
|
330
346
|
# @private
|
331
347
|
def mocha_inspect
|
332
348
|
@name.mocha_inspect
|
@@ -339,7 +355,7 @@ module Mocha
|
|
339
355
|
|
340
356
|
# @private
|
341
357
|
def ensure_method_not_already_defined(method_name)
|
342
|
-
|
358
|
+
__singleton_class__.send(:undef_method, method_name) if __singleton_class__.method_defined?(method_name) || __singleton_class__.private_method_defined?(method_name)
|
343
359
|
end
|
344
360
|
|
345
361
|
# @private
|
@@ -347,6 +363,34 @@ module Mocha
|
|
347
363
|
@expectations.any?
|
348
364
|
end
|
349
365
|
|
350
|
-
|
366
|
+
private
|
367
|
+
|
368
|
+
def raise_unexpected_invocation_error(invocation, matching_expectation)
|
369
|
+
if @unexpected_invocation.nil?
|
370
|
+
@unexpected_invocation = invocation
|
371
|
+
matching_expectation.invoke(invocation) if matching_expectation
|
372
|
+
message = "#{@unexpected_invocation.call_description}\n#{@mockery.mocha_inspect}"
|
373
|
+
else
|
374
|
+
message = @unexpected_invocation.short_call_description
|
375
|
+
end
|
376
|
+
raise ExpectationErrorFactory.build("unexpected invocation: #{message}", caller)
|
377
|
+
end
|
378
|
+
|
379
|
+
def check_responder_responds_to(symbol)
|
380
|
+
if @responder && !@responder.respond_to?(symbol) # rubocop:disable Style/GuardClause
|
381
|
+
raise NoMethodError, "undefined method `#{symbol}' for #{mocha_inspect} which responds like #{@responder.mocha_inspect}"
|
382
|
+
end
|
383
|
+
end
|
351
384
|
|
385
|
+
def check_expiry
|
386
|
+
if @expired # rubocop:disable Style/GuardClause
|
387
|
+
Deprecation.warning(
|
388
|
+
"#{mocha_inspect} was instantiated in one test but it is receiving invocations within another test.",
|
389
|
+
' This can lead to unintended interactions between tests and hence unexpected test failures.',
|
390
|
+
' Ensure that every test correctly cleans up any state that it introduces.',
|
391
|
+
' A Mocha::StubbingError will be raised in this scenario in the future.'
|
392
|
+
)
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
352
396
|
end
|