rspec-mocks-diag 3.8.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.yardopts +6 -0
  4. data/Changelog.md +1108 -0
  5. data/LICENSE.md +25 -0
  6. data/README.md +460 -0
  7. data/lib/rspec/mocks.rb +130 -0
  8. data/lib/rspec/mocks/any_instance.rb +11 -0
  9. data/lib/rspec/mocks/any_instance/chain.rb +110 -0
  10. data/lib/rspec/mocks/any_instance/error_generator.rb +31 -0
  11. data/lib/rspec/mocks/any_instance/expect_chain_chain.rb +31 -0
  12. data/lib/rspec/mocks/any_instance/expectation_chain.rb +50 -0
  13. data/lib/rspec/mocks/any_instance/message_chains.rb +83 -0
  14. data/lib/rspec/mocks/any_instance/proxy.rb +116 -0
  15. data/lib/rspec/mocks/any_instance/recorder.rb +289 -0
  16. data/lib/rspec/mocks/any_instance/stub_chain.rb +51 -0
  17. data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +23 -0
  18. data/lib/rspec/mocks/argument_list_matcher.rb +100 -0
  19. data/lib/rspec/mocks/argument_matchers.rb +320 -0
  20. data/lib/rspec/mocks/configuration.rb +212 -0
  21. data/lib/rspec/mocks/error_generator.rb +378 -0
  22. data/lib/rspec/mocks/example_methods.rb +434 -0
  23. data/lib/rspec/mocks/instance_method_stasher.rb +146 -0
  24. data/lib/rspec/mocks/marshal_extension.rb +41 -0
  25. data/lib/rspec/mocks/matchers/expectation_customization.rb +20 -0
  26. data/lib/rspec/mocks/matchers/have_received.rb +134 -0
  27. data/lib/rspec/mocks/matchers/receive.rb +132 -0
  28. data/lib/rspec/mocks/matchers/receive_message_chain.rb +82 -0
  29. data/lib/rspec/mocks/matchers/receive_messages.rb +77 -0
  30. data/lib/rspec/mocks/message_chain.rb +87 -0
  31. data/lib/rspec/mocks/message_expectation.rb +748 -0
  32. data/lib/rspec/mocks/method_double.rb +287 -0
  33. data/lib/rspec/mocks/method_reference.rb +202 -0
  34. data/lib/rspec/mocks/minitest_integration.rb +68 -0
  35. data/lib/rspec/mocks/mutate_const.rb +339 -0
  36. data/lib/rspec/mocks/object_reference.rb +149 -0
  37. data/lib/rspec/mocks/order_group.rb +81 -0
  38. data/lib/rspec/mocks/proxy.rb +485 -0
  39. data/lib/rspec/mocks/space.rb +238 -0
  40. data/lib/rspec/mocks/standalone.rb +3 -0
  41. data/lib/rspec/mocks/syntax.rb +325 -0
  42. data/lib/rspec/mocks/targets.rb +124 -0
  43. data/lib/rspec/mocks/test_double.rb +171 -0
  44. data/lib/rspec/mocks/verifying_double.rb +129 -0
  45. data/lib/rspec/mocks/verifying_message_expectation.rb +54 -0
  46. data/lib/rspec/mocks/verifying_proxy.rb +220 -0
  47. data/lib/rspec/mocks/version.rb +9 -0
  48. metadata +186 -0
