Coming Soon

Hi all - I normally don’t like to blast the Ruby list w/ RSpec
news besides release announcements, but this will likely
be interesting to any of you who are interested in RSpec.

If you’re not, then please save yourself some time and hit
delete now. Otherwise, read on, and thanks!

David

=======================================
Dear spec’ers,

As many of you already know, we’re gearing up for a pretty big 0.8
release of RSpec in the next couple of weeks. I’m writing in advance
because I want to give you a heads up about upcoming changes and how
they may impact your existing specs.

Two important things to note first:

  1. We will provide a translator that you’ll be able to use to convert
    the majority of your existing specs to the new syntax before we remove
    deprecated methods.
  2. The syntax changes described below will be the last major changes
    you’ll see before a 1.0 release.

Here is the plan, though the time line is not yet clear.

== rspec-0.8.0-RC1

  • Will be released within the next couple of weeks.
  • Will be fully backwards compatible with 0.7.5.1.
  • Will also support all of the new syntax using expectation matchers
    (see below).

Because this is such a significant change, we want to do a Release
Candidate first.

== rspec-0.8.x

Between 0.8.0 and 0.9.0, there will be at least one release that will
include:

  • A pre-0.8 to 0.9 translator.
  • Noisy deprecation warnings that will let you know what methods will
    be going and what you should use instead.
  • A simple means of silencing those warnings (at your own peril!)

== rspec-0.9

  • Will remove all of the old syntax.

=======================================
Here are some answers to some questions that some of you may have:

== What is changing?

All of the should_xyz methods will be losing an underscore and gaining a
space:

#before
actual.should_equal(expected)
actual.should_not_equal(expected)

#after
actual.should equal(expected)
actual.should_not equal(expected)

#equal, in this example, is a method that returns an expectation
matcher,
which Ruby passes to #should, which then interacts with the matcher
to evaluate whether or not the expectation is met and report
accordingly.

All args to expectation matchers will require parens, and blocks must
be expressed
using curly braces. This has to do with ambiguity of arguments and
operator precedence. Don’t worry, if you do the wrong thing you’ll get
a warning. More on this below.

== Why this change?

The current syntax is supported by some very clever use of
method_missing. I’m allowed to say it was clever because I didn’t
write it ;). At first it seemed awesome, but we’ve found that it
conflicts with other frameworks that use metaprogramming techniques to
late-bind to method_missing. So we had to make a choice between
rethinking RSpec’s implementation or commit to a future of monkey
patching other frameworks as they introduce new uses of
method_missing.

Using expectation matchers means that we only need to add 4 methods to
Object:
#for expectation matchers
should
should_not

#for mocks/stubs
should_receive
should_not_receive

So it is much less invasive than it was before and, because we are not
using method_missing on YOUR objects, is much less conflict/error
prone.

It also supports a clear entry point to writing custom expectation
matchers, so if you have some domain-specific expectations like
“should travel_more” or “should get_a_raise”, you’ll have a very easy
means of doing so.

== Will there be any existing expectations that will no longer be
supported at all?

Yes, but only a few, and only related to RSpec on Rails. We will NOT
be supporting the following in the new syntax:

controller.should_render
controller.should_redirect_to

You will be able to use instead:

response.should render_template
response.should render_text
response.should redirect_to

… but only after the action.

== For )(&)('s sake, WHEN will you stop making changes like this?

Right now.

While we will not commit to 100% backwards compatibility, we on the
RSpec Development Team are as anxious for this to stabilize as you
are. We just feel that when we get to a 1.0 release we absolutely must
have an API that is solid, easy to use, stable and maintainable. We
just didn’t see an end in sight to the problems we’d been seeing w/
the soon-to-be-ex-syntax, and we are very confident in this move and
its potential to fulfill those requirements.

== What’s up w/ the parens and {} blocks?

Parens: When you do this:

a.b c d

… Ruby gives you the all familiar:

“warning: parenthesize argument(s) for future version”

If you can live w/ that, then have at it w/o the parens.

Curly braces: This has to do w/ precedence. do/end has a lower
precedence than {}, which means that in this expression:

target.should satisfy do
end

… the block will be passed to #should instead of #satisfy. We need
the blocks to be passed to the matcher (#satisfy in this example), so
curly braces are required. This will be enforced by RSpec. When
#should or #should_not receive a block, the spec will fail with a
warning telling you to use {} instead of do/end. So you won’t have the
opportunity to simply forget.

=======================================
We’re very excited about this release. I hope this email answers
most of your questions. If you have others, please
feel free, though I may punt on technical questions as many of those
will be answered by documentation in the 0.8.0-RC1 release.

Thanks for your patience with this and thanks especially to all of those
who contribute to RSpec’s evolution by participating with this list and
submitting RFEs to the tracker.

Cheers,
David C.
on behalf of The RSpec Development Team

On Feb 2, 2007, at 5:05 AM, David C. wrote:

== Why this change?

A very interesting and informative email and I don’t even use RSpec. :wink:

Good luck with your new release.

James Edward G. II

David C. schrieb:

Dear spec’ers,
deprecated methods.
(see below).
be going and what you should use instead.

I would prefere instead (as logical expressions): equal / not_equal
so:
actual should not_equal(expected)

Klaus

Klaus R. wrote:

David C. schrieb:

Dear spec’ers,
deprecated methods.
(see below).
be going and what you should use instead.

I would prefere instead (as logical expressions): equal / not_equal
so:
actual should not_equal(expected)

By grouping the not with the should, you are able to negate arbitrary
expectations. If the not goes with the expectation, then each
expectation must provide its own negative (e.g. equal/not_equal,
match/not_match).

– Jim W.

Well, you can solve that problem by overriding method_missing on Object
so
that expectations that match the regex /^not_(.+)/ can be automagically
negated…

I’m kidding of course. I applaud this decision by the RSpec team. A
couple
of Rails projects that I work on use RSpec and at one point, also used
Mocha. Some subtle bugs were cropping up due to clashes between the
libraries’ use of method missing.

Mushfeq.