rspec-mocks 3.8.2 → 3.9.0

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: f53d2fe5ab69778d6528b80a08aaa48869a527c5185f715671c0d48beecf5db4
4
+ data.tar.gz: 8e06d4be6fbc3dec6cbbdf75d141638db33653579fcd95b4869cb41b97afb4e8
5
5
  SHA512:
6
- metadata.gz: 218a26419d38c53216a2c5a0275296b1c70239a240e0de6bc7cfbd8d837e703e2e1bd424fe11829400d7182c7f88a6d9690f4851f9883b8c87da6ae9c7e88378
7
- data.tar.gz: 4c746074ce149784310c2aec5b7d0ba5939106a07bcd23ba8b9d917756cd99c849a7befdd052c71b241fc21c066a337e0c1fb286442cb4099d2b72e2729315d8
6
+ metadata.gz: 6863b589a173e3985263e2b49c797389e7db68912df5f6f294f23833d66cbeb72b10b9b800cca08383322f1b1775b99f7514878663b715b48d4d6e39582b4836
7
+ data.tar.gz: 320ec537f1f7708bd0fb5317ab3878cb569f2a9dbd676b8b8512f36ece73f5efc0d9f7d85bb8b6b30ac145cc5ff3f10d13212897c19e6559a475526703325e1d
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,14 @@
1
+ ### 3.9.0 / 2019-10-07
2
+ [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.8.2...v3.9.0)
3
+
4
+ Enhancements:
5
+
6
+ * Improve thread safety of message expectations by using Mutex to prevent
7
+ deadlocking errors. (Ry Biesemeyer, #1236)
8
+ * Add the ability to use `time` as an alias for `times`. For example:
9
+ `expect(Class).to receive(:method).exactly(1).time`.
10
+ (Pistos, Benoit Tigeot, #1271)
11
+
1
12
  ### 3.8.2 / 2019-10-02
2
13
  [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.8.1...v3.8.2)
3
14
 
data/README.md CHANGED
@@ -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)
@@ -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
@@ -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,6 +360,7 @@ 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
@@ -378,6 +382,7 @@ module RSpec
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
@@ -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.
@@ -20,6 +25,7 @@ module RSpec
20
25
  @order_group = order_group
21
26
  @error_generator = ErrorGenerator.new(object)
22
27
  @messages_received = []
28
+ @messages_received_mutex = Mutex.new
23
29
  @options = options
24
30
  @null_object = false
25
31
  @method_doubles = Hash.new { |h, k| h[k] = MethodDouble.new(@object, k, self) }
@@ -90,27 +96,31 @@ module RSpec
90
96
  @error_generator.raise_expectation_on_unstubbed_method(expected_method_name)
91
97
  end
92
98
 
93
- @messages_received.each do |(actual_method_name, args, received_block)|
94
- next unless expectation.matches?(actual_method_name, *args)
99
+ @messages_received_mutex.synchronize do
100
+ @messages_received.each do |(actual_method_name, args, received_block)|
101
+ next unless expectation.matches?(actual_method_name, *args)
95
102
 
96
- expectation.safe_invoke(nil)
97
- block.call(*args, &received_block) if block
103
+ expectation.safe_invoke(nil)
104
+ block.call(*args, &received_block) if block
105
+ end
98
106
  end
99
107
  end
100
108
 
101
109
  # @private
102
110
  def check_for_unexpected_arguments(expectation)
103
- return if @messages_received.empty?
111
+ @messages_received_mutex.synchronize do
112
+ return if @messages_received.empty?
104
113
 
105
- return if @messages_received.any? { |method_name, args, _| expectation.matches?(method_name, *args) }
114
+ return if @messages_received.any? { |method_name, args, _| expectation.matches?(method_name, *args) }
106
115
 
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
116
+ name_but_not_args, others = @messages_received.partition do |(method_name, args, _)|
117
+ expectation.matches_name_but_not_args(method_name, *args)
118
+ end
110
119
 
111
- return if name_but_not_args.empty? && !others.empty?
120
+ return if name_but_not_args.empty? && !others.empty?
112
121
 
113
- expectation.raise_unexpected_message_args_error(name_but_not_args.map { |args| args[1] })
122
+ expectation.raise_unexpected_message_args_error(name_but_not_args.map { |args| args[1] })
123
+ end
114
124
  end
115
125
 
116
126
  # @private
@@ -141,17 +151,23 @@ module RSpec
141
151
 
142
152
  # @private
143
153
  def reset
144
- @messages_received.clear
154
+ @messages_received_mutex.synchronize do
155
+ @messages_received.clear
156
+ end
145
157
  end
146
158
 
147
159
  # @private
148
160
  def received_message?(method_name, *args, &block)
149
- @messages_received.any? { |array| array == [method_name, args, block] }
161
+ @messages_received_mutex.synchronize do
162
+ @messages_received.any? { |array| array == [method_name, args, block] }
163
+ end
150
164
  end
151
165
 
152
166
  # @private
153
167
  def messages_arg_list
154
- @messages_received.map { |_, args, _| args }
168
+ @messages_received_mutex.synchronize do
169
+ @messages_received.map { |_, args, _| args }
170
+ end
155
171
  end
156
172
 
157
173
  # @private
@@ -162,7 +178,9 @@ module RSpec
162
178
  # @private
163
179
  def record_message_received(message, *args, &block)
164
180
  @order_group.invoked SpecificMessage.new(object, message, args)
165
- @messages_received << [message, args, block]
181
+ @messages_received_mutex.synchronize do
182
+ @messages_received << [message, args, block]
183
+ end
166
184
  end
167
185
 
168
186
  # @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.9.0'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
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.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Baker
@@ -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: 2019-10-07 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.9.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.9.0
64
64
  - !ruby/object:Gem::Dependency
65
65
  name: diff-lcs
66
66
  requirement: !ruby/object:Gem::Requirement
@@ -194,7 +194,7 @@ 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.9.0/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
@@ -217,5 +217,5 @@ requirements: []
217
217
  rubygems_version: 3.0.6
218
218
  signing_key:
219
219
  specification_version: 4
220
- summary: rspec-mocks-3.8.2
220
+ summary: rspec-mocks-3.9.0
221
221
  test_files: []
metadata.gz.sig CHANGED
Binary file