rspec-mocks 3.0.0.beta1 → 3.0.0.beta2
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.
- data.tar.gz.sig +1 -1
- data/Changelog.md +95 -3
- data/README.md +27 -13
- data/features/README.md +15 -7
- data/features/argument_matchers/README.md +5 -5
- data/features/argument_matchers/explicit.feature +6 -6
- data/features/argument_matchers/general_matchers.feature +4 -4
- data/features/argument_matchers/type_matchers.feature +2 -2
- data/features/message_expectations/README.md +29 -27
- data/features/message_expectations/call_original.feature +0 -1
- data/features/message_expectations/message_chains_using_expect.feature +49 -0
- data/features/method_stubs/README.md +2 -1
- data/features/method_stubs/{any_instance.feature → allow_any_instance_of.feature} +12 -12
- data/features/method_stubs/{stub_chain.feature → receive_message_chain.feature} +3 -3
- data/features/method_stubs/to_ary.feature +1 -1
- data/features/mutating_constants/stub_defined_constant.feature +0 -1
- data/features/outside_rspec/standalone.feature +1 -1
- data/features/spies/spy_pure_mock_method.feature +1 -1
- data/features/test_frameworks/test_unit.feature +21 -10
- data/features/verifying_doubles/README.md +17 -0
- data/features/verifying_doubles/class_doubles.feature +1 -16
- data/features/verifying_doubles/dynamic_classes.feature +0 -1
- data/features/verifying_doubles/{introduction.feature → instance_doubles.feature} +41 -23
- data/features/verifying_doubles/partial_doubles.feature +2 -2
- data/lib/rspec/mocks.rb +69 -82
- data/lib/rspec/mocks/any_instance/expect_chain_chain.rb +35 -0
- data/lib/rspec/mocks/any_instance/expectation_chain.rb +1 -2
- data/lib/rspec/mocks/any_instance/recorder.rb +52 -18
- data/lib/rspec/mocks/any_instance/stub_chain.rb +1 -1
- data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +4 -0
- data/lib/rspec/mocks/argument_list_matcher.rb +10 -44
- data/lib/rspec/mocks/argument_matchers.rb +132 -163
- data/lib/rspec/mocks/configuration.rb +28 -4
- data/lib/rspec/mocks/error_generator.rb +46 -13
- data/lib/rspec/mocks/example_methods.rb +13 -12
- data/lib/rspec/mocks/extensions/marshal.rb +1 -1
- data/lib/rspec/mocks/framework.rb +3 -4
- data/lib/rspec/mocks/instance_method_stasher.rb +2 -3
- data/lib/rspec/mocks/matchers/have_received.rb +8 -6
- data/lib/rspec/mocks/matchers/receive.rb +28 -20
- data/lib/rspec/mocks/matchers/receive_message_chain.rb +65 -0
- data/lib/rspec/mocks/matchers/receive_messages.rb +3 -2
- data/lib/rspec/mocks/message_chain.rb +91 -0
- data/lib/rspec/mocks/message_expectation.rb +86 -80
- data/lib/rspec/mocks/method_double.rb +2 -11
- data/lib/rspec/mocks/method_reference.rb +82 -23
- data/lib/rspec/mocks/method_signature_verifier.rb +207 -0
- data/lib/rspec/mocks/mutate_const.rb +34 -50
- data/lib/rspec/mocks/object_reference.rb +0 -1
- data/lib/rspec/mocks/proxy.rb +70 -13
- data/lib/rspec/mocks/ruby_features.rb +24 -0
- data/lib/rspec/mocks/space.rb +105 -31
- data/lib/rspec/mocks/standalone.rb +2 -2
- data/lib/rspec/mocks/syntax.rb +43 -8
- data/lib/rspec/mocks/targets.rb +16 -7
- data/lib/rspec/mocks/test_double.rb +41 -15
- data/lib/rspec/mocks/verifying_double.rb +51 -4
- data/lib/rspec/mocks/verifying_message_expecation.rb +12 -12
- data/lib/rspec/mocks/verifying_proxy.rb +32 -19
- data/lib/rspec/mocks/version.rb +1 -1
- data/spec/rspec/mocks/and_call_original_spec.rb +28 -7
- data/spec/rspec/mocks/and_return_spec.rb +23 -0
- data/spec/rspec/mocks/and_yield_spec.rb +1 -2
- data/spec/rspec/mocks/any_instance_spec.rb +33 -17
- data/spec/rspec/mocks/array_including_matcher_spec.rb +6 -6
- data/spec/rspec/mocks/before_all_spec.rb +132 -0
- data/spec/rspec/mocks/block_return_value_spec.rb +12 -1
- data/spec/rspec/mocks/combining_implementation_instructions_spec.rb +9 -11
- data/spec/rspec/mocks/configuration_spec.rb +14 -1
- data/spec/rspec/mocks/double_spec.rb +867 -24
- data/spec/rspec/mocks/example_methods_spec.rb +13 -0
- data/spec/rspec/mocks/extensions/marshal_spec.rb +17 -17
- data/spec/rspec/mocks/failing_argument_matchers_spec.rb +29 -1
- data/spec/rspec/mocks/hash_excluding_matcher_spec.rb +12 -12
- data/spec/rspec/mocks/hash_including_matcher_spec.rb +21 -17
- data/spec/rspec/mocks/instance_method_stasher_spec.rb +2 -3
- data/spec/rspec/mocks/matchers/have_received_spec.rb +7 -0
- data/spec/rspec/mocks/matchers/receive_message_chain_spec.rb +198 -0
- data/spec/rspec/mocks/matchers/receive_messages_spec.rb +2 -2
- data/spec/rspec/mocks/matchers/receive_spec.rb +19 -6
- data/spec/rspec/mocks/method_signature_verifier_spec.rb +272 -0
- data/spec/rspec/mocks/methods_spec.rb +0 -1
- data/spec/rspec/mocks/multiple_return_value_spec.rb +2 -2
- data/spec/rspec/mocks/mutate_const_spec.rb +24 -1
- data/spec/rspec/mocks/nil_expectation_warning_spec.rb +6 -22
- data/spec/rspec/mocks/null_object_mock_spec.rb +13 -7
- data/spec/rspec/mocks/options_hash_spec.rb +3 -3
- data/spec/rspec/mocks/{partial_mock_spec.rb → partial_double_spec.rb} +5 -2
- data/spec/rspec/mocks/{partial_mock_using_mocks_directly_spec.rb → partial_double_using_mocks_directly_spec.rb} +1 -1
- data/spec/rspec/mocks/passing_argument_matchers_spec.rb +18 -0
- data/spec/rspec/mocks/serialization_spec.rb +1 -0
- data/spec/rspec/mocks/space_spec.rb +218 -7
- data/spec/rspec/mocks/stub_chain_spec.rb +6 -0
- data/spec/rspec/mocks/stub_spec.rb +0 -6
- data/spec/rspec/mocks/syntax_spec.rb +19 -0
- data/spec/rspec/mocks/test_double_spec.rb +0 -1
- data/spec/rspec/mocks/verifying_double_spec.rb +281 -18
- data/spec/rspec/mocks/verifying_message_expecation_spec.rb +7 -6
- data/spec/rspec/mocks_spec.rb +168 -42
- data/spec/spec_helper.rb +34 -22
- metadata +94 -63
- metadata.gz.sig +0 -0
- checksums.yaml +0 -15
- checksums.yaml.gz.sig +0 -2
- data/features/outside_rspec/configuration.feature +0 -60
- data/lib/rspec/mocks/arity_calculator.rb +0 -66
- data/lib/rspec/mocks/errors.rb +0 -12
- data/lib/rspec/mocks/mock.rb +0 -7
- data/lib/rspec/mocks/proxy_for_nil.rb +0 -37
- data/lib/rspec/mocks/stub_chain.rb +0 -51
- data/spec/rspec/mocks/argument_expectation_spec.rb +0 -32
- data/spec/rspec/mocks/arity_calculator_spec.rb +0 -95
- data/spec/rspec/mocks/mock_space_spec.rb +0 -113
- data/spec/rspec/mocks/mock_spec.rb +0 -788
@@ -39,20 +39,44 @@ module RSpec
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
|
43
|
-
|
42
|
+
# Provides the ability to set either `expect`,
|
43
|
+
# `should` or both syntaxes. RSpec uses `expect`
|
44
|
+
# syntax by default. This is needed if you want to
|
45
|
+
# explicitly enable `should` syntax and/or explicitly
|
46
|
+
# disable `expect` syntax.
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
#
|
50
|
+
# RSpec.configure do |rspec|
|
51
|
+
# rspec.mock_with :rspec do |mocks|
|
52
|
+
# mocks.syntax = [:expect, :should]
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
def syntax=(*values)
|
57
|
+
syntaxes = values.flatten
|
58
|
+
if syntaxes.include?(:expect)
|
44
59
|
Syntax.enable_expect
|
45
60
|
else
|
46
61
|
Syntax.disable_expect
|
47
62
|
end
|
48
63
|
|
49
|
-
if
|
64
|
+
if syntaxes.include?(:should)
|
50
65
|
Syntax.enable_should
|
51
66
|
else
|
52
67
|
Syntax.disable_should
|
53
68
|
end
|
54
69
|
end
|
55
70
|
|
71
|
+
# Returns an array with a list of syntaxes
|
72
|
+
# that are enabled.
|
73
|
+
#
|
74
|
+
# @example
|
75
|
+
#
|
76
|
+
# unless RSpec::Mocks.configuration.syntax.include?(:expect)
|
77
|
+
# raise "this RSpec extension gem requires the rspec-mocks `:expect` syntax"
|
78
|
+
# end
|
79
|
+
#
|
56
80
|
def syntax
|
57
81
|
syntaxes = []
|
58
82
|
syntaxes << :should if Syntax.should_enabled?
|
@@ -84,7 +108,7 @@ module RSpec
|
|
84
108
|
end
|
85
109
|
|
86
110
|
# When set to true, partial mocks will be verified the same as object
|
87
|
-
# doubles. Any stubs will have their
|
111
|
+
# doubles. Any stubs will have their arguments checked against the original
|
88
112
|
# method, and methods that do not exist cannot be stubbed.
|
89
113
|
def verify_partial_doubles=(val)
|
90
114
|
@verify_partial_doubles = !!val
|
@@ -1,5 +1,25 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Mocks
|
3
|
+
# @public
|
4
|
+
# Raised when a message expectation is not satisfied.
|
5
|
+
MockExpectationError = Class.new(Exception)
|
6
|
+
|
7
|
+
# @public
|
8
|
+
# Raised when a test double is used after it has been torn
|
9
|
+
# down (typically at the end of an rspec-core example).
|
10
|
+
ExpiredTestDoubleError = Class.new(MockExpectationError)
|
11
|
+
|
12
|
+
# @public
|
13
|
+
# Raised when doubles or partial doubles are used outside of the per-test lifecycle.
|
14
|
+
OutsideOfExampleError = Class.new(StandardError)
|
15
|
+
|
16
|
+
# @private
|
17
|
+
UnsupportedMatcherError = Class.new(StandardError)
|
18
|
+
# @private
|
19
|
+
NegationUnsupportedError = Class.new(StandardError)
|
20
|
+
|
21
|
+
VerifyingDoubleNotDefinedError = Class.new(StandardError)
|
22
|
+
|
3
23
|
# @private
|
4
24
|
class ErrorGenerator
|
5
25
|
attr_writer :opts
|
@@ -56,13 +76,26 @@ module RSpec
|
|
56
76
|
end
|
57
77
|
|
58
78
|
# @private
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
actual
|
79
|
+
def raise_non_public_error(method_name, visibility)
|
80
|
+
raise NoMethodError, "%s method `%s' called on %s" % [
|
81
|
+
visibility, method_name, intro
|
63
82
|
]
|
64
83
|
end
|
65
84
|
|
85
|
+
# @private
|
86
|
+
def raise_invalid_arguments_error(verifier)
|
87
|
+
__raise verifier.error_message
|
88
|
+
end
|
89
|
+
|
90
|
+
# @private
|
91
|
+
def raise_expired_test_double_error
|
92
|
+
raise ExpiredTestDoubleError,
|
93
|
+
"#{intro} was originally created in one example but has leaked into " +
|
94
|
+
"another example and can no longer be used. rspec-mocks' doubles are " +
|
95
|
+
"designed to only last for one example, and you need to create a new " +
|
96
|
+
"one in each example you wish to use it for."
|
97
|
+
end
|
98
|
+
|
66
99
|
# @private
|
67
100
|
def received_part_of_expectation_error(actual_received_count, *args)
|
68
101
|
"received: #{count_message(actual_received_count)}" +
|
@@ -112,14 +145,14 @@ module RSpec
|
|
112
145
|
end
|
113
146
|
|
114
147
|
# @private
|
115
|
-
def raise_wrong_arity_error(args_to_yield,
|
116
|
-
__raise "#{intro} yielded |#{arg_list(*args_to_yield)}| to block with
|
148
|
+
def raise_wrong_arity_error(args_to_yield, signature)
|
149
|
+
__raise "#{intro} yielded |#{arg_list(*args_to_yield)}| to block with #{signature.description}"
|
117
150
|
end
|
118
151
|
|
119
152
|
# @private
|
120
|
-
def
|
121
|
-
__raise "#{intro} is a pure
|
122
|
-
"available on a partial
|
153
|
+
def raise_only_valid_on_a_partial_double(method)
|
154
|
+
__raise "#{intro} is a pure test double. `#{method}` is only " +
|
155
|
+
"available on a partial double."
|
123
156
|
end
|
124
157
|
|
125
158
|
# @private
|
@@ -189,12 +222,12 @@ module RSpec
|
|
189
222
|
end
|
190
223
|
|
191
224
|
def count_message(count, expectation_count_type=nil)
|
192
|
-
return "at least #{
|
193
|
-
return "at most #{
|
194
|
-
return
|
225
|
+
return "at least #{times(count.abs)}" if count < 0 || expectation_count_type == :at_least
|
226
|
+
return "at most #{times(count)}" if expectation_count_type == :at_most
|
227
|
+
return times(count)
|
195
228
|
end
|
196
229
|
|
197
|
-
def
|
230
|
+
def times(count)
|
198
231
|
"#{count} time#{count == 1 ? '' : 's'}"
|
199
232
|
end
|
200
233
|
|
@@ -12,9 +12,9 @@ module RSpec
|
|
12
12
|
# @param name [String/Symbol] (optional) used in
|
13
13
|
# clarify intent
|
14
14
|
# @param stubs (Hash) (optional) hash of message/return-value pairs
|
15
|
-
# @return (
|
15
|
+
# @return (Double)
|
16
16
|
#
|
17
|
-
# Constructs an instance of [RSpec::Mocks::
|
17
|
+
# Constructs an instance of [RSpec::Mocks::Double](RSpec::Mocks::Double) configured
|
18
18
|
# with an optional name, used for reporting in failure messages, and an optional
|
19
19
|
# hash of message/return-value pairs.
|
20
20
|
#
|
@@ -28,7 +28,7 @@ module RSpec
|
|
28
28
|
# card.rank #=> "A"
|
29
29
|
#
|
30
30
|
def double(*args)
|
31
|
-
declare_double(
|
31
|
+
ExampleMethods.declare_double(Double, *args)
|
32
32
|
end
|
33
33
|
|
34
34
|
# @overload instance_double(doubled_class)
|
@@ -43,7 +43,7 @@ module RSpec
|
|
43
43
|
# [double](double).
|
44
44
|
def instance_double(doubled_class, *args)
|
45
45
|
ref = ObjectReference.for(doubled_class)
|
46
|
-
declare_verifying_double(InstanceVerifyingDouble, ref, *args)
|
46
|
+
ExampleMethods.declare_verifying_double(InstanceVerifyingDouble, ref, *args)
|
47
47
|
end
|
48
48
|
|
49
49
|
# @overload class_double(doubled_class)
|
@@ -58,7 +58,7 @@ module RSpec
|
|
58
58
|
# [double](double).
|
59
59
|
def class_double(doubled_class, *args)
|
60
60
|
ref = ObjectReference.for(doubled_class)
|
61
|
-
declare_verifying_double(ClassVerifyingDouble, ref, *args)
|
61
|
+
ExampleMethods.declare_verifying_double(ClassVerifyingDouble, ref, *args)
|
62
62
|
end
|
63
63
|
|
64
64
|
# @overload object_double(object_or_name)
|
@@ -73,7 +73,7 @@ module RSpec
|
|
73
73
|
# for verification. In all other ways it behaves like a [double](double).
|
74
74
|
def object_double(object_or_name, *args)
|
75
75
|
ref = ObjectReference.for(object_or_name, :allow_direct_object_refs)
|
76
|
-
declare_verifying_double(ObjectVerifyingDouble, ref, *args)
|
76
|
+
ExampleMethods.declare_verifying_double(ObjectVerifyingDouble, ref, *args)
|
77
77
|
end
|
78
78
|
|
79
79
|
# Disables warning messages about expectations being set on nil.
|
@@ -164,6 +164,7 @@ module RSpec
|
|
164
164
|
Matchers::HaveReceived.new(method_name, &block)
|
165
165
|
end
|
166
166
|
|
167
|
+
# @api private
|
167
168
|
def self.included(klass)
|
168
169
|
klass.class_exec do
|
169
170
|
# This gets mixed in so that if `RSpec::Matchers` is included in
|
@@ -172,14 +173,13 @@ module RSpec
|
|
172
173
|
end
|
173
174
|
end
|
174
175
|
|
175
|
-
|
176
|
-
|
177
|
-
def declare_verifying_double(type, ref, *args)
|
176
|
+
# @api private
|
177
|
+
def self.declare_verifying_double(type, ref, *args)
|
178
178
|
if RSpec::Mocks.configuration.verify_doubled_constant_names? &&
|
179
179
|
!ref.defined?
|
180
180
|
|
181
|
-
raise
|
182
|
-
"#{ref.
|
181
|
+
raise VerifyingDoubleNotDefinedError,
|
182
|
+
"#{ref.description} is not a defined constant. " +
|
183
183
|
"Perhaps you misspelt it? " +
|
184
184
|
"Disable check with verify_doubled_constant_names configuration option."
|
185
185
|
end
|
@@ -187,7 +187,8 @@ module RSpec
|
|
187
187
|
declare_double(type, ref, *args)
|
188
188
|
end
|
189
189
|
|
190
|
-
|
190
|
+
# @api private
|
191
|
+
def self.declare_double(type, *args)
|
191
192
|
args << {} unless Hash === args.last
|
192
193
|
type.new(*args)
|
193
194
|
end
|
@@ -3,7 +3,7 @@ module Marshal
|
|
3
3
|
# Duplicates any mock objects before serialization. Otherwise,
|
4
4
|
# serialization will fail because methods exist on the singleton class.
|
5
5
|
def dump_with_mocks(object, *rest)
|
6
|
-
if
|
6
|
+
if !::RSpec::Mocks.space.registered?(object) || NilClass === object
|
7
7
|
dump_without_mocks(object, *rest)
|
8
8
|
else
|
9
9
|
dump_without_mocks(object.dup, *rest)
|
@@ -9,19 +9,17 @@ require 'rspec/mocks/method_double'
|
|
9
9
|
require 'rspec/mocks/argument_matchers'
|
10
10
|
require 'rspec/mocks/example_methods'
|
11
11
|
require 'rspec/mocks/proxy'
|
12
|
-
require 'rspec/mocks/proxy_for_nil'
|
13
12
|
require 'rspec/mocks/test_double'
|
14
|
-
require 'rspec/mocks/mock'
|
15
13
|
require 'rspec/mocks/argument_list_matcher'
|
16
14
|
require 'rspec/mocks/message_expectation'
|
17
15
|
require 'rspec/mocks/order_group'
|
18
|
-
require 'rspec/mocks/errors'
|
19
16
|
require 'rspec/mocks/error_generator'
|
20
17
|
require 'rspec/mocks/space'
|
21
18
|
require 'rspec/mocks/extensions/marshal'
|
22
19
|
require 'rspec/mocks/any_instance/chain'
|
23
20
|
require 'rspec/mocks/any_instance/stub_chain'
|
24
21
|
require 'rspec/mocks/any_instance/stub_chain_chain'
|
22
|
+
require 'rspec/mocks/any_instance/expect_chain_chain'
|
25
23
|
require 'rspec/mocks/any_instance/expectation_chain'
|
26
24
|
require 'rspec/mocks/any_instance/message_chains'
|
27
25
|
require 'rspec/mocks/any_instance/recorder'
|
@@ -29,7 +27,8 @@ require 'rspec/mocks/mutate_const'
|
|
29
27
|
require 'rspec/mocks/matchers/have_received'
|
30
28
|
require 'rspec/mocks/matchers/receive'
|
31
29
|
require 'rspec/mocks/matchers/receive_messages'
|
32
|
-
require 'rspec/mocks/
|
30
|
+
require 'rspec/mocks/matchers/receive_message_chain'
|
31
|
+
require 'rspec/mocks/message_chain'
|
33
32
|
require 'rspec/mocks/targets'
|
34
33
|
require 'rspec/mocks/syntax'
|
35
34
|
require 'rspec/mocks/configuration'
|
@@ -54,7 +54,7 @@ module RSpec
|
|
54
54
|
# @private
|
55
55
|
def stash
|
56
56
|
return if !method_defined_directly_on_klass?
|
57
|
-
@original_method ||= ::RSpec::
|
57
|
+
@original_method ||= ::RSpec::Support.method_handle_for(@object, @method)
|
58
58
|
end
|
59
59
|
|
60
60
|
# @private
|
@@ -79,7 +79,7 @@ module RSpec
|
|
79
79
|
|
80
80
|
# @private
|
81
81
|
def method_defined_on_klass?(klass = @klass)
|
82
|
-
|
82
|
+
MethodReference.method_defined_at_any_visibility?(klass, @method)
|
83
83
|
end
|
84
84
|
|
85
85
|
def method_owned_by_klass?
|
@@ -109,4 +109,3 @@ module RSpec
|
|
109
109
|
end
|
110
110
|
end
|
111
111
|
end
|
112
|
-
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Mocks
|
3
3
|
module Matchers
|
4
|
+
# @private
|
4
5
|
class HaveReceived
|
5
6
|
COUNT_CONSTRAINTS = %w(exactly at_least at_most times once twice)
|
6
7
|
ARGS_CONSTRAINTS = %w(with)
|
@@ -35,7 +36,7 @@ module RSpec
|
|
35
36
|
generate_failure_message
|
36
37
|
end
|
37
38
|
|
38
|
-
def
|
39
|
+
def failure_message_when_negated
|
39
40
|
generate_failure_message
|
40
41
|
end
|
41
42
|
|
@@ -53,9 +54,11 @@ module RSpec
|
|
53
54
|
private
|
54
55
|
|
55
56
|
def expect
|
56
|
-
expectation
|
57
|
-
|
58
|
-
|
57
|
+
@expectation ||= begin
|
58
|
+
expectation = mock_proxy.build_expectation(@method_name)
|
59
|
+
apply_constraints_to expectation
|
60
|
+
expectation
|
61
|
+
end
|
59
62
|
end
|
60
63
|
|
61
64
|
def apply_constraints_to(expectation)
|
@@ -90,10 +93,9 @@ module RSpec
|
|
90
93
|
end
|
91
94
|
|
92
95
|
def mock_proxy
|
93
|
-
RSpec::Mocks.proxy_for(@subject)
|
96
|
+
RSpec::Mocks.space.proxy_for(@subject)
|
94
97
|
end
|
95
98
|
end
|
96
99
|
end
|
97
100
|
end
|
98
101
|
end
|
99
|
-
|
@@ -1,17 +1,13 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Mocks
|
3
3
|
module Matchers
|
4
|
+
# @private
|
4
5
|
class Receive
|
5
6
|
def initialize(message, block)
|
6
7
|
@message = message
|
7
8
|
@block = block
|
8
9
|
@recorded_customizations = []
|
9
|
-
|
10
|
-
# MRI, JRuby and RBX report the caller inconsistently; MRI
|
11
|
-
# reports an extra "in `new'" line in the backtrace that the
|
12
|
-
# others do not include. The safest way to find the right
|
13
|
-
# line is to search for the first line BEFORE rspec/mocks/syntax.rb.
|
14
|
-
@backtrace_line = CallerFilter.first_non_rspec_line
|
10
|
+
@backtrace_line = CallerFilter.first_non_rspec_line
|
15
11
|
end
|
16
12
|
|
17
13
|
def name
|
@@ -27,7 +23,7 @@ module RSpec
|
|
27
23
|
def setup_negative_expectation(subject, &block)
|
28
24
|
# ensure `never` goes first for cases like `never.and_return(5)`,
|
29
25
|
# where `and_return` is meant to raise an error
|
30
|
-
@recorded_customizations.unshift
|
26
|
+
@recorded_customizations.unshift ExpectationCustomization.new(:never, [], nil)
|
31
27
|
|
32
28
|
warn_if_any_instance("expect", subject)
|
33
29
|
|
@@ -56,7 +52,7 @@ module RSpec
|
|
56
52
|
next if method_defined?(method)
|
57
53
|
|
58
54
|
define_method(method) do |*args, &block|
|
59
|
-
@recorded_customizations <<
|
55
|
+
@recorded_customizations << ExpectationCustomization.new(method, args, block)
|
60
56
|
self
|
61
57
|
end
|
62
58
|
end
|
@@ -75,17 +71,19 @@ module RSpec
|
|
75
71
|
end
|
76
72
|
|
77
73
|
def setup_mock_proxy_method_substitute(subject, method, block)
|
78
|
-
proxy = ::RSpec::Mocks.proxy_for(subject)
|
74
|
+
proxy = ::RSpec::Mocks.space.proxy_for(subject)
|
79
75
|
setup_method_substitute(proxy, method, block, @backtrace_line)
|
80
76
|
end
|
81
77
|
|
82
78
|
def setup_any_instance_method_substitute(subject, method, block)
|
83
|
-
any_instance_recorder = ::RSpec::Mocks.any_instance_recorder_for(subject)
|
79
|
+
any_instance_recorder = ::RSpec::Mocks.space.any_instance_recorder_for(subject)
|
84
80
|
setup_method_substitute(any_instance_recorder, method, block)
|
85
81
|
end
|
86
82
|
|
87
83
|
def setup_method_substitute(host, method, block, *args)
|
88
84
|
args << @message.to_sym
|
85
|
+
block = move_block_to_last_customization(block)
|
86
|
+
|
89
87
|
expectation = host.__send__(method, *args, &(@block || block))
|
90
88
|
|
91
89
|
@recorded_customizations.each do |customization|
|
@@ -94,19 +92,29 @@ module RSpec
|
|
94
92
|
expectation
|
95
93
|
end
|
96
94
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
@args = args
|
101
|
-
@block = block
|
102
|
-
end
|
95
|
+
def move_block_to_last_customization(block)
|
96
|
+
last = @recorded_customizations.last
|
97
|
+
return block unless last
|
103
98
|
|
104
|
-
|
105
|
-
|
106
|
-
end
|
99
|
+
last.block ||= block
|
100
|
+
nil
|
107
101
|
end
|
108
102
|
end
|
109
103
|
end
|
104
|
+
|
105
|
+
# @private
|
106
|
+
class ExpectationCustomization
|
107
|
+
attr_accessor :block
|
108
|
+
|
109
|
+
def initialize(method_name, args, block)
|
110
|
+
@method_name = method_name
|
111
|
+
@args = args
|
112
|
+
@block = block
|
113
|
+
end
|
114
|
+
|
115
|
+
def playback_onto(expectation)
|
116
|
+
expectation.__send__(@method_name, *@args, &@block)
|
117
|
+
end
|
118
|
+
end
|
110
119
|
end
|
111
120
|
end
|
112
|
-
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Mocks
|
3
|
+
module Matchers
|
4
|
+
# @private
|
5
|
+
class ReceiveMessageChain
|
6
|
+
def initialize(chain, &block)
|
7
|
+
@chain = chain
|
8
|
+
@block = block
|
9
|
+
@recorded_customizations = []
|
10
|
+
end
|
11
|
+
|
12
|
+
[:and_return, :and_throw, :and_raise, :and_yield, :and_call_original].each do |msg|
|
13
|
+
define_method(msg) do |*args, &block|
|
14
|
+
@recorded_customizations << ExpectationCustomization.new(msg, args, block)
|
15
|
+
self
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def name
|
20
|
+
"receive_message_chain"
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup_allowance(subject, &block)
|
24
|
+
chain = StubChain.stub_chain_on(subject, *@chain, &(@block || block))
|
25
|
+
replay_customizations(chain)
|
26
|
+
end
|
27
|
+
|
28
|
+
def setup_any_instance_allowance(subject, &block)
|
29
|
+
recorder = ::RSpec::Mocks.space.any_instance_recorder_for(subject)
|
30
|
+
chain = recorder.stub_chain(*@chain, &(@block || block))
|
31
|
+
replay_customizations(chain)
|
32
|
+
end
|
33
|
+
|
34
|
+
def setup_any_instance_expectation(subject, &block)
|
35
|
+
recorder = ::RSpec::Mocks.space.any_instance_recorder_for(subject)
|
36
|
+
chain = recorder.expect_chain(*@chain, &(@block || block))
|
37
|
+
replay_customizations(chain)
|
38
|
+
end
|
39
|
+
|
40
|
+
def setup_expectation(subject, &block)
|
41
|
+
chain = ExpectChain.expect_chain_on(subject, *@chain, &(@block || block))
|
42
|
+
replay_customizations(chain)
|
43
|
+
end
|
44
|
+
|
45
|
+
def setup_negative_expectation(*args)
|
46
|
+
raise NegationUnsupportedError.new(
|
47
|
+
"`expect(...).not_to receive_message_chain` is not supported " +
|
48
|
+
"since it doesn't really make sense. What would it even mean?"
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
alias matches? setup_expectation
|
53
|
+
alias does_not_match? setup_negative_expectation
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def replay_customizations(chain)
|
58
|
+
@recorded_customizations.each do |customization|
|
59
|
+
customization.playback_onto(chain)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|