rspec-mocks 3.8.2 → 3.10.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 863a1af1be0ed566b9345a1bdb9ec999137b959e8612b102d6af6e8b43ecd001
4
- data.tar.gz: 01f7282d03cea9cf658c3ada9bb008d7ab9f3d60313e092b9709a0b0e28685b3
3
+ metadata.gz: 8df50d671b287d9eea08c7e0af0cc98ae18da52ce63543c0e48378d4230a889f
4
+ data.tar.gz: 0e8e4186d4eefc8344439185e0533a53b980fd983f80d8faf600c5fe7f5ebf2d
5
5
  SHA512:
6
- metadata.gz: 218a26419d38c53216a2c5a0275296b1c70239a240e0de6bc7cfbd8d837e703e2e1bd424fe11829400d7182c7f88a6d9690f4851f9883b8c87da6ae9c7e88378
7
- data.tar.gz: 4c746074ce149784310c2aec5b7d0ba5939106a07bcd23ba8b9d917756cd99c849a7befdd052c71b241fc21c066a337e0c1fb286442cb4099d2b72e2729315d8
6
+ metadata.gz: 0b687302ef0bd48764d9b78df91c0ce9f4918e9697493fbf0d4083f77ac4bd99879a68975bca874b06a887d1f83bcaaca35f476d4a4036286684c37bb3e040c6
7
+ data.tar.gz: 102e13e93f56865812cf40a46e3be075f67984dde3eaae091b3b14ffae2c96623f6c2e85112c6ffe759fc7be83c4ba8d0133b59fa91d5d0a3055307dc5c13273
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,56 @@
1
+ ### Development
2
+ [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.2...main)
3
+
4
+ ### 3.10.2 / 2021-01-27
5
+ [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.1...v3.10.2)
6
+
7
+ Bug Fixes:
8
+
9
+ * Support keyword arguments with `and_call_original` on Ruby 3.0.
10
+ (Bryan Powell, #1385)
11
+ * `RSpec::Mocks::Constant#previously_defined?` is now always a boolean.
12
+ (Phil Pirozhkov, #1397)
13
+ * Support keyword arguments on Ruby 3.0 when used with `expect_any_instance_of`
14
+ or `allow_any_instance_of` with `and_call_original`.
15
+ (Jess Hottenstein, #1407)
16
+
17
+ ### 3.10.1 / 2020-12-27
18
+ [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.0...v3.10.1)
19
+
20
+ Bug Fixes:
21
+
22
+ * Issue `ArgumentError` rather than `TypeError` when unsupported methods on
23
+ unsupported objects are attempted to be stubbed. (@zhisme, #1357)
24
+
25
+ ### 3.10.0 / 2020-10-30
26
+ [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.9.1...v3.10.0)
27
+
28
+ Enhancements:
29
+ * Add the ability to set a custom error generator in `MessageExpectation`.
30
+ This will allow rspec-expectations to inject a custom failure message.
31
+ (Benoit Tigeot and Nicolas Zermati, #1312)
32
+ * Return the result of the block passed to `RSpec::Mocks.with_temporary_scope`
33
+ when block run. (@expeehaa, #1329)
34
+
35
+ ### 3.9.1 / 2019-12-31
36
+ [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.9.0...v3.9.1)
37
+
38
+ Bug Fixes:
39
+
40
+ * Trigger `RSpec::Mocks.configuration.verifying_double_callbacks` when using
41
+ `allow_any_instance_of` or `expect_any_instance_of` (Daniel Orner, #1309)
42
+
43
+ ### 3.9.0 / 2019-10-07
44
+ [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.8.2...v3.9.0)
45
+
46
+ Enhancements:
47
+
48
+ * Improve thread safety of message expectations by using Mutex to prevent
49
+ deadlocking errors. (Ry Biesemeyer, #1236)
50
+ * Add the ability to use `time` as an alias for `times`. For example:
51
+ `expect(Class).to receive(:method).exactly(1).time`.
52
+ (Pistos, Benoit Tigeot, #1271)
53
+
1
54
  ### 3.8.2 / 2019-10-02
2
55
  [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.8.1...v3.8.2)
3
56
 
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # RSpec Mocks [![Build Status](https://secure.travis-ci.org/rspec/rspec-mocks.svg?branch=master)](http://travis-ci.org/rspec/rspec-mocks) [![Code Climate](https://codeclimate.com/github/rspec/rspec-mocks.svg)](https://codeclimate.com/github/rspec/rspec-mocks)
1
+ # RSpec Mocks [![Build Status](https://github.com/rspec/rspec-mocks/workflows/RSpec%20CI/badge.svg?branch=3-10-maintenance)](https://github.com/rspec/rspec-mocks/actions) [![Code Climate](https://codeclimate.com/github/rspec/rspec-mocks.svg)](https://codeclimate.com/github/rspec/rspec-mocks)
2
2
  rspec-mocks is a test-double framework for rspec with support for method stubs,
3
3
  fakes, and message expectations on generated test-doubles and real objects
4
4
  alike.
@@ -8,12 +8,12 @@ alike.
8
8
  gem install rspec # for rspec-core, rspec-expectations, rspec-mocks
9
9
  gem install rspec-mocks # for rspec-mocks only
10
10
 
11
- Want to run against the `master` branch? You'll need to include the dependent
11
+ Want to run against the `main` branch? You'll need to include the dependent
12
12
  RSpec repos as well. Add the following to your `Gemfile`:
13
13
 
14
14
  ```ruby
15
15
  %w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
16
- gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'master'
16
+ gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main'
17
17
  end
18
18
  ```
19
19
  ## Contributing
@@ -53,7 +53,7 @@ book = instance_double("Book", :pages => 250)
53
53
  Verifying doubles have some clever tricks to enable you to both test in
54
54
  isolation without your dependencies loaded while still being able to validate
55
55
  them against real objects. More detail is available in [their
56
- documentation](https://github.com/rspec/rspec-mocks/blob/master/features/verifying_doubles).
56
+ documentation](https://github.com/rspec/rspec-mocks/blob/main/features/verifying_doubles).
57
57
 
58
58
  Verifying doubles can also accept custom identifiers, just like double(), e.g.:
59
59
 
@@ -285,12 +285,15 @@ expect(double).to receive(:msg).with(hash_excluding(:a => 5)) # first arg is a h
285
285
  ```ruby
286
286
  expect(double).to receive(:msg).once
287
287
  expect(double).to receive(:msg).twice
288
+ expect(double).to receive(:msg).exactly(n).time
288
289
  expect(double).to receive(:msg).exactly(n).times
289
290
  expect(double).to receive(:msg).at_least(:once)
290
291
  expect(double).to receive(:msg).at_least(:twice)
292
+ expect(double).to receive(:msg).at_least(n).time
291
293
  expect(double).to receive(:msg).at_least(n).times
292
294
  expect(double).to receive(:msg).at_most(:once)
293
295
  expect(double).to receive(:msg).at_most(:twice)
296
+ expect(double).to receive(:msg).at_most(n).time
294
297
  expect(double).to receive(:msg).at_most(n).times
295
298
  ```
296
299
 
@@ -327,7 +330,7 @@ expect(double).to receive(:msg).and_return(value)
327
330
  expect(double).to receive(:msg).exactly(3).times.and_return(value1, value2, value3)
328
331
  # returns value1 the first time, value2 the second, etc
329
332
  expect(double).to receive(:msg).and_raise(error)
330
- # error can be an instantiated object or a class
333
+ # `error` can be an instantiated object (e.g. `StandardError.new(some_arg)`) or a class (e.g. `StandardError`)
331
334
  # if it is a class, it must be instantiable with no args
332
335
  expect(double).to receive(:msg).and_throw(:msg)
333
336
  expect(double).to receive(:msg).and_yield(values, to, yield)
@@ -400,7 +403,7 @@ your code.
400
403
  ## Stubbing and Hiding Constants
401
404
 
402
405
  See the [mutating constants
403
- README](https://github.com/rspec/rspec-mocks/blob/master/features/mutating_constants/README.md)
406
+ README](https://github.com/rspec/rspec-mocks/blob/main/features/mutating_constants/README.md)
404
407
  for info on this feature.
405
408
 
406
409
  ## Use `before(:example)`, not `before(:context)`
@@ -87,12 +87,15 @@ module RSpec
87
87
 
88
88
  # Call the passed block and verify mocks after it has executed. This allows
89
89
  # mock usage in arbitrary places, such as a `before(:all)` hook.
90
+ #
91
+ # @return [Object] the return value from the block
90
92
  def self.with_temporary_scope
91
93
  setup
92
94
 
93
95
  begin
94
- yield
96
+ result = yield
95
97
  verify
98
+ result
96
99
  ensure
97
100
  teardown
98
101
  end
@@ -41,6 +41,7 @@ module RSpec
41
41
  record :thrice
42
42
  record :exactly
43
43
  record :times
44
+ record :time
44
45
  record :never
45
46
  record :at_least
46
47
  record :at_most
@@ -21,6 +21,11 @@ module RSpec
21
21
  @backed_up_method_owner = {}
22
22
  @klass = klass
23
23
  @expectation_set = false
24
+
25
+ return unless RSpec::Mocks.configuration.verify_partial_doubles?
26
+ RSpec::Mocks.configuration.verifying_double_callbacks.each do |block|
27
+ block.call(ObjectReference.for(klass))
28
+ end
24
29
  end
25
30
 
26
31
  # Initializes the recording a stub to be played back against any
@@ -256,6 +261,7 @@ module RSpec
256
261
  recorder.playback!(self, method_name)
257
262
  __send__(method_name, *args, &blk)
258
263
  end
264
+ @klass.__send__(:ruby2_keywords, method_name) if @klass.respond_to?(:ruby2_keywords, true)
259
265
  end
260
266
 
261
267
  def mark_invoked!(method_name)
@@ -5,7 +5,7 @@ module RSpec
5
5
  class HaveReceived
6
6
  include Matcher
7
7
 
8
- COUNT_CONSTRAINTS = %w[exactly at_least at_most times once twice thrice]
8
+ COUNT_CONSTRAINTS = %w[exactly at_least at_most times time once twice thrice]
9
9
  ARGS_CONSTRAINTS = %w[with]
10
10
  CONSTRAINTS = COUNT_CONSTRAINTS + ARGS_CONSTRAINTS + %w[ordered]
11
11
 
@@ -1,3 +1,5 @@
1
+ RSpec::Support.require_rspec_support 'mutex'
2
+
1
3
  module RSpec
2
4
  module Mocks
3
5
  # A message expectation that only allows concrete return values to be set
@@ -236,6 +238,7 @@ module RSpec
236
238
  self.inner_implementation_action = block
237
239
  self
238
240
  end
241
+ alias time times
239
242
 
240
243
  # Expect a message not to be received at all.
241
244
  #
@@ -357,12 +360,13 @@ module RSpec
357
360
  # some collaborators it delegates to for this stuff but for now this was
358
361
  # the simplest way to split the public from private stuff to make it
359
362
  # easier to publish the docs for the APIs we want published.
363
+ # rubocop:disable Metrics/ModuleLength
360
364
  module ImplementationDetails
361
365
  attr_accessor :error_generator, :implementation
362
366
  attr_reader :message
363
367
  attr_reader :orig_object
364
368
  attr_writer :expected_received_count, :expected_from, :argument_list_matcher
365
- protected :expected_received_count=, :expected_from=, :error_generator, :error_generator=, :implementation=
369
+ protected :expected_received_count=, :expected_from=, :error_generator=, :implementation=
366
370
 
367
371
  # @private
368
372
  attr_reader :type
@@ -372,12 +376,13 @@ module RSpec
372
376
  type=:expectation, opts={}, &implementation_block)
373
377
  @type = type
374
378
  @error_generator = error_generator
375
- @error_generator.opts = opts
379
+ @error_generator.opts = error_generator.opts.merge(opts)
376
380
  @expected_from = expected_from
377
381
  @method_double = method_double
378
382
  @orig_object = @method_double.object
379
383
  @message = @method_double.method_name
380
384
  @actual_received_count = 0
385
+ @actual_received_count_write_mutex = Support::Mutex.new
381
386
  @expected_received_count = type == :expectation ? 1 : :any
382
387
  @argument_list_matcher = ArgumentListMatcher::MATCH_ALL
383
388
  @order_group = expectation_ordering
@@ -536,7 +541,9 @@ module RSpec
536
541
  end
537
542
 
538
543
  def increase_actual_received_count!
539
- @actual_received_count += 1
544
+ @actual_received_count_write_mutex.synchronize do
545
+ @actual_received_count += 1
546
+ end
540
547
  end
541
548
 
542
549
  private
@@ -567,7 +574,9 @@ module RSpec
567
574
  parent_stub.invoke(nil, *args, &block)
568
575
  end
569
576
  ensure
570
- @actual_received_count += increment
577
+ @actual_received_count_write_mutex.synchronize do
578
+ @actual_received_count += increment
579
+ end
571
580
  end
572
581
 
573
582
  def has_been_invoked?
@@ -626,6 +635,7 @@ module RSpec
626
635
  nil
627
636
  end
628
637
  end
638
+ # rubocop:enable Metrics/ModuleLength
629
639
 
630
640
  include ImplementationDetails
631
641
  end
@@ -63,6 +63,7 @@ module RSpec
63
63
  define_method(method_name) do |*args, &block|
64
64
  method_double.proxy_method_invoked(self, *args, &block)
65
65
  end
66
+ ruby2_keywords(method_name) if Module.private_method_defined?(:ruby2_keywords)
66
67
  __send__(visibility, method_name)
67
68
  end
68
69
 
@@ -66,7 +66,7 @@ module RSpec
66
66
 
67
67
  # @private
68
68
  def self.unmutated(name)
69
- previously_defined = recursive_const_defined?(name)
69
+ previously_defined = !!recursive_const_defined?(name)
70
70
  rescue NameError
71
71
  new(name) do |c|
72
72
  c.valid_name = false
@@ -9,6 +9,11 @@ module RSpec
9
9
  end
10
10
  end
11
11
 
12
+ unless defined?(Mutex)
13
+ Support.require_rspec_support 'mutex'
14
+ Mutex = Support::Mutex
15
+ end
16
+
12
17
  # @private
13
18
  def ensure_implemented(*_args)
14
19
  # noop for basic proxies, see VerifyingProxy for behaviour.
@@ -16,15 +21,32 @@ module RSpec
16
21
 
17
22
  # @private
18
23
  def initialize(object, order_group, options={})
24
+ ensure_can_be_proxied!(object)
25
+
19
26
  @object = object
20
27
  @order_group = order_group
21
28
  @error_generator = ErrorGenerator.new(object)
22
29
  @messages_received = []
30
+ @messages_received_mutex = Mutex.new
23
31
  @options = options
24
32
  @null_object = false
25
33
  @method_doubles = Hash.new { |h, k| h[k] = MethodDouble.new(@object, k, self) }
26
34
  end
27
35
 
36
+ # @private
37
+ def ensure_can_be_proxied!(object)
38
+ return unless object.is_a?(Symbol) || object.frozen?
39
+ return if object.nil?
40
+
41
+ msg = "Cannot proxy frozen objects"
42
+ if Symbol === object
43
+ msg << ". Symbols such as #{object} cannot be mocked or stubbed."
44
+ else
45
+ msg << ", rspec-mocks relies on proxies for method stubbing and expectations."
46
+ end
47
+ raise ArgumentError, msg
48
+ end
49
+
28
50
  # @private
29
51
  attr_reader :object
30
52
 
@@ -90,27 +112,31 @@ module RSpec
90
112
  @error_generator.raise_expectation_on_unstubbed_method(expected_method_name)
91
113
  end
92
114
 
93
- @messages_received.each do |(actual_method_name, args, received_block)|
94
- next unless expectation.matches?(actual_method_name, *args)
115
+ @messages_received_mutex.synchronize do
116
+ @messages_received.each do |(actual_method_name, args, received_block)|
117
+ next unless expectation.matches?(actual_method_name, *args)
95
118
 
96
- expectation.safe_invoke(nil)
97
- block.call(*args, &received_block) if block
119
+ expectation.safe_invoke(nil)
120
+ block.call(*args, &received_block) if block
121
+ end
98
122
  end
99
123
  end
100
124
 
101
125
  # @private
102
126
  def check_for_unexpected_arguments(expectation)
103
- return if @messages_received.empty?
127
+ @messages_received_mutex.synchronize do
128
+ return if @messages_received.empty?
104
129
 
105
- return if @messages_received.any? { |method_name, args, _| expectation.matches?(method_name, *args) }
130
+ return if @messages_received.any? { |method_name, args, _| expectation.matches?(method_name, *args) }
106
131
 
107
- name_but_not_args, others = @messages_received.partition do |(method_name, args, _)|
108
- expectation.matches_name_but_not_args(method_name, *args)
109
- end
132
+ name_but_not_args, others = @messages_received.partition do |(method_name, args, _)|
133
+ expectation.matches_name_but_not_args(method_name, *args)
134
+ end
110
135
 
111
- return if name_but_not_args.empty? && !others.empty?
136
+ return if name_but_not_args.empty? && !others.empty?
112
137
 
113
- expectation.raise_unexpected_message_args_error(name_but_not_args.map { |args| args[1] })
138
+ expectation.raise_unexpected_message_args_error(name_but_not_args.map { |args| args[1] })
139
+ end
114
140
  end
115
141
 
116
142
  # @private
@@ -141,17 +167,23 @@ module RSpec
141
167
 
142
168
  # @private
143
169
  def reset
144
- @messages_received.clear
170
+ @messages_received_mutex.synchronize do
171
+ @messages_received.clear
172
+ end
145
173
  end
146
174
 
147
175
  # @private
148
176
  def received_message?(method_name, *args, &block)
149
- @messages_received.any? { |array| array == [method_name, args, block] }
177
+ @messages_received_mutex.synchronize do
178
+ @messages_received.any? { |array| array == [method_name, args, block] }
179
+ end
150
180
  end
151
181
 
152
182
  # @private
153
183
  def messages_arg_list
154
- @messages_received.map { |_, args, _| args }
184
+ @messages_received_mutex.synchronize do
185
+ @messages_received.map { |_, args, _| args }
186
+ end
155
187
  end
156
188
 
157
189
  # @private
@@ -162,7 +194,9 @@ module RSpec
162
194
  # @private
163
195
  def record_message_received(message, *args, &block)
164
196
  @order_group.invoked SpecificMessage.new(object, message, args)
165
- @messages_received << [message, args, block]
197
+ @messages_received_mutex.synchronize do
198
+ @messages_received << [message, args, block]
199
+ end
166
200
  end
167
201
 
168
202
  # @private
@@ -3,7 +3,7 @@ module RSpec
3
3
  # Version information for RSpec mocks.
4
4
  module Version
5
5
  # Version of RSpec mocks currently in use in SemVer format.
6
- STRING = '3.8.2'
6
+ STRING = '3.10.2'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-mocks
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.8.2
4
+ version: 3.10.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Baker
8
8
  - David Chelimsky
9
9
  - Myron Marston
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain:
13
13
  - |
@@ -45,7 +45,7 @@ cert_chain:
45
45
  ZsVDj6a7lH3cNqtWXZxrb2wO38qV5AkYj8SQK7Hj3/Yui9myUX3crr+PdetazSqQ
46
46
  F3MdtaDehhjC
47
47
  -----END CERTIFICATE-----
48
- date: 2019-10-02 00:00:00.000000000 Z
48
+ date: 2021-01-28 00:00:00.000000000 Z
49
49
  dependencies:
50
50
  - !ruby/object:Gem::Dependency
51
51
  name: rspec-support
@@ -53,14 +53,14 @@ dependencies:
53
53
  requirements:
54
54
  - - "~>"
55
55
  - !ruby/object:Gem::Version
56
- version: 3.8.0
56
+ version: 3.10.0
57
57
  type: :runtime
58
58
  prerelease: false
59
59
  version_requirements: !ruby/object:Gem::Requirement
60
60
  requirements:
61
61
  - - "~>"
62
62
  - !ruby/object:Gem::Version
63
- version: 3.8.0
63
+ version: 3.10.0
64
64
  - !ruby/object:Gem::Dependency
65
65
  name: diff-lcs
66
66
  requirement: !ruby/object:Gem::Requirement
@@ -85,14 +85,14 @@ dependencies:
85
85
  name: rake
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  requirements:
88
- - - "~>"
88
+ - - ">"
89
89
  - !ruby/object:Gem::Version
90
90
  version: 10.0.0
91
91
  type: :development
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
- - - "~>"
95
+ - - ">"
96
96
  - !ruby/object:Gem::Version
97
97
  version: 10.0.0
98
98
  - !ruby/object:Gem::Dependency
@@ -194,11 +194,11 @@ licenses:
194
194
  - MIT
195
195
  metadata:
196
196
  bug_tracker_uri: https://github.com/rspec/rspec-mocks/issues
197
- changelog_uri: https://github.com/rspec/rspec-mocks/blob/v3.8.2/Changelog.md
197
+ changelog_uri: https://github.com/rspec/rspec-mocks/blob/v3.10.2/Changelog.md
198
198
  documentation_uri: https://rspec.info/documentation/
199
199
  mailing_list_uri: https://groups.google.com/forum/#!forum/rspec
200
200
  source_code_uri: https://github.com/rspec/rspec-mocks
201
- post_install_message:
201
+ post_install_message:
202
202
  rdoc_options:
203
203
  - "--charset=UTF-8"
204
204
  require_paths:
@@ -214,8 +214,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
214
214
  - !ruby/object:Gem::Version
215
215
  version: '0'
216
216
  requirements: []
217
- rubygems_version: 3.0.6
218
- signing_key:
217
+ rubygems_version: 3.2.4
218
+ signing_key:
219
219
  specification_version: 4
220
- summary: rspec-mocks-3.8.2
220
+ summary: rspec-mocks-3.10.2
221
221
  test_files: []
metadata.gz.sig CHANGED
Binary file