rspec-mocks 3.13.7 → 4.0.0.beta1
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/Changelog.md +15 -1
- data/LICENSE.md +1 -0
- data/README.md +8 -39
- data/lib/rspec/mocks/any_instance/expectation_chain.rb +1 -1
- data/lib/rspec/mocks/any_instance/proxy.rb +3 -9
- data/lib/rspec/mocks/any_instance/recorder.rb +13 -25
- data/lib/rspec/mocks/any_instance/stub_chain.rb +1 -1
- data/lib/rspec/mocks/argument_list_matcher.rb +9 -11
- data/lib/rspec/mocks/configuration.rb +1 -73
- data/lib/rspec/mocks/error_generator.rb +14 -23
- data/lib/rspec/mocks/example_methods.rb +28 -28
- data/lib/rspec/mocks/instance_method_stasher.rb +25 -102
- data/lib/rspec/mocks/message_expectation.rb +2 -3
- data/lib/rspec/mocks/method_double.rb +61 -71
- data/lib/rspec/mocks/method_reference.rb +8 -26
- data/lib/rspec/mocks/minitest_integration.rb +1 -1
- data/lib/rspec/mocks/mutate_const.rb +0 -1
- data/lib/rspec/mocks/object_reference.rb +2 -8
- data/lib/rspec/mocks/proxy.rb +8 -27
- data/lib/rspec/mocks/space.rb +4 -17
- data/lib/rspec/mocks/standalone.rb +2 -0
- data/lib/rspec/mocks/test_double.rb +5 -3
- data/lib/rspec/mocks/verifying_double.rb +2 -3
- data/lib/rspec/mocks/verifying_proxy.rb +2 -4
- data/lib/rspec/mocks/version.rb +1 -1
- data/lib/rspec/mocks.rb +0 -2
- data.tar.gz.sig +0 -0
- metadata +28 -29
- metadata.gz.sig +0 -0
- data/lib/rspec/mocks/syntax.rb +0 -325
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e4915179fc75a2e044c363714cd6fa9fd53793a4fb8259b547434a0c9ef30863
|
|
4
|
+
data.tar.gz: 462d98b713cd2631b9c14a5e15badde5c8bc73478795def839cc903a12d8685b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 17bf39282a033c69d455ea688c166432b103a846aa72b24dec91ee1e714f0a12112f5a04ce2ed2fd69b31a3a7069754f19fc6e278917324aaa5146079b00e8ca
|
|
7
|
+
data.tar.gz: 47cf0ca37ffbde593befd106ade7f6c0fbf8d638f1d20c1d63d31bc3b26f1bb3fb08f780838106a9170dfc7b7629364adf99117b89cef0e60ed9761c5e8860d6
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/Changelog.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
### Development
|
|
2
|
-
[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.7...
|
|
2
|
+
[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.7...main)
|
|
3
|
+
|
|
4
|
+
# 4.0.0.beta1 / 2026-02-18
|
|
5
|
+
|
|
6
|
+
Breaking Changes:
|
|
7
|
+
|
|
8
|
+
* Ruby < 3.0 is no longer supported. (Phil Pirozhkov, Jon Rowe, rspec/rspec-mocks#1349, rspec/rspec#258)
|
|
9
|
+
* Remove monkey-patching `should_receive`/`stub` syntax. (Phil Pirozhkov, rspec/rspec-mocks#1365)
|
|
10
|
+
* Remove the deprecated `RSpec::Mocks::CannotSupportArgMutationsError`.
|
|
11
|
+
(Phil Pirozhkov, rspec/rspec-mocks#1400)
|
|
12
|
+
* Change the default setting for `RSpec::Mocks::Configuration#verify_partial_doubles`
|
|
13
|
+
to `true`. (Phil Pirozhkov, rspec/rspec-mocks#1409)
|
|
14
|
+
* Remove deprecated `allow_message_expectations_on_nil` example method.
|
|
15
|
+
(Phil Pirozhkov, rspec/rspec-mocks#1410)
|
|
16
|
+
* Fix stubbing of prepended-only methods. (Lin Jen-Shin, rspec/rspec-mocks#1218)
|
|
3
17
|
|
|
4
18
|
### 3.13.7 / 2025-10-31
|
|
5
19
|
[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.6...rspec-mocks-v3.13.7)
|
data/LICENSE.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
2
|
=====================
|
|
3
3
|
|
|
4
|
+
* Copyright © 2013 David Chelimsky, Myron Marston, Jon Rowe, Sam Phippen, Xavier Shay, Bradley Schaefer
|
|
4
5
|
* Copyright © 2012 David Chelimsky, Myron Marston
|
|
5
6
|
* Copyright © 2006 David Chelimsky, The RSpec Development Team
|
|
6
7
|
* Copyright © 2005 Steven Baker
|
data/README.md
CHANGED
|
@@ -1,35 +1,11 @@
|
|
|
1
|
-
# RSpec
|
|
2
|
-
rspec-mocks is a test-double framework for rspec with support for method stubs,
|
|
3
|
-
fakes, and message expectations on generated test-doubles and real objects
|
|
4
|
-
alike.
|
|
1
|
+
# RSpec::Mocks
|
|
5
2
|
|
|
6
|
-
|
|
3
|
+
This is the detailed readme for `rspec-mocks`, see also:
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
RSpec repos as well. Add the following to your `Gemfile`:
|
|
13
|
-
|
|
14
|
-
```ruby
|
|
15
|
-
%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
|
|
16
|
-
gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main'
|
|
17
|
-
end
|
|
18
|
-
```
|
|
19
|
-
## Contributing
|
|
20
|
-
|
|
21
|
-
Once you've set up the environment, you'll need to cd into the working
|
|
22
|
-
directory of whichever repo you want to work in. From there you can run the
|
|
23
|
-
specs and cucumber features, and make patches.
|
|
24
|
-
|
|
25
|
-
NOTE: You do not need to use rspec-dev to work on a specific RSpec repo. You
|
|
26
|
-
can treat each RSpec repo as an independent project.
|
|
27
|
-
|
|
28
|
-
For information about contributing to RSpec, please refer to the following markdown files:
|
|
29
|
-
* [Build details](BUILD_DETAIL.md)
|
|
30
|
-
* [Code of Conduct](CODE_OF_CONDUCT.md)
|
|
31
|
-
* [Detailed contributing guide](CONTRIBUTING.md)
|
|
32
|
-
* [Development setup guide](DEVELOPMENT.md)
|
|
5
|
+
* [The combined readme](../README.md)
|
|
6
|
+
* [rspec-core](../rspec-core/README.md)
|
|
7
|
+
* [rspec-expectations](../rspec-expectations/README.md)
|
|
8
|
+
* [rspec-support](../rspec-support/README.md)
|
|
33
9
|
|
|
34
10
|
## Test Doubles
|
|
35
11
|
|
|
@@ -53,7 +29,7 @@ book = instance_double("Book", :pages => 250)
|
|
|
53
29
|
Verifying doubles have some clever tricks to enable you to both test in
|
|
54
30
|
isolation without your dependencies loaded while still being able to validate
|
|
55
31
|
them against real objects. More detail is available in [their
|
|
56
|
-
documentation](https://github.com/rspec/rspec
|
|
32
|
+
documentation](https://github.com/rspec/rspec/tree/main/rspec-mocks/features/verifying_doubles#readme).
|
|
57
33
|
|
|
58
34
|
Verifying doubles can also accept custom identifiers, just like double(), e.g.:
|
|
59
35
|
|
|
@@ -405,7 +381,7 @@ your code.
|
|
|
405
381
|
## Stubbing and Hiding Constants
|
|
406
382
|
|
|
407
383
|
See the [mutating constants
|
|
408
|
-
README](https://github.com/rspec/rspec
|
|
384
|
+
README](https://github.com/rspec/rspec/tree/main/rspec-mocks/features/mutating_constants)
|
|
409
385
|
for info on this feature.
|
|
410
386
|
|
|
411
387
|
## Use `before(:example)`, not `before(:context)`
|
|
@@ -456,10 +432,3 @@ you are interested in learning more, here is some recommended reading:
|
|
|
456
432
|
* Test Double: http://www.martinfowler.com/bliki/TestDouble.html
|
|
457
433
|
* Test Double Patterns: http://xunitpatterns.com/Test%20Double%20Patterns.html
|
|
458
434
|
* Mocks aren't stubs: http://www.martinfowler.com/articles/mocksArentStubs.html
|
|
459
|
-
|
|
460
|
-
## Also see
|
|
461
|
-
|
|
462
|
-
* [https://github.com/rspec/rspec](https://github.com/rspec/rspec)
|
|
463
|
-
* [https://github.com/rspec/rspec-core](https://github.com/rspec/rspec-core)
|
|
464
|
-
* [https://github.com/rspec/rspec-expectations](https://github.com/rspec/rspec-expectations)
|
|
465
|
-
* [https://github.com/rspec/rspec-rails](https://github.com/rspec/rspec-rails)
|
|
@@ -25,7 +25,7 @@ module RSpec
|
|
|
25
25
|
def create_message_expectation_on(instance)
|
|
26
26
|
proxy = ::RSpec::Mocks.space.proxy_for(instance)
|
|
27
27
|
method_name, opts = @expectation_args
|
|
28
|
-
opts
|
|
28
|
+
opts ||= {}
|
|
29
29
|
|
|
30
30
|
me = proxy.add_message_expectation(method_name, opts, &@expectation_block)
|
|
31
31
|
if RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks?
|
|
@@ -86,7 +86,7 @@ module RSpec
|
|
|
86
86
|
unless defined?(BasicObject)
|
|
87
87
|
class BasicObject
|
|
88
88
|
# Remove all methods except those expected to be defined on BasicObject
|
|
89
|
-
(instance_methods.map(&:to_sym) - [:__send__,
|
|
89
|
+
(instance_methods.map(&:to_sym) - [:__send__, :!, :instance_eval, :==, :instance_exec, :!=, :equal?, :__id__, :__binding__, :object_id]).each do |method|
|
|
90
90
|
undef_method method
|
|
91
91
|
end
|
|
92
92
|
end
|
|
@@ -105,14 +105,8 @@ module RSpec
|
|
|
105
105
|
@targets = targets
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
super || @targets.first.respond_to?(method_name, include_private)
|
|
111
|
-
end
|
|
112
|
-
else
|
|
113
|
-
def respond_to?(method_name, include_private=false)
|
|
114
|
-
super || @targets.first.respond_to?(method_name, include_private)
|
|
115
|
-
end
|
|
108
|
+
def respond_to_missing?(method_name, include_private=false)
|
|
109
|
+
super || @targets.first.respond_to?(method_name, include_private)
|
|
116
110
|
end
|
|
117
111
|
|
|
118
112
|
def method_missing(*args, &block)
|
|
@@ -157,7 +157,7 @@ module RSpec
|
|
|
157
157
|
private
|
|
158
158
|
|
|
159
159
|
def ancestor_is_an_observer?(ancestor, method_name)
|
|
160
|
-
return if ancestor == @klass
|
|
160
|
+
return false if ancestor == @klass
|
|
161
161
|
|
|
162
162
|
::RSpec::Mocks.space.
|
|
163
163
|
any_instance_recorder_for(ancestor).already_observing?(method_name)
|
|
@@ -202,24 +202,17 @@ module RSpec
|
|
|
202
202
|
remove_method method_name
|
|
203
203
|
|
|
204
204
|
# A @klass can have methods implemented (see Method#owner) in @klass
|
|
205
|
-
# or inherited from a superclass.
|
|
206
|
-
# a method regardless of the 'owner' and restore it to @klass after
|
|
207
|
-
# because a call to 'super' from @klass's copied method would end up
|
|
208
|
-
# calling the original class's superclass's method.
|
|
205
|
+
# or inherited from a superclass.
|
|
209
206
|
#
|
|
210
|
-
#
|
|
211
|
-
# this behavior and a call to 'super' from the method copied to @klass
|
|
207
|
+
# A call to 'super' from the method copied to @klass
|
|
212
208
|
# will call @klass's superclass method, which is the original
|
|
213
209
|
# implementer of this method! This leads to very strange errors
|
|
214
210
|
# if @klass's copied method calls 'super', since it would end up
|
|
215
211
|
# calling itself, the original method implemented in @klass's
|
|
216
212
|
# superclass.
|
|
217
213
|
#
|
|
218
|
-
#
|
|
219
|
-
|
|
220
|
-
#
|
|
221
|
-
# https://github.com/ruby/ruby/commit/c8854d2ca4be9ee6946e6d17b0e17d9ef130ee81
|
|
222
|
-
if RUBY_VERSION < "2.3" || backed_up_method_owner[method_name.to_sym] == self
|
|
214
|
+
# We need to only restore methods that @klass originally owned.
|
|
215
|
+
if backed_up_method_owner[method_name.to_sym] == self
|
|
223
216
|
alias_method method_name, alias_method_name
|
|
224
217
|
end
|
|
225
218
|
remove_method alias_method_name
|
|
@@ -260,7 +253,8 @@ module RSpec
|
|
|
260
253
|
backup_method!(method_name)
|
|
261
254
|
recorder = self
|
|
262
255
|
method_was_private = @klass.private_method_defined?(method_name)
|
|
263
|
-
|
|
256
|
+
|
|
257
|
+
@klass.define_method(method_name) do |*args, &blk|
|
|
264
258
|
recorder.playback!(self, method_name)
|
|
265
259
|
__send__(method_name, *args, &blk)
|
|
266
260
|
end
|
|
@@ -271,7 +265,7 @@ module RSpec
|
|
|
271
265
|
def mark_invoked!(method_name)
|
|
272
266
|
backup_method!(method_name)
|
|
273
267
|
recorder = self
|
|
274
|
-
@klass.
|
|
268
|
+
@klass.define_method(method_name) do |*_args, &_blk|
|
|
275
269
|
invoked_instance = recorder.instance_that_received(method_name)
|
|
276
270
|
inspect = "#<#{self.class}:#{object_id} #{instance_variables.map { |name| "#{name}=#{instance_variable_get name}" }.join(', ')}>"
|
|
277
271
|
AnyInstance.error_generator.raise_message_already_received_by_other_instance_error(
|
|
@@ -280,18 +274,12 @@ module RSpec
|
|
|
280
274
|
end
|
|
281
275
|
end
|
|
282
276
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
return unless problem_mod
|
|
277
|
+
def allow_no_prepended_module_definition_of(method_name)
|
|
278
|
+
prepended_modules = RSpec::Mocks::Proxy.prepended_modules_of(@klass)
|
|
279
|
+
problem_mod = prepended_modules.find { |mod| mod.method_defined?(method_name) }
|
|
280
|
+
return unless problem_mod
|
|
288
281
|
|
|
289
|
-
|
|
290
|
-
end
|
|
291
|
-
else
|
|
292
|
-
def allow_no_prepended_module_definition_of(_method_name)
|
|
293
|
-
# nothing to do; prepends aren't supported on this version of ruby
|
|
294
|
-
end
|
|
282
|
+
AnyInstance.error_generator.raise_not_supported_with_prepend_error(method_name, problem_mod)
|
|
295
283
|
end
|
|
296
284
|
end
|
|
297
285
|
end
|
|
@@ -13,7 +13,7 @@ module RSpec
|
|
|
13
13
|
def create_message_expectation_on(instance)
|
|
14
14
|
proxy = ::RSpec::Mocks.space.proxy_for(instance)
|
|
15
15
|
method_name, opts = @expectation_args
|
|
16
|
-
opts
|
|
16
|
+
opts ||= {}
|
|
17
17
|
|
|
18
18
|
stub = proxy.add_stub(method_name, opts, &@expectation_block)
|
|
19
19
|
@recorder.stubs[stub.message] << stub
|
|
@@ -60,14 +60,12 @@ module RSpec
|
|
|
60
60
|
|
|
61
61
|
return false if expected_args.size != actual_args.size
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if Hash
|
|
68
|
-
|
|
69
|
-
return false
|
|
70
|
-
end
|
|
63
|
+
# If the expectation was set with keywords, while the actual method was called with a positional hash argument, they don't match.
|
|
64
|
+
# If the expectation was set without keywords, e.g., with({a: 1}), then it fine to call it with either foo(a: 1) or foo({a: 1}).
|
|
65
|
+
# This corresponds to Ruby semantics, as if the method was def foo(options).
|
|
66
|
+
if Hash === expected_args.last && Hash === actual_args.last
|
|
67
|
+
if !Hash.ruby2_keywords_hash?(actual_args.last) && Hash.ruby2_keywords_hash?(expected_args.last)
|
|
68
|
+
return false
|
|
71
69
|
end
|
|
72
70
|
end
|
|
73
71
|
|
|
@@ -100,11 +98,11 @@ module RSpec
|
|
|
100
98
|
def ensure_expected_args_valid!
|
|
101
99
|
if expected_args.count { |a| ArgumentMatchers::AnyArgsMatcher::INSTANCE == a } > 1
|
|
102
100
|
raise ArgumentError, "`any_args` can only be passed to " \
|
|
103
|
-
|
|
101
|
+
"`with` once but you have passed it multiple times."
|
|
104
102
|
elsif expected_args.count > 1 && expected_args.any? { |a| ArgumentMatchers::NoArgsMatcher::INSTANCE == a }
|
|
105
103
|
raise ArgumentError, "`no_args` can only be passed as a " \
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
"singleton argument to `with` (i.e. `with(no_args)`), " \
|
|
105
|
+
"but you have passed additional arguments."
|
|
108
106
|
end
|
|
109
107
|
end
|
|
110
108
|
|
|
@@ -7,7 +7,7 @@ module RSpec
|
|
|
7
7
|
@yield_receiver_to_any_instance_implementation_blocks = true
|
|
8
8
|
@verify_doubled_constant_names = false
|
|
9
9
|
@transfer_nested_constants = false
|
|
10
|
-
@verify_partial_doubles =
|
|
10
|
+
@verify_partial_doubles = true
|
|
11
11
|
@temporarily_suppress_partial_double_verification = false
|
|
12
12
|
@color = false
|
|
13
13
|
end
|
|
@@ -45,69 +45,6 @@ module RSpec
|
|
|
45
45
|
# end
|
|
46
46
|
attr_writer :yield_receiver_to_any_instance_implementation_blocks
|
|
47
47
|
|
|
48
|
-
# Adds `stub` and `should_receive` to the given
|
|
49
|
-
# modules or classes. This is usually only necessary
|
|
50
|
-
# if you application uses some proxy classes that
|
|
51
|
-
# "strip themselves down" to a bare minimum set of
|
|
52
|
-
# methods and remove `stub` and `should_receive` in
|
|
53
|
-
# the process.
|
|
54
|
-
#
|
|
55
|
-
# @example
|
|
56
|
-
# RSpec.configure do |rspec|
|
|
57
|
-
# rspec.mock_with :rspec do |mocks|
|
|
58
|
-
# mocks.add_stub_and_should_receive_to Delegator
|
|
59
|
-
# end
|
|
60
|
-
# end
|
|
61
|
-
#
|
|
62
|
-
def add_stub_and_should_receive_to(*modules)
|
|
63
|
-
modules.each do |mod|
|
|
64
|
-
Syntax.enable_should(mod)
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Provides the ability to set either `expect`,
|
|
69
|
-
# `should` or both syntaxes. RSpec uses `expect`
|
|
70
|
-
# syntax by default. This is needed if you want to
|
|
71
|
-
# explicitly enable `should` syntax and/or explicitly
|
|
72
|
-
# disable `expect` syntax.
|
|
73
|
-
#
|
|
74
|
-
# @example
|
|
75
|
-
# RSpec.configure do |rspec|
|
|
76
|
-
# rspec.mock_with :rspec do |mocks|
|
|
77
|
-
# mocks.syntax = [:expect, :should]
|
|
78
|
-
# end
|
|
79
|
-
# end
|
|
80
|
-
#
|
|
81
|
-
def syntax=(*values)
|
|
82
|
-
syntaxes = values.flatten
|
|
83
|
-
if syntaxes.include?(:expect)
|
|
84
|
-
Syntax.enable_expect
|
|
85
|
-
else
|
|
86
|
-
Syntax.disable_expect
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
if syntaxes.include?(:should)
|
|
90
|
-
Syntax.enable_should
|
|
91
|
-
else
|
|
92
|
-
Syntax.disable_should
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# Returns an array with a list of syntaxes
|
|
97
|
-
# that are enabled.
|
|
98
|
-
#
|
|
99
|
-
# @example
|
|
100
|
-
# unless RSpec::Mocks.configuration.syntax.include?(:expect)
|
|
101
|
-
# raise "this RSpec extension gem requires the rspec-mocks `:expect` syntax"
|
|
102
|
-
# end
|
|
103
|
-
#
|
|
104
|
-
def syntax
|
|
105
|
-
syntaxes = []
|
|
106
|
-
syntaxes << :should if Syntax.should_enabled?
|
|
107
|
-
syntaxes << :expect if Syntax.expect_enabled?
|
|
108
|
-
syntaxes
|
|
109
|
-
end
|
|
110
|
-
|
|
111
48
|
def verify_doubled_constant_names?
|
|
112
49
|
!!@verify_doubled_constant_names
|
|
113
50
|
end
|
|
@@ -192,13 +129,6 @@ module RSpec
|
|
|
192
129
|
RSpec::Mocks::MarshalExtension.unpatch!
|
|
193
130
|
end
|
|
194
131
|
end
|
|
195
|
-
|
|
196
|
-
# @api private
|
|
197
|
-
# Resets the configured syntax to the default.
|
|
198
|
-
def reset_syntaxes_to_default
|
|
199
|
-
self.syntax = [:should, :expect]
|
|
200
|
-
RSpec::Mocks::Syntax.warn_about_should!
|
|
201
|
-
end
|
|
202
132
|
end
|
|
203
133
|
|
|
204
134
|
# Mocks specific configuration, as distinct from `RSpec.configuration`
|
|
@@ -206,7 +136,5 @@ module RSpec
|
|
|
206
136
|
def self.configuration
|
|
207
137
|
@configuration ||= Configuration.new
|
|
208
138
|
end
|
|
209
|
-
|
|
210
|
-
configuration.reset_syntaxes_to_default
|
|
211
139
|
end
|
|
212
140
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
RSpec::Support.require_rspec_support "object_formatter"
|
|
2
|
+
RSpec::Support.require_rspec_support 'ruby_features'
|
|
2
3
|
|
|
3
4
|
module RSpec
|
|
4
5
|
module Mocks
|
|
@@ -17,14 +18,6 @@ module RSpec
|
|
|
17
18
|
# invoked.
|
|
18
19
|
MockExpectationAlreadyInvokedError = Class.new(Exception)
|
|
19
20
|
|
|
20
|
-
# Raised for situations that RSpec cannot support due to mutations made
|
|
21
|
-
# externally on arguments that RSpec is holding onto to use for later
|
|
22
|
-
# comparisons.
|
|
23
|
-
#
|
|
24
|
-
# @deprecated We no longer raise this error but the constant remains until
|
|
25
|
-
# RSpec 4 for SemVer reasons.
|
|
26
|
-
CannotSupportArgMutationsError = Class.new(StandardError)
|
|
27
|
-
|
|
28
21
|
# @private
|
|
29
22
|
UnsupportedMatcherError = Class.new(StandardError)
|
|
30
23
|
# @private
|
|
@@ -202,8 +195,8 @@ module RSpec
|
|
|
202
195
|
# @private
|
|
203
196
|
def raise_already_invoked_error(message, calling_customization)
|
|
204
197
|
error_message = "The message expectation for #{intro}.#{message} has already been invoked " \
|
|
205
|
-
|
|
206
|
-
|
|
198
|
+
"and cannot be modified further (e.g. using `#{calling_customization}`). All message expectation " \
|
|
199
|
+
"customizations must be applied before it is used for the first time."
|
|
207
200
|
|
|
208
201
|
notify MockExpectationAlreadyInvokedError.new(error_message)
|
|
209
202
|
end
|
|
@@ -214,8 +207,8 @@ module RSpec
|
|
|
214
207
|
|
|
215
208
|
def expectation_on_nil_message(method_name)
|
|
216
209
|
"An expectation of `:#{method_name}` was set on `nil`. " \
|
|
217
|
-
|
|
218
|
-
|
|
210
|
+
"To allow expectations on `nil` and suppress this message, set `RSpec::Mocks.configuration.allow_message_expectations_on_nil` to `true`. " \
|
|
211
|
+
"To disallow expectations on `nil`, set `RSpec::Mocks.configuration.allow_message_expectations_on_nil` to `false`"
|
|
219
212
|
end
|
|
220
213
|
|
|
221
214
|
# @private
|
|
@@ -269,19 +262,17 @@ module RSpec
|
|
|
269
262
|
expected_args = format_args(expectation.expected_args)
|
|
270
263
|
actual_args = format_received_args(args_for_multiple_calls)
|
|
271
264
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
(Hash.ruby2_keywords_hash?(expected_hash) != Hash.ruby2_keywords_hash?(actual_hash))
|
|
265
|
+
expected_hash = expectation.expected_args.last
|
|
266
|
+
actual_hash = args_for_multiple_calls.last.last
|
|
267
|
+
if Hash === expected_hash && Hash === actual_hash &&
|
|
268
|
+
(Hash.ruby2_keywords_hash?(expected_hash) != Hash.ruby2_keywords_hash?(actual_hash))
|
|
277
269
|
|
|
278
|
-
|
|
279
|
-
|
|
270
|
+
actual_description = Hash.ruby2_keywords_hash?(actual_hash) ? " (keyword arguments)" : " (options hash)"
|
|
271
|
+
expected_description = Hash.ruby2_keywords_hash?(expected_hash) ? " (keyword arguments)" : " (options hash)"
|
|
280
272
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
end
|
|
273
|
+
if actual_description != expected_description
|
|
274
|
+
actual_args += actual_description
|
|
275
|
+
expected_args += expected_description
|
|
285
276
|
end
|
|
286
277
|
end
|
|
287
278
|
|
|
@@ -192,16 +192,6 @@ module RSpec
|
|
|
192
192
|
class_double(*args).as_null_object
|
|
193
193
|
end
|
|
194
194
|
|
|
195
|
-
# Disables warning messages about expectations being set on nil.
|
|
196
|
-
#
|
|
197
|
-
# By default warning messages are issued when expectations are set on
|
|
198
|
-
# nil. This is to prevent false-positives and to catch potential bugs
|
|
199
|
-
# early on.
|
|
200
|
-
# @deprecated Use {RSpec::Mocks::Configuration#allow_message_expectations_on_nil} instead.
|
|
201
|
-
def allow_message_expectations_on_nil
|
|
202
|
-
RSpec::Mocks.space.proxy_for(nil).warn_about_expectations = false
|
|
203
|
-
end
|
|
204
|
-
|
|
205
195
|
# Stubs the named constant with the given value.
|
|
206
196
|
# Like method stubs, the constant will be restored
|
|
207
197
|
# to its original value (or lack of one, if it was
|
|
@@ -303,8 +293,7 @@ module RSpec
|
|
|
303
293
|
#
|
|
304
294
|
# @note This method is usually provided by rspec-expectations. However,
|
|
305
295
|
# if you use rspec-mocks without rspec-expectations, there's a definition
|
|
306
|
-
# of it that is made available here.
|
|
307
|
-
# this method will be undefined.
|
|
296
|
+
# of it that is made available here.
|
|
308
297
|
|
|
309
298
|
# @method allow
|
|
310
299
|
# Used to wrap an object in preparation for stubbing a method
|
|
@@ -312,40 +301,42 @@ module RSpec
|
|
|
312
301
|
#
|
|
313
302
|
# @example
|
|
314
303
|
# allow(dbl).to receive(:foo).with(5).and_return(:return_value)
|
|
315
|
-
|
|
316
|
-
|
|
304
|
+
def allow(target)
|
|
305
|
+
AllowanceTarget.new(target)
|
|
306
|
+
end
|
|
317
307
|
|
|
318
|
-
# @method expect_any_instance_of
|
|
319
308
|
# Used to wrap a class in preparation for setting a mock expectation
|
|
320
309
|
# on instances of it.
|
|
321
310
|
#
|
|
322
311
|
# @example
|
|
323
312
|
# expect_any_instance_of(MyClass).to receive(:foo)
|
|
324
313
|
#
|
|
325
|
-
|
|
314
|
+
def expect_any_instance_of(klass)
|
|
315
|
+
AnyInstanceExpectationTarget.new(klass)
|
|
316
|
+
end
|
|
326
317
|
|
|
327
|
-
# @method allow_any_instance_of
|
|
328
318
|
# Used to wrap a class in preparation for stubbing a method
|
|
329
319
|
# on instances of it.
|
|
330
320
|
#
|
|
331
321
|
# @example
|
|
332
322
|
# allow_any_instance_of(MyClass).to receive(:foo)
|
|
333
323
|
#
|
|
334
|
-
|
|
324
|
+
def allow_any_instance_of(klass)
|
|
325
|
+
AnyInstanceAllowanceTarget.new(klass)
|
|
326
|
+
end
|
|
335
327
|
|
|
336
|
-
# @method receive
|
|
337
328
|
# Used to specify a message that you expect or allow an object
|
|
338
|
-
# to receive. The object returned by `receive` supports
|
|
339
|
-
#
|
|
340
|
-
# supported, allowing you to constrain the arguments or number of
|
|
329
|
+
# to receive. The object returned by `receive` supports a fluent
|
|
330
|
+
# interface, allowing you to constrain the arguments or number of
|
|
341
331
|
# times, and configure how the object should respond to the message.
|
|
342
332
|
#
|
|
343
333
|
# @example
|
|
344
334
|
# expect(obj).to receive(:hello).with("world").exactly(3).times
|
|
345
335
|
#
|
|
346
|
-
|
|
336
|
+
def receive(method_name, &block)
|
|
337
|
+
Matchers::Receive.new(method_name, block)
|
|
338
|
+
end
|
|
347
339
|
|
|
348
|
-
# @method receive_messages
|
|
349
340
|
# Shorthand syntax used to setup message(s), and their return value(s),
|
|
350
341
|
# that you expect or allow an object to receive. The method takes a hash
|
|
351
342
|
# of messages and their respective return values. Unlike with `receive`,
|
|
@@ -356,9 +347,12 @@ module RSpec
|
|
|
356
347
|
# allow(obj).to receive_messages(:speak => "Hello World")
|
|
357
348
|
# allow(obj).to receive_messages(:speak => "Hello", :meow => "Meow")
|
|
358
349
|
#
|
|
359
|
-
|
|
350
|
+
def receive_messages(message_return_value_hash, &block)
|
|
351
|
+
matcher = Matchers::ReceiveMessages.new(message_return_value_hash)
|
|
352
|
+
matcher.warn_about_block if block
|
|
353
|
+
matcher
|
|
354
|
+
end
|
|
360
355
|
|
|
361
|
-
# @method receive_message_chain
|
|
362
356
|
# @overload receive_message_chain(method1, method2)
|
|
363
357
|
# @overload receive_message_chain("method1.method2")
|
|
364
358
|
# @overload receive_message_chain(method1, method_to_value_hash)
|
|
@@ -386,7 +380,9 @@ module RSpec
|
|
|
386
380
|
# # Common use in Rails/ActiveRecord:
|
|
387
381
|
# allow(Article).to receive_message_chain("recent.published") { [Article.new] }
|
|
388
382
|
#
|
|
389
|
-
|
|
383
|
+
def receive_message_chain(*messages, &block)
|
|
384
|
+
Matchers::ReceiveMessageChain.new(messages, &block)
|
|
385
|
+
end
|
|
390
386
|
|
|
391
387
|
# @private
|
|
392
388
|
def self.included(klass)
|
|
@@ -425,9 +421,13 @@ module RSpec
|
|
|
425
421
|
type.new(*args)
|
|
426
422
|
end
|
|
427
423
|
|
|
428
|
-
# This module exists to
|
|
424
|
+
# This module exists to provide the `expect` method for cases where
|
|
429
425
|
# rspec-mocks is used w/o rspec-expectations.
|
|
430
426
|
module ExpectHost
|
|
427
|
+
# @private
|
|
428
|
+
def expect(target)
|
|
429
|
+
ExpectationTarget.new(target)
|
|
430
|
+
end
|
|
431
431
|
end
|
|
432
432
|
end
|
|
433
433
|
end
|