@@ -0,0 +1,25 @@
1
+ The MIT License (MIT)
2
+ =====================
3
+
4
+ * Copyright © 2012 David Chelimsky, Myron Marston
5
+ * Copyright © 2006 David Chelimsky, The RSpec Development Team
6
+ * Copyright © 2005 Steven Baker
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining
9
+ a copy of this software and associated documentation files (the
10
+ "Software"), to deal in the Software without restriction, including
11
+ without limitation the rights to use, copy, modify, merge, publish,
12
+ distribute, sublicense, and/or sell copies of the Software, and to
13
+ permit persons to whom the Software is furnished to do so, subject to
14
+ the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be
17
+ included in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,460 @@
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
+ 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.
5
+
6
+ ## Install
7
+
8
+ gem install rspec # for rspec-core, rspec-expectations, rspec-mocks
9
+ gem install rspec-mocks # for rspec-mocks only
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 => "https://github.com/rspec/#{lib}.git", :branch => 'master'
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)
33
+
34
+ ## Test Doubles
35
+
36
+ A test double is an object that stands in for another object in your system
37
+ during a code example. Use the `double` method, passing in an optional identifier, to create one:
38
+
39
+ ```ruby
40
+ book = double("book")
41
+ ```
42
+
43
+ Most of the time you will want some confidence that your doubles resemble an
44
+ existing object in your system. Verifying doubles are provided for this
45
+ purpose. If the existing object is available, they will prevent you from adding
46
+ stubs and expectations for methods that do not exist or that have an invalid
47
+ number of parameters.
48
+
49
+ ```ruby
50
+ book = instance_double("Book", :pages => 250)
51
+ ```
52
+
53
+ Verifying doubles have some clever tricks to enable you to both test in
54
+ isolation without your dependencies loaded while still being able to validate
55
+ them against real objects. More detail is available in [their
56
+ documentation](https://github.com/rspec/rspec-mocks/blob/master/features/verifying_doubles).
57
+
58
+ Verifying doubles can also accept custom identifiers, just like double(), e.g.:
59
+
60
+ ```ruby
61
+ books = []
62
+ books << instance_double("Book", :rspec_book, :pages => 250)
63
+ books << instance_double("Book", "(Untitled)", :pages => 5000)
64
+
65
+ puts books.inspect # with names, it's clearer which were actually added
66
+ ```
67
+
68
+ ## Method Stubs
69
+
70
+ A method stub is an implementation that returns a pre-determined value. Method
71
+ stubs can be declared on test doubles or real objects using the same syntax.
72
+ rspec-mocks supports 3 forms for declaring method stubs:
73
+
74
+ ```ruby
75
+ allow(book).to receive(:title) { "The RSpec Book" }
76
+ allow(book).to receive(:title).and_return("The RSpec Book")
77
+ allow(book).to receive_messages(
78
+ :title => "The RSpec Book",
79
+ :subtitle => "Behaviour-Driven Development with RSpec, Cucumber, and Friends")
80
+ ```
81
+
82
+ You can also use this shortcut, which creates a test double and declares a
83
+ method stub in one statement:
84
+
85
+ ```ruby
86
+ book = double("book", :title => "The RSpec Book")
87
+ ```
88
+
89
+ The first argument is a name, which is used for documentation and appears in
90
+ failure messages. If you don't care about the name, you can leave it out,
91
+ making the combined instantiation/stub declaration very terse:
92
+
93
+ ```ruby
94
+ double(:foo => 'bar')
95
+ ```
96
+
97
+ This is particularly nice when providing a list of test doubles to a method
98
+ that iterates through them:
99
+
100
+ ```ruby
101
+ order.calculate_total_price(double(:price => 1.99), double(:price => 2.99))
102
+ ```
103
+
104
+ ### Stubbing a chain of methods
105
+
106
+ You can use `receive_message_chain` in place of `receive` to stub a chain of messages:
107
+
108
+ ```ruby
109
+ allow(double).to receive_message_chain("foo.bar") { :baz }
110
+ allow(double).to receive_message_chain(:foo, :bar => :baz)
111
+ allow(double).to receive_message_chain(:foo, :bar) { :baz }
112
+
113
+ # Given any of the above forms:
114
+ double.foo.bar # => :baz
115
+ ```
116
+
117
+ Chains can be arbitrarily long, which makes it quite painless to violate the Law of Demeter in violent ways, so you should consider any use of `receive_message_chain` a code smell. Even though not all code smells indicate real problems (think fluent interfaces), `receive_message_chain` still results in brittle examples. For example, if you write `allow(foo).to receive_message_chain(:bar, :baz => 37)` in a spec and then the implementation calls `foo.baz.bar`, the stub will not work.
118
+
119
+ ## Consecutive return values
120
+
121
+ When a stub might be invoked more than once, you can provide additional
122
+ arguments to `and_return`. The invocations cycle through the list. The last
123
+ value is returned for any subsequent invocations:
124
+
125
+ ```ruby
126
+ allow(die).to receive(:roll).and_return(1, 2, 3)
127
+ die.roll # => 1
128
+ die.roll # => 2
129
+ die.roll # => 3
130
+ die.roll # => 3
131
+ die.roll # => 3
132
+ ```
133
+
134
+ To return an array in a single invocation, declare an array:
135
+
136
+ ```ruby
137
+ allow(team).to receive(:players).and_return([double(:name => "David")])
138
+ ```
139
+
140
+ ## Message Expectations
141
+
142
+ A message expectation is an expectation that the test double will receive a
143
+ message some time before the example ends. If the message is received, the
144
+ expectation is satisfied. If not, the example fails.
145
+
146
+ ```ruby
147
+ validator = double("validator")
148
+ expect(validator).to receive(:validate) { "02134" }
149
+ zipcode = Zipcode.new("02134", validator)
150
+ zipcode.valid?
151
+ ```
152
+
153
+ ## Test Spies
154
+
155
+ Verifies the given object received the expected message during the course of
156
+ the test. For a message to be verified, the given object must be setup to spy
157
+ on it, either by having it explicitly stubbed or by being a null object double
158
+ (e.g. `double(...).as_null_object`). Convenience methods are provided to easily
159
+ create null object doubles for this purpose:
160
+
161
+ ```ruby
162
+ spy("invitation") # => same as `double("invitation").as_null_object`
163
+ instance_spy("Invitation") # => same as `instance_double("Invitation").as_null_object`
164
+ class_spy("Invitation") # => same as `class_double("Invitation").as_null_object`
165
+ object_spy("Invitation") # => same as `object_double("Invitation").as_null_object`
166
+ ```
167
+
168
+ Verifying messages received in this way implements the Test Spy pattern.
169
+
170
+ ```ruby
171
+ invitation = spy('invitation')
172
+
173
+ user.accept_invitation(invitation)
174
+
175
+ expect(invitation).to have_received(:accept)
176
+
177
+ # You can also use other common message expectations. For example:
178
+ expect(invitation).to have_received(:accept).with(mailer)
179
+ expect(invitation).to have_received(:accept).twice
180
+ expect(invitation).to_not have_received(:accept).with(mailer)
181
+
182
+ # One can specify a return value on the spy the same way one would a double.
183
+ invitation = spy('invitation', :accept => true)
184
+ expect(invitation).to have_received(:accept).with(mailer)
185
+ expect(invitation.accept).to eq(true)
186
+ ```
187
+
188
+ Note that `have_received(...).with(...)` is unable to work properly when
189
+ passed arguments are mutated after the spy records the received message.
190
+ For example, this does not work properly:
191
+
192
+ ```ruby
193
+ greeter = spy("greeter")
194
+
195
+ message = "Hello"
196
+ greeter.greet_with(message)
197
+ message << ", World"
198
+
199
+ expect(greeter).to have_received(:greet_with).with("Hello")
200
+ ```
201
+
202
+ ## Nomenclature
203
+
204
+ ### Mock Objects and Test Stubs
205
+
206
+ The names Mock Object and Test Stub suggest specialized Test Doubles. i.e.
207
+ a Test Stub is a Test Double that only supports method stubs, and a Mock
208
+ Object is a Test Double that supports message expectations and method
209
+ stubs.
210
+
211
+ There is a lot of overlapping nomenclature here, and there are many
212
+ variations of these patterns (fakes, spies, etc). Keep in mind that most of
213
+ the time we're talking about method-level concepts that are variations of
214
+ method stubs and message expectations, and we're applying to them to _one_
215
+ generic kind of object: a Test Double.
216
+
217
+ ### Test-Specific Extension
218
+
219
+ a.k.a. Partial Double, a Test-Specific Extension is an extension of a
220
+ real object in a system that is instrumented with test-double like
221
+ behaviour in the context of a test. This technique is very common in Ruby
222
+ because we often see class objects acting as global namespaces for methods.
223
+ For example, in Rails:
224
+
225
+ ```ruby
226
+ person = double("person")
227
+ allow(Person).to receive(:find) { person }
228
+ ```
229
+
230
+ In this case we're instrumenting Person to return the person object we've
231
+ defined whenever it receives the `find` message. We can also set a message
232
+ expectation so that the example fails if `find` is not called:
233
+
234
+ ```ruby
235
+ person = double("person")
236
+ expect(Person).to receive(:find) { person }
237
+ ```
238
+
239
+ RSpec replaces the method we're stubbing or mocking with its own
240
+ test-double-like method. At the end of the example, RSpec verifies any message
241
+ expectations, and then restores the original methods.
242
+
243
+ ## Expecting Arguments
244
+
245
+ ```ruby
246
+ expect(double).to receive(:msg).with(*args)
247
+ expect(double).to_not receive(:msg).with(*args)
248
+ ```
249
+
250
+ You can set multiple expectations for the same message if you need to:
251
+
252
+ ```ruby
253
+ expect(double).to receive(:msg).with("A", 1, 3)
254
+ expect(double).to receive(:msg).with("B", 2, 4)
255
+ ```
256
+
257
+ ## Argument Matchers
258
+
259
+ Arguments that are passed to `with` are compared with actual arguments
260
+ received using ===. In cases in which you want to specify things about the
261
+ arguments rather than the arguments themselves, you can use any of the
262
+ matchers that ship with rspec-expectations. They don't all make syntactic
263
+ sense (they were primarily designed for use with RSpec::Expectations), but
264
+ you are free to create your own custom RSpec::Matchers.
265
+
266
+ rspec-mocks also adds some keyword Symbols that you can use to
267
+ specify certain kinds of arguments:
268
+
269
+ ```ruby
270
+ expect(double).to receive(:msg).with(no_args)
271
+ expect(double).to receive(:msg).with(any_args)
272
+ expect(double).to receive(:msg).with(1, any_args) # any args acts like an arg splat and can go anywhere
273
+ expect(double).to receive(:msg).with(1, kind_of(Numeric), "b") #2nd argument can be any kind of Numeric
274
+ expect(double).to receive(:msg).with(1, boolean(), "b") #2nd argument can be true or false
275
+ expect(double).to receive(:msg).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp
276
+ expect(double).to receive(:msg).with(1, anything(), "b") #2nd argument can be anything at all
277
+ expect(double).to receive(:msg).with(1, duck_type(:abs, :div), "b") #2nd argument can be object that responds to #abs and #div
278
+ expect(double).to receive(:msg).with(hash_including(:a => 5)) # first arg is a hash with a: 5 as one of the key-values
279
+ expect(double).to receive(:msg).with(array_including(5)) # first arg is an array with 5 as one of the key-values
280
+ expect(double).to receive(:msg).with(hash_excluding(:a => 5)) # first arg is a hash without a: 5 as one of the key-values
281
+ ```
282
+
283
+ ## Receive Counts
284
+
285
+ ```ruby
286
+ expect(double).to receive(:msg).once
287
+ expect(double).to receive(:msg).twice
288
+ expect(double).to receive(:msg).exactly(n).times
289
+ expect(double).to receive(:msg).at_least(:once)
290
+ expect(double).to receive(:msg).at_least(:twice)
291
+ expect(double).to receive(:msg).at_least(n).times
292
+ expect(double).to receive(:msg).at_most(:once)
293
+ expect(double).to receive(:msg).at_most(:twice)
294
+ expect(double).to receive(:msg).at_most(n).times
295
+ ```
296
+
297
+ ## Ordering
298
+
299
+ ```ruby
300
+ expect(double).to receive(:msg).ordered
301
+ expect(double).to receive(:other_msg).ordered
302
+ # This will fail if the messages are received out of order
303
+ ```
304
+
305
+ This can include the same message with different arguments:
306
+
307
+ ```ruby
308
+ expect(double).to receive(:msg).with("A", 1, 3).ordered
309
+ expect(double).to receive(:msg).with("B", 2, 4).ordered
310
+ ```
311
+
312
+ ## Setting Responses
313
+
314
+ Whether you are setting a message expectation or a method stub, you can
315
+ tell the object precisely how to respond. The most generic way is to pass
316
+ a block to `receive`:
317
+
318
+ ```ruby
319
+ expect(double).to receive(:msg) { value }
320
+ ```
321
+
322
+ When the double receives the `msg` message, it evaluates the block and returns
323
+ the result.
324
+
325
+ ```ruby
326
+ expect(double).to receive(:msg).and_return(value)
327
+ expect(double).to receive(:msg).exactly(3).times.and_return(value1, value2, value3)
328
+ # returns value1 the first time, value2 the second, etc
329
+ expect(double).to receive(:msg).and_raise(error)
330
+ # error can be an instantiated object or a class
331
+ # if it is a class, it must be instantiable with no args
332
+ expect(double).to receive(:msg).and_throw(:msg)
333
+ expect(double).to receive(:msg).and_yield(values, to, yield)
334
+ expect(double).to receive(:msg).and_yield(values, to, yield).and_yield(some, other, values, this, time)
335
+ # for methods that yield to a block multiple times
336
+ ```
337
+
338
+ Any of these responses can be applied to a stub as well
339
+
340
+ ```ruby
341
+ allow(double).to receive(:msg).and_return(value)
342
+ allow(double).to receive(:msg).and_return(value1, value2, value3)
343
+ allow(double).to receive(:msg).and_raise(error)
344
+ allow(double).to receive(:msg).and_throw(:msg)
345
+ allow(double).to receive(:msg).and_yield(values, to, yield)
346
+ allow(double).to receive(:msg).and_yield(values, to, yield).and_yield(some, other, values, this, time)
347
+ ```
348
+
349
+ ## Arbitrary Handling
350
+
351
+ Once in a while you'll find that the available expectations don't solve the
352
+ particular problem you are trying to solve. Imagine that you expect the message
353
+ to come with an Array argument that has a specific length, but you don't care
354
+ what is in it. You could do this:
355
+
356
+ ```ruby
357
+ expect(double).to receive(:msg) do |arg|
358
+ expect(arg.size).to eq 7
359
+ end
360
+ ```
361
+
362
+ If the method being stubbed itself takes a block, and you need to yield to it
363
+ in some special way, you can use this:
364
+
365
+ ```ruby
366
+ expect(double).to receive(:msg) do |&arg|
367
+ begin
368
+ arg.call
369
+ ensure
370
+ # cleanup
371
+ end
372
+ end
373
+ ```
374
+
375
+ ## Delegating to the Original Implementation
376
+
377
+ When working with a partial mock object, you may occasionally
378
+ want to set a message expectation without interfering with how
379
+ the object responds to the message. You can use `and_call_original`
380
+ to achieve this:
381
+
382
+ ```ruby
383
+ expect(Person).to receive(:find).and_call_original
384
+ Person.find # => executes the original find method and returns the result
385
+ ```
386
+
387
+ ## Combining Expectation Details
388
+
389
+ Combining the message name with specific arguments, receive counts and responses
390
+ you can get quite a bit of detail in your expectations:
391
+
392
+ ```ruby
393
+ expect(double).to receive(:<<).with("illegal value").once.and_raise(ArgumentError)
394
+ ```
395
+
396
+ While this is a good thing when you really need it, you probably don't really
397
+ need it! Take care to specify only the things that matter to the behavior of
398
+ your code.
399
+
400
+ ## Stubbing and Hiding Constants
401
+
402
+ See the [mutating constants
403
+ README](https://github.com/rspec/rspec-mocks/blob/master/features/mutating_constants/README.md)
404
+ for info on this feature.
405
+
406
+ ## Use `before(:example)`, not `before(:context)`
407
+
408
+ Stubs in `before(:context)` are not supported. The reason is that all stubs and mocks get cleared out after each example, so any stub that is set in `before(:context)` would work in the first example that happens to run in that group, but not for any others.
409
+
410
+ Instead of `before(:context)`, use `before(:example)`.
411
+
412
+ ## Settings mocks or stubs on any instance of a class
413
+
414
+ rspec-mocks provides two methods, `allow_any_instance_of` and
415
+ `expect_any_instance_of`, that will allow you to stub or mock any instance
416
+ of a class. They are used in place of `allow` or `expect`:
417
+
418
+ ```ruby
419
+ allow_any_instance_of(Widget).to receive(:name).and_return("Wibble")
420
+ expect_any_instance_of(Widget).to receive(:name).and_return("Wobble")
421
+ ```
422
+
423
+ These methods add the appropriate stub or expectation to all instances of
424
+ `Widget`.
425
+
426
+ This feature is sometimes useful when working with legacy code, though in
427
+ general we discourage its use for a number of reasons:
428
+
429
+ * The `rspec-mocks` API is designed for individual object instances, but this
430
+ feature operates on entire classes of objects. As a result there are some
431
+ semantically confusing edge cases. For example in
432
+ `expect_any_instance_of(Widget).to receive(:name).twice` it isn't clear
433
+ whether each specific instance is expected to receive `name` twice, or if two
434
+ receives total are expected. (It's the former.)
435
+ * Using this feature is often a design smell. It may be
436
+ that your test is trying to do too much or that the object under test is too
437
+ complex.
438
+ * It is the most complicated feature of `rspec-mocks`, and has historically
439
+ received the most bug reports. (None of the core team actively use it,
440
+ which doesn't help.)
441
+
442
+
443
+ ## Further Reading
444
+
445
+ There are many different viewpoints about the meaning of mocks and stubs. If
446
+ you are interested in learning more, here is some recommended reading:
447
+
448
+ * Mock Objects: http://www.mockobjects.com/
449
+ * Endo-Testing: http://www.ccs.neu.edu/research/demeter/related-work/extreme-programming/MockObjectsFinal.PDF
450
+ * Mock Roles, Not Objects: http://www.jmock.org/oopsla2004.pdf
451
+ * Test Double: http://www.martinfowler.com/bliki/TestDouble.html
452
+ * Test Double Patterns: http://xunitpatterns.com/Test%20Double%20Patterns.html
453
+ * Mocks aren't stubs: http://www.martinfowler.com/articles/mocksArentStubs.html
454
+
455
+ ## Also see
456
+
457
+ * [https://github.com/rspec/rspec](https://github.com/rspec/rspec)
458
+ * [https://github.com/rspec/rspec-core](https://github.com/rspec/rspec-core)
459
+ * [https://github.com/rspec/rspec-expectations](https://github.com/rspec/rspec-expectations)
460
+ * [https://github.com/rspec/rspec-rails](https://github.com/rspec/rspec-rails)