rspec-mocks 2.13.1 → 2.14.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog.md +45 -4
- data/README.md +1 -1
- data/features/argument_matchers/README.md +2 -2
- data/features/argument_matchers/explicit.feature +2 -3
- data/features/argument_matchers/general_matchers.feature +2 -2
- data/features/argument_matchers/type_matchers.feature +3 -4
- data/features/message_expectations/README.md +2 -2
- data/features/message_expectations/any_instance.feature +2 -2
- data/features/message_expectations/block_local_expectations.feature.pending +3 -3
- data/features/message_expectations/expect_message_using_expect.feature +103 -0
- data/features/message_expectations/expect_message_using_should_receive.feature +118 -0
- data/features/message_expectations/receive_counts.feature +1 -1
- data/features/method_stubs/README.md +1 -1
- data/features/method_stubs/any_instance.feature +11 -11
- data/features/method_stubs/as_null_object.feature +1 -1
- data/features/method_stubs/stub_implementation.feature +2 -2
- data/features/outside_rspec/configuration.feature +0 -20
- data/features/spies/spy_partial_mock_method.feature +34 -0
- data/features/spies/spy_pure_mock_method.feature +76 -0
- data/features/spies/spy_unstubbed_method.feature +18 -0
- data/features/step_definitions/additional_cli_steps.rb +7 -0
- data/features/test_frameworks/test_unit.feature +43 -0
- data/lib/rspec/mocks.rb +9 -34
- data/lib/rspec/mocks/any_instance/chain.rb +8 -2
- data/lib/rspec/mocks/any_instance/expectation_chain.rb +19 -16
- data/lib/rspec/mocks/any_instance/recorder.rb +6 -3
- data/lib/rspec/mocks/any_instance/stub_chain.rb +11 -11
- data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +8 -10
- data/lib/rspec/mocks/argument_list_matcher.rb +7 -3
- data/lib/rspec/mocks/configuration.rb +28 -1
- data/lib/rspec/mocks/deprecation.rb +18 -0
- data/lib/rspec/mocks/error_generator.rb +60 -8
- data/lib/rspec/mocks/errors.rb +1 -1
- data/lib/rspec/mocks/example_methods.rb +39 -3
- data/lib/rspec/mocks/extensions/marshal.rb +4 -10
- data/lib/rspec/mocks/framework.rb +16 -4
- data/lib/rspec/mocks/instance_method_stasher.rb +3 -0
- data/lib/rspec/mocks/matchers/have_received.rb +93 -0
- data/lib/rspec/mocks/matchers/receive.rb +92 -0
- data/lib/rspec/mocks/message_expectation.rb +66 -129
- data/lib/rspec/mocks/method_double.rb +50 -43
- data/lib/rspec/mocks/mutate_const.rb +8 -20
- data/lib/rspec/mocks/proxy.rb +41 -25
- data/lib/rspec/mocks/proxy_for_nil.rb +36 -0
- data/lib/rspec/mocks/space.rb +64 -11
- data/lib/rspec/mocks/stub_chain.rb +51 -0
- data/lib/rspec/mocks/syntax.rb +329 -0
- data/lib/rspec/mocks/targets.rb +69 -0
- data/lib/rspec/mocks/test_double.rb +25 -4
- data/lib/rspec/mocks/version.rb +1 -1
- data/lib/spec/mocks.rb +1 -3
- data/spec/rspec/mocks/and_call_original_spec.rb +8 -0
- data/spec/rspec/mocks/and_yield_spec.rb +6 -6
- data/spec/rspec/mocks/any_instance_spec.rb +43 -31
- data/spec/rspec/mocks/any_number_of_times_spec.rb +6 -0
- data/spec/rspec/mocks/argument_expectation_spec.rb +12 -14
- data/spec/rspec/mocks/at_least_spec.rb +46 -37
- data/spec/rspec/mocks/at_most_spec.rb +12 -12
- data/spec/rspec/mocks/block_return_value_spec.rb +18 -1
- data/spec/rspec/mocks/bug_report_10260_spec.rb +1 -1
- data/spec/rspec/mocks/bug_report_10263_spec.rb +1 -1
- data/spec/rspec/mocks/bug_report_11545_spec.rb +4 -4
- data/spec/rspec/mocks/bug_report_600_spec.rb +1 -1
- data/spec/rspec/mocks/bug_report_7611_spec.rb +1 -1
- data/spec/rspec/mocks/configuration_spec.rb +124 -0
- data/spec/rspec/mocks/double_spec.rb +13 -1
- data/spec/rspec/mocks/failing_argument_matchers_spec.rb +17 -1
- data/spec/rspec/mocks/hash_excluding_matcher_spec.rb +13 -13
- data/spec/rspec/mocks/matchers/have_received_spec.rb +266 -0
- data/spec/rspec/mocks/matchers/receive_spec.rb +318 -0
- data/spec/rspec/mocks/methods_spec.rb +27 -0
- data/spec/rspec/mocks/mock_ordering_spec.rb +4 -4
- data/spec/rspec/mocks/mock_space_spec.rb +94 -39
- data/spec/rspec/mocks/mock_spec.rb +65 -50
- data/spec/rspec/mocks/multiple_return_value_spec.rb +10 -10
- data/spec/rspec/mocks/mutate_const_spec.rb +21 -1
- data/spec/rspec/mocks/nil_expectation_warning_spec.rb +10 -4
- data/spec/rspec/mocks/null_object_mock_spec.rb +11 -2
- data/spec/rspec/mocks/once_counts_spec.rb +5 -5
- data/spec/rspec/mocks/options_hash_spec.rb +4 -4
- data/spec/rspec/mocks/partial_mock_spec.rb +20 -11
- data/spec/rspec/mocks/partial_mock_using_mocks_directly_spec.rb +7 -7
- data/spec/rspec/mocks/passing_argument_matchers_spec.rb +2 -2
- data/spec/rspec/mocks/precise_counts_spec.rb +6 -6
- data/spec/rspec/mocks/serialization_spec.rb +1 -22
- data/spec/rspec/mocks/stash_spec.rb +4 -12
- data/spec/rspec/mocks/stub_implementation_spec.rb +3 -3
- data/spec/rspec/mocks/stub_spec.rb +44 -20
- data/spec/rspec/mocks/stubbed_message_expectations_spec.rb +6 -6
- data/spec/rspec/mocks/twice_counts_spec.rb +6 -6
- data/spec/rspec/mocks_spec.rb +1 -3
- data/spec/spec_helper.rb +25 -1
- metadata +86 -81
- data/features/message_expectations/expect_message.feature +0 -94
- data/lib/rspec/mocks/any_instance.rb +0 -81
- data/lib/rspec/mocks/extensions/psych.rb +0 -23
- data/lib/rspec/mocks/methods.rb +0 -155
- data/lib/rspec/mocks/serialization.rb +0 -34
- data/spec/rspec/mocks/combining_implementation_instructions_spec.rb +0 -197
@@ -4,11 +4,6 @@ module RSpec
|
|
4
4
|
# @private
|
5
5
|
class StubChain < Chain
|
6
6
|
|
7
|
-
# @private
|
8
|
-
def initialize(*args, &block)
|
9
|
-
record(:stub, *args, &block)
|
10
|
-
end
|
11
|
-
|
12
7
|
# @private
|
13
8
|
def expectation_fulfilled?
|
14
9
|
true
|
@@ -16,13 +11,18 @@ module RSpec
|
|
16
11
|
|
17
12
|
private
|
18
13
|
|
14
|
+
def create_message_expectation_on(instance)
|
15
|
+
proxy = ::RSpec::Mocks.proxy_for(instance)
|
16
|
+
expected_from = IGNORED_BACKTRACE_LINE
|
17
|
+
proxy.add_stub(expected_from, *@expectation_args, &@expectation_block)
|
18
|
+
end
|
19
|
+
|
19
20
|
def invocation_order
|
20
21
|
@invocation_order ||= {
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:and_yield => [:with, :stub]
|
22
|
+
:with => [nil],
|
23
|
+
:and_return => [:with, nil],
|
24
|
+
:and_raise => [:with, nil],
|
25
|
+
:and_yield => [:with, nil]
|
26
26
|
}
|
27
27
|
end
|
28
28
|
|
@@ -34,4 +34,4 @@ module RSpec
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
37
|
-
end
|
37
|
+
end
|
@@ -4,22 +4,20 @@ module RSpec
|
|
4
4
|
# @private
|
5
5
|
class StubChainChain < StubChain
|
6
6
|
|
7
|
-
# @private
|
8
|
-
def initialize(*args, &block)
|
9
|
-
record(:stub_chain, *args, &block)
|
10
|
-
end
|
11
|
-
|
12
7
|
private
|
13
8
|
|
9
|
+
def create_message_expectation_on(instance)
|
10
|
+
::RSpec::Mocks::StubChain.stub_chain_on(instance, *@expectation_args, &@expectation_block)
|
11
|
+
end
|
12
|
+
|
14
13
|
def invocation_order
|
15
14
|
@invocation_order ||= {
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:and_yield => [:stub_chain]
|
15
|
+
:and_return => [nil],
|
16
|
+
:and_raise => [nil],
|
17
|
+
:and_yield => [nil]
|
20
18
|
}
|
21
19
|
end
|
22
20
|
end
|
23
21
|
end
|
24
22
|
end
|
25
|
-
end
|
23
|
+
end
|
@@ -30,7 +30,7 @@ module RSpec
|
|
30
30
|
|
31
31
|
# @api public
|
32
32
|
# @param [Array] *expected_args a list of expected literals and/or argument matchers
|
33
|
-
# @param [Block] block a block with arity matching the expected
|
33
|
+
# @param [Block] block a block with arity matching the expected
|
34
34
|
#
|
35
35
|
# Initializes an `ArgumentListMatcher` with a collection of literal
|
36
36
|
# values and/or argument matchers, or a block that handles the evaluation
|
@@ -73,8 +73,12 @@ module RSpec
|
|
73
73
|
return ArgumentMatchers::EqualityProxy.new(arg)
|
74
74
|
end
|
75
75
|
|
76
|
-
def is_matcher?(
|
77
|
-
|
76
|
+
def is_matcher?(object)
|
77
|
+
return false if object.respond_to?(:i_respond_to_everything_so_im_not_really_a_matcher)
|
78
|
+
|
79
|
+
[:failure_message_for_should, :failure_message].any? do |msg|
|
80
|
+
object.respond_to?(msg)
|
81
|
+
end && object.respond_to?(:matches?)
|
78
82
|
end
|
79
83
|
|
80
84
|
def block_passes?(*args)
|
@@ -19,10 +19,37 @@ module RSpec
|
|
19
19
|
#
|
20
20
|
def add_stub_and_should_receive_to(*modules)
|
21
21
|
modules.each do |mod|
|
22
|
-
|
22
|
+
Syntax.enable_should(mod)
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
def syntax=(values)
|
27
|
+
if Array(values).include?(:expect)
|
28
|
+
Syntax.enable_expect
|
29
|
+
else
|
30
|
+
Syntax.disable_expect
|
31
|
+
end
|
32
|
+
|
33
|
+
if Array(values).include?(:should)
|
34
|
+
Syntax.enable_should
|
35
|
+
else
|
36
|
+
Syntax.disable_should
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def syntax
|
41
|
+
syntaxes = []
|
42
|
+
syntaxes << :should if Syntax.should_enabled?
|
43
|
+
syntaxes << :expect if Syntax.expect_enabled?
|
44
|
+
syntaxes
|
45
|
+
end
|
25
46
|
end
|
47
|
+
|
48
|
+
def self.configuration
|
49
|
+
@configuration ||= Configuration.new
|
50
|
+
end
|
51
|
+
|
52
|
+
configuration.syntax = [:should, :expect]
|
26
53
|
end
|
27
54
|
end
|
28
55
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Mocks
|
3
|
+
module Deprecation
|
4
|
+
# @private
|
5
|
+
#
|
6
|
+
# Used internally to print deprecation warnings
|
7
|
+
def deprecate(deprecated, options={})
|
8
|
+
message = "DEPRECATION: #{deprecated} is deprecated."
|
9
|
+
message << " Use #{options[:replacement]} instead." if options[:replacement]
|
10
|
+
message << " Called from #{caller(0)[2]}."
|
11
|
+
warn message
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
extend(Mocks::Deprecation) unless respond_to?(:deprecate)
|
17
|
+
end
|
18
|
+
|
@@ -23,27 +23,59 @@ module RSpec
|
|
23
23
|
# @private
|
24
24
|
def raise_unexpected_message_args_error(expectation, *args)
|
25
25
|
expected_args = format_args(*expectation.expected_args)
|
26
|
-
actual_args =
|
26
|
+
actual_args = format_received_args(*args)
|
27
27
|
__raise "#{intro} received #{expectation.message.inspect} with unexpected arguments\n expected: #{expected_args}\n got: #{actual_args}"
|
28
28
|
end
|
29
29
|
|
30
30
|
# @private
|
31
31
|
def raise_missing_default_stub_error(expectation, *args)
|
32
32
|
expected_args = format_args(*expectation.expected_args)
|
33
|
-
actual_args =
|
33
|
+
actual_args = format_received_args(*args)
|
34
34
|
__raise "#{intro} received #{expectation.message.inspect} with unexpected arguments\n expected: #{expected_args}\n got: #{actual_args}\n Please stub a default value first if message might be received with other args as well. \n"
|
35
35
|
end
|
36
36
|
|
37
37
|
# @private
|
38
38
|
def raise_similar_message_args_error(expectation, *args_for_multiple_calls)
|
39
39
|
expected_args = format_args(*expectation.expected_args)
|
40
|
-
actual_args = args_for_multiple_calls.collect {|a|
|
40
|
+
actual_args = args_for_multiple_calls.collect {|a| format_received_args(*a)}.join(", ")
|
41
41
|
__raise "#{intro} received #{expectation.message.inspect} with unexpected arguments\n expected: #{expected_args}\n got: #{actual_args}"
|
42
42
|
end
|
43
43
|
|
44
44
|
# @private
|
45
|
-
def raise_expectation_error(message, expected_received_count, actual_received_count, *args)
|
46
|
-
|
45
|
+
def raise_expectation_error(message, expected_received_count, argument_list_matcher, actual_received_count, expectation_count_type, *args)
|
46
|
+
expected_part = expected_part_of_expectation_error(expected_received_count, expectation_count_type, argument_list_matcher)
|
47
|
+
received_part = received_part_of_expectation_error(actual_received_count, *args)
|
48
|
+
__raise "(#{intro}).#{message}#{format_args(*args)}\n #{expected_part}\n #{received_part}"
|
49
|
+
end
|
50
|
+
|
51
|
+
# @private
|
52
|
+
def received_part_of_expectation_error(actual_received_count, *args)
|
53
|
+
"received: #{count_message(actual_received_count)}" +
|
54
|
+
method_call_args_description(args)
|
55
|
+
end
|
56
|
+
|
57
|
+
# @private
|
58
|
+
def expected_part_of_expectation_error(expected_received_count, expectation_count_type, argument_list_matcher)
|
59
|
+
"expected: #{count_message(expected_received_count, expectation_count_type)}" +
|
60
|
+
method_call_args_description(argument_list_matcher.expected_args)
|
61
|
+
end
|
62
|
+
|
63
|
+
# @private
|
64
|
+
def method_call_args_description(args)
|
65
|
+
if args.first.is_a?(ArgumentMatchers::AnyArgsMatcher)
|
66
|
+
" with any arguments"
|
67
|
+
elsif args.first.is_a?(ArgumentMatchers::NoArgsMatcher)
|
68
|
+
" with no arguments"
|
69
|
+
elsif args.length > 0
|
70
|
+
" with arguments: #{args.inspect.gsub(/\A\[(.+)\]\z/, '(\1)')}"
|
71
|
+
else
|
72
|
+
""
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# @private
|
77
|
+
def describe_expectation(message, expected_received_count, actual_received_count, *args)
|
78
|
+
"have received #{message}#{format_args(*args)} #{count_message(expected_received_count)}"
|
47
79
|
end
|
48
80
|
|
49
81
|
# @private
|
@@ -72,6 +104,18 @@ module RSpec
|
|
72
104
|
"available on a partial mock object."
|
73
105
|
end
|
74
106
|
|
107
|
+
# @private
|
108
|
+
def raise_expectation_on_unstubbed_method(method)
|
109
|
+
__raise "#{intro} expected to have received #{method}, but that " +
|
110
|
+
"method has not been stubbed."
|
111
|
+
end
|
112
|
+
|
113
|
+
# @private
|
114
|
+
def raise_expectation_on_mocked_method(method)
|
115
|
+
__raise "#{intro} expected to have received #{method}, but that " +
|
116
|
+
"method has been mocked instead of stubbed."
|
117
|
+
end
|
118
|
+
|
75
119
|
private
|
76
120
|
|
77
121
|
def intro
|
@@ -105,8 +149,17 @@ module RSpec
|
|
105
149
|
args.collect {|arg| arg.respond_to?(:description) ? arg.description : arg.inspect}.join(", ")
|
106
150
|
end
|
107
151
|
|
108
|
-
def
|
109
|
-
|
152
|
+
def format_received_args(*args)
|
153
|
+
args.empty? ? "(no args)" : "(" + received_arg_list(*args) + ")"
|
154
|
+
end
|
155
|
+
|
156
|
+
def received_arg_list(*args)
|
157
|
+
args.collect(&:inspect).join(", ")
|
158
|
+
end
|
159
|
+
|
160
|
+
def count_message(count, expectation_count_type=nil)
|
161
|
+
return "at least #{pretty_print(count.abs)}" if count < 0 || expectation_count_type == :at_least
|
162
|
+
return "at most #{pretty_print(count)}" if expectation_count_type == :at_most
|
110
163
|
return pretty_print(count)
|
111
164
|
end
|
112
165
|
|
@@ -117,4 +170,3 @@ module RSpec
|
|
117
170
|
end
|
118
171
|
end
|
119
172
|
end
|
120
|
-
|
data/lib/rspec/mocks/errors.rb
CHANGED
@@ -31,13 +31,15 @@ module RSpec
|
|
31
31
|
declare_double('Double', *args)
|
32
32
|
end
|
33
33
|
|
34
|
-
#
|
34
|
+
# Deprecated: Use [double](#double-instance_method).
|
35
35
|
def mock(*args)
|
36
|
+
RSpec.deprecate "mock", :replacement => "double"
|
36
37
|
declare_double('Mock', *args)
|
37
38
|
end
|
38
39
|
|
39
|
-
#
|
40
|
+
# Deprecated: Use [double](#double-instance_method).
|
40
41
|
def stub(*args)
|
42
|
+
RSpec.deprecate "stub", :replacement => "double"
|
41
43
|
declare_double('Stub', *args)
|
42
44
|
end
|
43
45
|
|
@@ -47,7 +49,7 @@ module RSpec
|
|
47
49
|
# nil. This is to prevent false-positives and to catch potential bugs
|
48
50
|
# early on.
|
49
51
|
def allow_message_expectations_on_nil
|
50
|
-
|
52
|
+
RSpec::Mocks.space.proxy_for(nil).warn_about_expectations = false
|
51
53
|
end
|
52
54
|
|
53
55
|
# Stubs the named constant with the given value.
|
@@ -107,6 +109,36 @@ module RSpec
|
|
107
109
|
ConstantMutator.hide(constant_name)
|
108
110
|
end
|
109
111
|
|
112
|
+
# Verifies that the given object received the expected message during the
|
113
|
+
# course of the test. The method must have previously been stubbed in
|
114
|
+
# order for messages to be verified.
|
115
|
+
#
|
116
|
+
# Stubbing and verifying messages received in this way implements the
|
117
|
+
# Test Spy pattern.
|
118
|
+
#
|
119
|
+
# @param method_name [Symbol] name of the method expected to have been
|
120
|
+
# called.
|
121
|
+
#
|
122
|
+
# @example
|
123
|
+
#
|
124
|
+
# invitation = double('invitation', accept: true)
|
125
|
+
# user.accept_invitation(invitation)
|
126
|
+
# expect(invitation).to have_received(:accept)
|
127
|
+
#
|
128
|
+
# # You can also use most message expectations:
|
129
|
+
# expect(invitation).to have_received(:accept).with(mailer).once
|
130
|
+
def have_received(method_name)
|
131
|
+
Matchers::HaveReceived.new(method_name)
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.included(klass)
|
135
|
+
klass.class_eval do
|
136
|
+
# This gets mixed in so that if `RSpec::Matchers` is included in
|
137
|
+
# `klass` later, it's definition of `expect` will take precedence.
|
138
|
+
include ExpectHost unless method_defined?(:expect)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
110
142
|
private
|
111
143
|
|
112
144
|
def declare_double(declared_as, *args)
|
@@ -115,6 +147,10 @@ module RSpec
|
|
115
147
|
RSpec::Mocks::Mock.new(*args)
|
116
148
|
end
|
117
149
|
|
150
|
+
# This module exists to host the `expect` method for cases where
|
151
|
+
# rspec-mocks is used w/o rspec-expectations.
|
152
|
+
module ExpectHost
|
153
|
+
end
|
118
154
|
end
|
119
155
|
end
|
120
156
|
end
|
@@ -2,18 +2,12 @@ module Marshal
|
|
2
2
|
class << self
|
3
3
|
def dump_with_mocks(*args)
|
4
4
|
object = args.shift
|
5
|
-
return dump_without_mocks(*args.unshift(object)) unless object.instance_variable_defined?(:@mock_proxy)
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
object.__send__(:remove_instance_variable, :@mock_proxy)
|
11
|
-
|
12
|
-
begin
|
13
|
-
dump_without_mocks(*args.unshift(object.dup))
|
14
|
-
ensure
|
15
|
-
object.instance_variable_set(:@mock_proxy,mp)
|
6
|
+
if ( ::RSpec::Mocks.space && !::RSpec::Mocks.space.registered?(object) ) || NilClass === object
|
7
|
+
return dump_without_mocks(*args.unshift(object))
|
16
8
|
end
|
9
|
+
|
10
|
+
dump_without_mocks(*args.unshift(object.dup))
|
17
11
|
end
|
18
12
|
|
19
13
|
alias_method :dump_without_mocks, :dump
|
@@ -2,13 +2,14 @@
|
|
2
2
|
# supports wrapping rspec's mocking functionality without invading every
|
3
3
|
# object in the system.
|
4
4
|
|
5
|
-
require 'rspec/mocks/
|
5
|
+
require 'rspec/mocks/deprecation'
|
6
6
|
require 'rspec/mocks/extensions/instance_exec'
|
7
7
|
require 'rspec/mocks/instance_method_stasher'
|
8
8
|
require 'rspec/mocks/method_double'
|
9
|
-
require 'rspec/mocks/methods'
|
10
9
|
require 'rspec/mocks/argument_matchers'
|
10
|
+
require 'rspec/mocks/example_methods'
|
11
11
|
require 'rspec/mocks/proxy'
|
12
|
+
require 'rspec/mocks/proxy_for_nil'
|
12
13
|
require 'rspec/mocks/test_double'
|
13
14
|
require 'rspec/mocks/mock'
|
14
15
|
require 'rspec/mocks/argument_list_matcher'
|
@@ -17,6 +18,17 @@ require 'rspec/mocks/order_group'
|
|
17
18
|
require 'rspec/mocks/errors'
|
18
19
|
require 'rspec/mocks/error_generator'
|
19
20
|
require 'rspec/mocks/space'
|
20
|
-
require 'rspec/mocks/
|
21
|
-
require 'rspec/mocks/any_instance'
|
21
|
+
require 'rspec/mocks/extensions/marshal'
|
22
|
+
require 'rspec/mocks/any_instance/chain'
|
23
|
+
require 'rspec/mocks/any_instance/stub_chain'
|
24
|
+
require 'rspec/mocks/any_instance/stub_chain_chain'
|
25
|
+
require 'rspec/mocks/any_instance/expectation_chain'
|
26
|
+
require 'rspec/mocks/any_instance/message_chains'
|
27
|
+
require 'rspec/mocks/any_instance/recorder'
|
22
28
|
require 'rspec/mocks/mutate_const'
|
29
|
+
require 'rspec/mocks/matchers/have_received'
|
30
|
+
require 'rspec/mocks/matchers/receive'
|
31
|
+
require 'rspec/mocks/stub_chain'
|
32
|
+
require 'rspec/mocks/targets'
|
33
|
+
require 'rspec/mocks/syntax'
|
34
|
+
require 'rspec/mocks/configuration'
|
@@ -75,6 +75,9 @@ module RSpec
|
|
75
75
|
def restore
|
76
76
|
return unless @method_is_stashed
|
77
77
|
|
78
|
+
if @klass.__send__(:method_defined?, @method)
|
79
|
+
@klass.__send__(:undef_method, @method)
|
80
|
+
end
|
78
81
|
@klass.__send__(:alias_method, @method, stashed_method_name)
|
79
82
|
@klass.__send__(:remove_method, stashed_method_name)
|
80
83
|
@method_is_stashed = false
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Mocks
|
3
|
+
module Matchers
|
4
|
+
class HaveReceived
|
5
|
+
COUNT_CONSTRAINTS = %w(exactly at_least at_most times once twice)
|
6
|
+
ARGS_CONSTRAINTS = %w(with)
|
7
|
+
CONSTRAINTS = COUNT_CONSTRAINTS + ARGS_CONSTRAINTS
|
8
|
+
|
9
|
+
def initialize(method_name)
|
10
|
+
@method_name = method_name
|
11
|
+
@constraints = []
|
12
|
+
@subject = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def matches?(subject)
|
16
|
+
@subject = subject
|
17
|
+
@expectation = expect
|
18
|
+
expected_messages_received?
|
19
|
+
end
|
20
|
+
|
21
|
+
def does_not_match?(subject)
|
22
|
+
@subject = subject
|
23
|
+
ensure_count_unconstrained
|
24
|
+
@expectation = expect.never
|
25
|
+
expected_messages_received?
|
26
|
+
end
|
27
|
+
|
28
|
+
def failure_message
|
29
|
+
generate_failure_message
|
30
|
+
end
|
31
|
+
|
32
|
+
def negative_failure_message
|
33
|
+
generate_failure_message
|
34
|
+
end
|
35
|
+
|
36
|
+
def description
|
37
|
+
expect.description
|
38
|
+
end
|
39
|
+
|
40
|
+
CONSTRAINTS.each do |expectation|
|
41
|
+
define_method expectation do |*args|
|
42
|
+
@constraints << [expectation, *args]
|
43
|
+
self
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def expect
|
50
|
+
expectation = mock_proxy.build_expectation(@method_name)
|
51
|
+
apply_constraints_to expectation
|
52
|
+
expectation
|
53
|
+
end
|
54
|
+
|
55
|
+
def apply_constraints_to(expectation)
|
56
|
+
@constraints.each do |constraint|
|
57
|
+
expectation.send(*constraint)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def ensure_count_unconstrained
|
62
|
+
if count_constraint
|
63
|
+
raise RSpec::Mocks::MockExpectationError,
|
64
|
+
"can't use #{count_constraint} when negative"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def count_constraint
|
69
|
+
@constraints.map(&:first).detect do |constraint|
|
70
|
+
COUNT_CONSTRAINTS.include?(constraint)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def generate_failure_message
|
75
|
+
mock_proxy.check_for_unexpected_arguments(@expectation)
|
76
|
+
@expectation.generate_error
|
77
|
+
rescue RSpec::Mocks::MockExpectationError => error
|
78
|
+
error.message
|
79
|
+
end
|
80
|
+
|
81
|
+
def expected_messages_received?
|
82
|
+
mock_proxy.replay_received_message_on @expectation
|
83
|
+
@expectation.expected_messages_received?
|
84
|
+
end
|
85
|
+
|
86
|
+
def mock_proxy
|
87
|
+
RSpec::Mocks.proxy_for(@subject)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|