rspec-mocks 3.1.3 → 3.2.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
  SHA1:
3
- metadata.gz: 8967bb910d6e9e42450e14ac9ce3fd37b078ba5e
4
- data.tar.gz: e05cfe6e3b29c252f091de7f562e3b2424a14a1c
3
+ metadata.gz: 23676d8c392cc0e21a6fc7fdec5248f084775150
4
+ data.tar.gz: fbaf8723ad0840c4da3dc8c6cc21093d2bd2f1c7
5
5
  SHA512:
6
- metadata.gz: 72a62c1548028c0517d412fdd5b62bd8047135a6a25696f180df864b9cc4e0332be07f29290888fe1375afa7de822e404f36d6111e83ab739dee57cbf5676c17
7
- data.tar.gz: 496c5678781c6c5f14a3d929521f3e57698a28bf25766efd67eb5d918f93c108467228636275fbedbf71a34b56d28acb001ce47a6bd215cf74bb28e465b28b39
6
+ metadata.gz: 2563565823fee6d8c5f0a3358af1fb0ed0a12d77f1128c82bcae6d3583cfdd7206d59dfbf2d0213d10ce10c5a480b31317b92194586c0ce7e1fb800e4e8b95c5
7
+ data.tar.gz: 00664f4764abbf01ab4c93986454c1d7582abba0fefc378f5abf1a4908fc2e66028242565843377b53e4f58310937d8c7c4747a2b961c9009e36774be83a4e62
Binary file
data.tar.gz.sig CHANGED
@@ -1,3 +1,5 @@
1
- �V��F��W��S��
2
- r65Vr�����m}�[��?�j5w��b�<:n��1�Ҝl9K(%p��6��wx��-Z����ڃm��������D�L����t7a����6I��~�>��p%]` �ՅN����앻��rz��q��w�㟢Ra�hؑj
3
- "E� DL��v�g�G.QR�Óc�nJ�,��j{4�)�qNJ+�)Dg�N�2���&%��w�ׯ��#a
1
+ *�$���W��_��Y�&Q�H$$Y"p+@�΢@�ڟ�TO�@��.7ીu�[�d�}�)�5˸p���\��p������B�f�j��w��K�|�)�K{bC�
2
+ b��hl?Ս�)qx���ٮ�eXIY�ё�ء"o��E��P������<�U}�yf�罣� ��[�ܲx
3
+ Mcl�|��
4
+ �ި�7�=63[?�����;�[\���x�Jɸn@� �@�ʎ���x�*�=O��h�;�%��Ya^R�M/��n�*o�W�$Ze�dR�%�=
5
+ �������#��y� �����1ʔ��t�"�2� *(C������8+�r�=�M
@@ -1,3 +1,59 @@
1
+ ### 3.2.0 / 2015-02-03
2
+ [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.3...v3.2.0)
3
+
4
+ Enhancements:
5
+
6
+ * Treat `any_args` as an arg splat, allowing it to match an arbitrary
7
+ number of args at any point in an arg list. (Myron Marston, #786)
8
+ * Print diffs when arguments in mock expectations are mismatched.
9
+ (Sam Phippen, #751)
10
+ * Support names for verified doubles (`instance_double`, `instance_spy`,
11
+ `class_double`, `class_spy`, `object_double`, `object_spy`). (Cezary
12
+ Baginski, #826)
13
+ * Make `array_including` and `hash_including` argument matchers composable.
14
+ (Sam Phippen, #819)
15
+ * Make `allow_any_instance_of(...).to receive(...).and_wrap_original`
16
+ work. (Ryan Fitzgerald, #869)
17
+
18
+ Bug Fixes:
19
+
20
+ * Provide a clear error when users wrongly combine `no_args` with
21
+ additional arguments (e.g. `expect().to receive().with(no_args, 1)`).
22
+ (Myron Marston, #786)
23
+ * Provide a clear error when users wrongly use `any_args` multiple times in the
24
+ same argument list (e.g. `expect().to receive().with(any_args, 1, any_args)`.
25
+ (Myron Marston, #786)
26
+ * Prevent the error generator from using user object #description methods.
27
+ See [#685](https://github.com/rspec/rspec-mocks/issues/685).
28
+ (Sam Phippen, #751)
29
+ * Make verified doubles declared as `(instance|class)_double(SomeConst)`
30
+ work properly when `SomeConst` has previously been stubbed.
31
+ `(instance|class)_double("SomeClass")` already worked properly.
32
+ (Myron Marston, #824)
33
+ * Add a matcher description for `receive`, `receive_messages` and
34
+ `receive_message_chain`. (Myron Marston, #828)
35
+ * Validate invocation args for null object verified doubles.
36
+ (Myron Marston, #829)
37
+ * Fix `RSpec::Mocks::Constant.original` when called with an invalid
38
+ constant to return an object indicating the constant name is invalid,
39
+ rather than blowing up. (Myron Marston, #833)
40
+ * Make `extend RSpec::Mocks::ExampleMethods` on any object work properly
41
+ to add the rspec-mocks API to that object. Previously, `expect` would
42
+ be undefined. (Myron Marston, #846)
43
+ * Fix `require 'rspec/mocks/standalone'` so that it only affects `main`
44
+ and not every object. It's really only intended to be used in a REPL
45
+ like IRB, but some gems have loaded it, thinking it needs to be loaded
46
+ when using rspec-mocks outside the context of rspec-core.
47
+ (Myron Marston, #846)
48
+ * Prevent message expectations from being modified by customization methods
49
+ (e.g. `with`) after they have been invoked. (Sam Phippen and Melanie Gilman, #837)
50
+ * Handle cases where a method stub cannot be removed due to something
51
+ external to RSpec monkeying with the method definition. This can
52
+ happen, for example, when you `file.reopen(io)` after previously
53
+ stubbing a method on the `file` object. (Myron Marston, #853)
54
+ * Provide a clear error when received message args are mutated before
55
+ a `have_received(...).with(...)` expectation. (Myron Marston, #868)
56
+
1
57
  ### 3.1.3 / 2014-10-08
2
58
  [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.2...v3.1.3)
3
59
 
@@ -48,7 +104,7 @@ Enhancements:
48
104
  * Add `and_wrap_original` modifier for partial doubles to mutate the
49
105
  response from a method. (Jon Rowe, #762)
50
106
 
51
- Bugfixes:
107
+ Bug Fixes:
52
108
 
53
109
  * Remove `any_number_of_times` from `any_instance` recorders that were
54
110
  erroneously causing mention of the method in documentation. (Jon Rowe, #760)
@@ -240,7 +296,7 @@ Bug Fixes:
240
296
  behavior. (Maurício Linhares)
241
297
 
242
298
  ### 3.0.0.beta1 / 2013-11-07
243
- [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.2...v3.0.0.beta1)
299
+ [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.3...v3.0.0.beta1)
244
300
 
245
301
  Breaking Changes for 3.0.0:
246
302
 
@@ -303,6 +359,13 @@ Bug Fixes:
303
359
  returns `nil` or `''` so that you still get a useful message.
304
360
  (Nick DeLuca)
305
361
 
362
+ ### 2.99.3 / 2015-01-09
363
+ [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.2...v2.99.3)
364
+
365
+ Bug Fixes:
366
+
367
+ * Fix regression that caused an error when a test double was deserialized from YAML. (Yuji Nakayama, #777)
368
+
306
369
  ### 2.99.2 / 2014-07-21
307
370
  [Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.1...v2.99.2)
308
371
 
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # RSpec Mocks [![Build Status](https://secure.travis-ci.org/rspec/rspec-mocks.png?branch=master)](http://travis-ci.org/rspec/rspec-mocks) [![Code Climate](https://codeclimate.com/github/rspec/rspec-mocks.png)](https://codeclimate.com/github/rspec/rspec-mocks)
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)
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,6 +8,15 @@ 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
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 => "git://github.com/rspec/#{lib}.git", :branch => 'master'
17
+ end
18
+ ```
19
+
11
20
  ## Test Doubles
12
21
 
13
22
  A test double is an object that stands in for another object in your system
@@ -32,6 +41,16 @@ isolation without your dependencies loaded while still being able to validate
32
41
  them against real objects. More detail is available in [their
33
42
  documentation](https://github.com/rspec/rspec-mocks/blob/master/features/verifying_doubles).
34
43
 
44
+ Verifying doubles can also accept custom identifiers, just like double(), e.g.:
45
+
46
+ ```ruby
47
+ books = []
48
+ books << instance_double("Book", :rspec_book, :pages => 250)
49
+ books << instance_double("Book", "(Untitled)", :pages => 5000)
50
+
51
+ puts books.inspect # with names, it's clearer which were actually added
52
+ ```
53
+
35
54
  ## Method Stubs
36
55
 
37
56
  A method stub is an implementation that returns a pre-determined value. Method
@@ -42,7 +61,7 @@ rspec-mocks supports 3 forms for declaring method stubs:
42
61
  allow(book).to receive(:title) { "The RSpec Book" }
43
62
  allow(book).to receive(:title).and_return("The RSpec Book")
44
63
  allow(book).to receive_messages(
45
- :title => "The RSpec Book",
64
+ :title => "The RSpec Book",
46
65
  :subtitle => "Behaviour-Driven Development with RSpec, Cucumber, and Friends")
47
66
  ```
48
67
 
@@ -206,8 +225,9 @@ rspec-mocks also adds some keyword Symbols that you can use to
206
225
  specify certain kinds of arguments:
207
226
 
208
227
  ```ruby
209
- expect(double).to receive(:msg).with(no_args())
210
- expect(double).to receive(:msg).with(any_args())
228
+ expect(double).to receive(:msg).with(no_args)
229
+ expect(double).to receive(:msg).with(any_args)
230
+ expect(double).to receive(:msg).with(1, any_args) # any args acts like an arg splat and can go anywhere
211
231
  expect(double).to receive(:msg).with(1, kind_of(Numeric), "b") #2nd argument can be any kind of Numeric
212
232
  expect(double).to receive(:msg).with(1, boolean(), "b") #2nd argument can be true or false
213
233
  expect(double).to receive(:msg).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp
@@ -366,7 +386,7 @@ general we discourage its use for a number of reasons:
366
386
 
367
387
  * The `rspec-mocks` API is designed for individual object instances, but this
368
388
  feature operates on entire classes of objects. As a result there are some
369
- sematically confusing edge cases. For example in
389
+ semantically confusing edge cases. For example in
370
390
  `expect_any_instance_of(Widget).to receive(:name).twice` it isn't clear
371
391
  whether each specific instance is expected to receive `name` twice, or if two
372
392
  receives total are expected. (It's the former.)
@@ -34,6 +34,7 @@ module RSpec
34
34
  record :and_throw
35
35
  record :and_yield
36
36
  record :and_call_original
37
+ record :and_wrap_original
37
38
  record :with
38
39
  record :once
39
40
  record :twice
@@ -31,7 +31,8 @@ module RSpec
31
31
  :and_return => [:with, nil],
32
32
  :and_raise => [:with, nil],
33
33
  :and_yield => [:with, nil],
34
- :and_call_original => [:with, nil]
34
+ :and_call_original => [:with, nil],
35
+ :and_wrap_original => [:with, nil]
35
36
  }
36
37
  end
37
38
 
@@ -44,12 +44,7 @@ module RSpec
44
44
  # @see #args_match?
45
45
  def initialize(*expected_args)
46
46
  @expected_args = expected_args
47
-
48
- @matchers = case expected_args.first
49
- when ArgumentMatchers::AnyArgsMatcher then Array
50
- when ArgumentMatchers::NoArgsMatcher then []
51
- else expected_args
52
- end
47
+ ensure_expected_args_valid!
53
48
  end
54
49
 
55
50
  # @api public
@@ -60,13 +55,46 @@ module RSpec
60
55
  #
61
56
  # @see #initialize
62
57
  def args_match?(*args)
63
- Support::FuzzyMatcher.values_match?(@matchers, args)
58
+ Support::FuzzyMatcher.values_match?(resolve_expected_args_based_on(args), args)
59
+ end
60
+
61
+ # @private
62
+ # Resolves abstract arg placeholders like `no_args` and `any_args` into
63
+ # a more concrete arg list based on the provided `actual_args`.
64
+ def resolve_expected_args_based_on(actual_args)
65
+ return [] if [ArgumentMatchers::NoArgsMatcher::INSTANCE] == expected_args
66
+
67
+ any_args_index = expected_args.index(ArgumentMatchers::AnyArgsMatcher::INSTANCE)
68
+ return expected_args unless any_args_index
69
+
70
+ replace_any_args_with_splat_of_anything(any_args_index, actual_args.count)
71
+ end
72
+
73
+ private
74
+
75
+ def replace_any_args_with_splat_of_anything(before_count, actual_args_count)
76
+ any_args_count = actual_args_count - expected_args.count + 1
77
+ after_count = expected_args.count - before_count - 1
78
+
79
+ any_args = 1.upto(any_args_count).map { ArgumentMatchers::AnyArgMatcher::INSTANCE }
80
+ expected_args.first(before_count) + any_args + expected_args.last(after_count)
81
+ end
82
+
83
+ def ensure_expected_args_valid!
84
+ if expected_args.count(ArgumentMatchers::AnyArgsMatcher::INSTANCE) > 1
85
+ raise ArgumentError, "`any_args` can only be passed to " \
86
+ "`with` once but you have passed it multiple times."
87
+ elsif expected_args.count > 1 && expected_args.include?(ArgumentMatchers::NoArgsMatcher::INSTANCE)
88
+ raise ArgumentError, "`no_args` can only be passed as a " \
89
+ "singleton argument to `with` (i.e. `with(no_args)`), " \
90
+ "but you have passed additional arguments."
91
+ end
64
92
  end
65
93
 
66
94
  # Value that will match all argument lists.
67
95
  #
68
96
  # @private
69
- MATCH_ALL = new(ArgumentMatchers::AnyArgsMatcher.new)
97
+ MATCH_ALL = new(ArgumentMatchers::AnyArgsMatcher::INSTANCE)
70
98
  end
71
99
  end
72
100
  end
@@ -14,14 +14,18 @@ module RSpec
14
14
  #
15
15
  # @see ArgumentListMatcher
16
16
  module ArgumentMatchers
17
- # Matches any args at all. Supports a more explicit variation of
18
- # `expect(object).to receive(:message)`
17
+ # Acts like an arg splat, matching any number of args at any point in an arg list.
19
18
  #
20
19
  # @example
21
20
  #
22
- # expect(object).to receive(:message).with(any_args)
21
+ # expect(object).to receive(:message).with(1, 2, any_args)
22
+ #
23
+ # # matches any of these:
24
+ # object.message(1, 2)
25
+ # object.message(1, 2, 3)
26
+ # object.message(1, 2, 3, 4)
23
27
  def any_args
24
- AnyArgsMatcher.new
28
+ AnyArgsMatcher::INSTANCE
25
29
  end
26
30
 
27
31
  # Matches any argument at all.
@@ -30,7 +34,7 @@ module RSpec
30
34
  #
31
35
  # expect(object).to receive(:message).with(anything)
32
36
  def anything
33
- AnyArgMatcher.new
37
+ AnyArgMatcher::INSTANCE
34
38
  end
35
39
 
36
40
  # Matches no arguments.
@@ -39,7 +43,7 @@ module RSpec
39
43
  #
40
44
  # expect(object).to receive(:message).with(no_args)
41
45
  def no_args
42
- NoArgsMatcher.new
46
+ NoArgsMatcher::INSTANCE
43
47
  end
44
48
 
45
49
  # Matches if the actual argument responds to the specified messages.
@@ -58,7 +62,7 @@ module RSpec
58
62
  #
59
63
  # expect(object).to receive(:message).with(boolean())
60
64
  def boolean
61
- BooleanMatcher.new
65
+ BooleanMatcher::INSTANCE
62
66
  end
63
67
 
64
68
  # Matches a hash that includes the specified key(s) or key/value pairs.
@@ -122,19 +126,36 @@ module RSpec
122
126
  # @private
123
127
  def self.anythingize_lonely_keys(*args)
124
128
  hash = args.last.class == Hash ? args.delete_at(-1) : {}
125
- args.each { | arg | hash[arg] = AnyArgMatcher.new }
129
+ args.each { | arg | hash[arg] = AnyArgMatcher::INSTANCE }
126
130
  hash
127
131
  end
128
132
 
133
+ # Intended to be subclassed by stateless, immutable argument matchers.
134
+ # Provides a `<klass name>::INSTANCE` constant for accessing a global
135
+ # singleton instance of the matcher. There is no need to construct
136
+ # multiple instance since there is no state. It also facilities the
137
+ # special case logic we need for some of these matchers, by making it
138
+ # easy to do comparisons like: `[klass::INSTANCE] == args` rather than
139
+ # `args.count == 1 && klass === args.first`.
140
+ #
141
+ # @private
142
+ class SingletonMatcher
143
+ private_class_method :new
144
+
145
+ def self.inherited(subklass)
146
+ subklass.const_set(:INSTANCE, subklass.send(:new))
147
+ end
148
+ end
149
+
129
150
  # @private
130
- class AnyArgsMatcher
151
+ class AnyArgsMatcher < SingletonMatcher
131
152
  def description
132
- "any args"
153
+ "*(any args)"
133
154
  end
134
155
  end
135
156
 
136
157
  # @private
137
- class AnyArgMatcher
158
+ class AnyArgMatcher < SingletonMatcher
138
159
  def ===(_other)
139
160
  true
140
161
  end
@@ -145,14 +166,14 @@ module RSpec
145
166
  end
146
167
 
147
168
  # @private
148
- class NoArgsMatcher
169
+ class NoArgsMatcher < SingletonMatcher
149
170
  def description
150
171
  "no args"
151
172
  end
152
173
  end
153
174
 
154
175
  # @private
155
- class BooleanMatcher
176
+ class BooleanMatcher < SingletonMatcher
156
177
  def ===(value)
157
178
  true == value || false == value
158
179
  end
@@ -177,7 +198,20 @@ module RSpec
177
198
  end
178
199
 
179
200
  def description(name)
180
- "#{name}(#{@expected.inspect.sub(/^\{/, "").sub(/\}$/, "")})"
201
+ "#{name}(#{formatted_expected_hash.inspect.sub(/^\{/, "").sub(/\}$/, "")})"
202
+ end
203
+
204
+ private
205
+
206
+ def formatted_expected_hash
207
+ Hash[
208
+ @expected.map do |k, v|
209
+ k = RSpec::Support.rspec_description_for_object(k)
210
+ v = RSpec::Support.rspec_description_for_object(v)
211
+
212
+ [k, v]
213
+ end
214
+ ]
181
215
  end
182
216
  end
183
217
 
@@ -210,11 +244,24 @@ module RSpec
210
244
  end
211
245
 
212
246
  def ===(actual)
213
- Set.new(actual).superset?(Set.new(@expected))
247
+ actual = actual.uniq
248
+ @expected.uniq.all? do |expected_element|
249
+ actual.any? do |actual_element|
250
+ RSpec::Support::FuzzyMatcher.values_match?(expected_element, actual_element)
251
+ end
252
+ end
214
253
  end
215
254
 
216
255
  def description
217
- "array_including(#{@expected.join(", ")})"
256
+ "array_including(#{formatted_expected_values})"
257
+ end
258
+
259
+ private
260
+
261
+ def formatted_expected_values
262
+ @expected.map do |x|
263
+ RSpec::Support.rspec_description_for_object(x)
264
+ end.join(", ")
218
265
  end
219
266
  end
220
267
 
@@ -104,6 +104,23 @@ module RSpec
104
104
  # isolated unit test will prevent you from being able to isolate it!
105
105
  attr_writer :verify_doubled_constant_names
106
106
 
107
+ # Provides a way to perform customisations when verifying doubles.
108
+ #
109
+ # @example
110
+ #
111
+ # RSpec::Mocks.configuration.when_declaring_verifying_double do |ref|
112
+ # ref.some_method!
113
+ # end
114
+ def when_declaring_verifying_double(&block)
115
+ verifying_double_declaration_callbacks << block
116
+ end
117
+
118
+ # @api private
119
+ # Returns an array of blocks to call when verifying doubles
120
+ def verifying_double_declaration_callbacks
121
+ @verifying_double_declaration_callbacks ||= []
122
+ end
123
+
107
124
  def transfer_nested_constants?
108
125
  !!@transfer_nested_constants
109
126
  end
@@ -123,6 +140,24 @@ module RSpec
123
140
  @verify_partial_doubles
124
141
  end
125
142
 
143
+ if ::RSpec.respond_to?(:configuration)
144
+ def color?
145
+ ::RSpec.configuration.color_enabled?
146
+ end
147
+ else
148
+ # Indicates whether or not diffs should be colored.
149
+ # Delegates to rspec-core's color option if rspec-core
150
+ # is loaded; otherwise you can set it here.
151
+ attr_writer :color
152
+
153
+ # Indicates whether or not diffs should be colored.
154
+ # Delegates to rspec-core's color option if rspec-core
155
+ # is loaded; otherwise you can set it here.
156
+ def color?
157
+ @color
158
+ end
159
+ end
160
+
126
161
  # Monkey-patch `Marshal.dump` to enable dumping of mocked or stubbed
127
162
  # objects. By default this will not work since RSpec mocks works by
128
163
  # adding singleton methods that cannot be serialized. This patch removes