Skip to content

Commit bc2bb27

Browse files
committed
More progress.
1 parent d8c613f commit bc2bb27

File tree

1 file changed

+72
-8
lines changed

1 file changed

+72
-8
lines changed

source/blog/2015-05-28-rspec-3-3-has-been-released.md

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: RSpec 3.3 has been released!
33
author: Myron Marston
44
---
55

6-
RSpec 3.2 has just been released! Given our commitment to
6+
RSpec 3.3 has just been released! Given our commitment to
77
[semantic versioning](http://semver.org/), this should be a trivial
88
upgrade for anyone already using RSpec 3.0, 3.1 or 3.2, but if we did introduce
99
any regressions, please let us know, and we'll get a patch release
@@ -46,7 +46,7 @@ top-level group defined in `spec/unit/baseball_spec.rb`.
4646

4747
For the most part, the new example IDs are primarily used internally by
4848
RSpec to support some of the new 3.3 features, but you're free to use
49-
them from the command line, and the re-run command printed by RSpec for
49+
them from the command line. The re-run command printed by RSpec for
5050
each failure will use them if the file location does not uniquely
5151
identify the failed example. Copying and pasting the re-run command
5252
for a particular failed example will always run just that example now!
@@ -101,7 +101,7 @@ without paying the cost of repeatedly running the entire suite. RSpec
101101
3.3 includes a new option that vastly simplifies this work flow:
102102

103103
~~~
104-
rspec --next-failure
104+
$ rspec --next-failure
105105
# or apply it to a specific file or directory:
106106
$ rspec spec/unit --next-failure
107107
~~~
@@ -175,7 +175,7 @@ and want to avoid that overhead, you can configure RSpec to
175175
### Expectations: New `aggregrate_failures` API
176176

177177
When you've got multiple independent expectations to make about a
178-
particular result, you've generally got two routes you can take. One way is
178+
particular result, there's generally two routes you can take. One way is
179179
to define a separate example for each expectation:
180180

181181
~~~ ruby
@@ -235,7 +235,7 @@ RSpec.describe Client do
235235
end
236236
~~~
237237

238-
Within the `aggregate_failures` block, expectations do not cause the
238+
Within the `aggregate_failures` block, expectations failures do not cause the
239239
example to abort. Instead, a single _aggregate_ exception will be
240240
raised at the end containing multiple sub-failures which RSpec will
241241
format nicely for you:
@@ -316,8 +316,8 @@ Failure/Error: expect([foo]).to include(bar)
316316
~~~
317317

318318
In addition, RSpec's improved formatting for `Time` and other objects will
319-
now be used wherever those objects are inspected for every matcher. So, for
320-
example, where you used to get this:
319+
now be used wherever those objects are inspected, regardless of which
320+
built-in matcher you used. So, for example, where you used to get this:
321321

322322
~~~
323323
Failure/Error: expect([Time.now]).to include(Time.now)
@@ -342,9 +342,73 @@ these improvements!
342342

343343
### Mocks: Improved Failure Output
344344

345+
RSpec::Mocks has also received some nice improvements to its failure output. RSpec's
346+
improved formatting for `Time` and other objects is now applied to mock expectation
347+
failures as well:
348+
349+
~~~
350+
Failure/Error: dbl.foo(Time.now)
351+
#<Double (anonymous)> received :foo with unexpected arguments
352+
expected: (2015-06-09 08:33:36.865827000 -0700)
353+
got: (2015-06-09 08:33:36.874197000 -0700)
354+
Diff:
355+
@@ -1,2 +1,2 @@
356+
-[2015-06-09 08:33:36.865827000 -0700]
357+
+[2015-06-09 08:33:36.874197000 -0700]
358+
~~~
359+
360+
In addition, the failure output for `have_received` has been much improved so that when
361+
the expected args do not match, it lists each set of actual args, and the number of
362+
times the message was received with those args:
363+
364+
~~~
365+
Failure/Error: expect(dbl).to have_received(:foo).with(3)
366+
#<Double (anonymous)> received :foo with unexpected arguments
367+
expected: (3)
368+
got: (1) (2 times)
369+
(2) (1 time)
370+
~~~
371+
372+
Thanks to John Ceh for implementing the latter improvement!
373+
345374
### Mocks: Stubbing `MyClass.new` Verifies Against `MyClass#initialize`
346375

347-
### Rails: ?
376+
RSpec's [verifying doubles
377+
(TODO)](https://relishapp.com/rspec/rspec-mocks/v/3-2/docs/verifying-doubles)
378+
use the metadata that Ruby's reflection capabilities provide to verify,
379+
among other things, that passed arguments are valid according to the
380+
original method's signature. However, when a method is defined using
381+
just an arg splat:
382+
383+
~~~ ruby
384+
def method_1(*args)
385+
method_2(*args)
386+
end
387+
388+
def method_2(a, b)
389+
end
390+
~~~
391+
392+
...then the verifying double is going to allow _any_ arguments, even
393+
if the method simply delegates to _another_ method that does have a
394+
strong signature. Unfortunately, `Class#new` is one of these methods.
395+
It's defined by Ruby to delegate to `#initialize`, and will only accept
396+
arguments that the signature of `initialize` can handle, but the metadata
397+
provided by `MyClass.method(:new).parameters` indicate it can handle any
398+
arguments, even if it can't.
399+
400+
In RSpec 3.3, we've improved verifying doubles so that when you stub
401+
`new` on a class, it uses the method signature of `#initialize` to
402+
verify arguments, unless you've redefined `new` to do something
403+
different. This allows verifying doubles to give you an error when
404+
you pass arguments to a stubbed `MyClass#new` method that the real
405+
class would not allow.
406+
407+
### Rails: Add support for PATCH to route specs created via scaffold.
408+
409+
### Rails: Add support for ActiveJob specs as standard
410+
RSpec::Rails::RailsExampleGoups via both :type => :job and inferring
411+
type from spec directory spec/jobs.
348412

349413
## Stats
350414

0 commit comments

Comments
 (0)