rspec-2.9.0 is released!

March 17th, 2012

rspec-2.9.0 is released wtih lots of bug fixes and a few minor feature improvements as well. Enjoy!

rspec-core-2.9.0 / 2012-03-17

full changelog

Enhancements

  • Support for “X minutes X seconds” spec run duration in formatter. (uzzz)
  • Strip whitespace from group and example names in doc formatter.
  • Removed spork-0.9 shim. If you’re using spork-0.8.x, you’ll need to upgrade to 0.9.0.

Bug fixes

  • Restore --full_backtrace option
  • Ensure that values passed to config.filter_run are respected when running over DRb (using spork).
  • Ensure shared example groups are reset after a run (as example groups are).
  • Remove rescue false from calls to filters represented as Procs
  • Ensure described_class gets the closest constant (pyromaniac)
  • In “autorun”, don’t run the specs in the at_exit hook if there was an exception (most likely due to a SyntaxError). (sunaku)
  • Don’t extend groups with modules already used to extend ancestor groups.
  • its correctly memoizes nil or false values (Yamada Masaki)

rspec-expectations-2.9.0 / 2012-03-17

full changelog

Enhancements

  • Move built-in matcher classes to RSpec::Matchers::BuiltIn to reduce pollution of RSpec::Matchers (which is included in every example).
  • Autoload files with matcher classes to improve load time.

Bug fixes

  • Align respond_to? and method_missing in DSL-defined matchers.
  • Clear out user-defined instance variables between invocations of DSL-defined matchers.
  • Dup the instance of a DSL generated matcher so its state is not changed by subsequent invocations.
  • Treat expected args consistently across positive and negative expectations (thanks to Ralf Kistner for the heads up)

rspec-mocks-2.9.0 / 2012-03-17

full changelog

Enhancements

  • Support order constraints across objects (preethiramdev)

Bug fixes

  • Allow a as_null_object to be passed to with
  • Pass proc to block passed to stub (Aubrey Rhodes)
  • Initialize child message expectation args to match any args (#109 - preethiramdev)

rspec-rails-2.9.0 / 2012-03-17

full changelog

Enhancments

  • add description method to RouteToMatcher (John Wulff)
  • Run “db:test:clone_structure” instead of “db:test:prepare” if Active Record’s schema format is “:sql”. (Andrey Voronkov)

Bug fixes

  • mock_model(XXX).as_null_object.unknown_method returns self again
  • Generated view specs use different IDs for each attribute.

rspec-rails-2.8.1 is released

January 5th, 2012

Bug fix release

The rails-3.2.0.rc2 release broke stub_model in rspec-rails-2.0.0 > 2.8.0. The rspec-rails-2.8.1 release fixes this issue, but it means that when you upgrade to rails-3.2.0.rc2 or greater, you’ll have to upgrade to rspec-rails-2.8.1 or greater.

Because rspec-rails-2.8.1 supports all versions of rails since 3.0, I recommend that you upgrade to rspec-rails-2.8.1 first, and then upgrade to rails-3.2.0.rc2 (or 3.2.0 once it’s out).

Changelog

http://rubydoc.info/gems/rspec-rails/file/Changelog.md

Docs

http://rubydoc.info/gems/rspec-rails
http://relishapp.com/rspec/rspec-rails

rspec-2.7.0 is released!

October 16th, 2011

We’re pleased to announce the release of rspec-2.7.0. Release notes for each gem are listed below, but here are a couple of highlights:

Just type rspec

With the the 2.7.0 release, if you keep all of your specs in the conventional spec directory, you don’t need to follow the rspec command with a path. Just type rspec.

If you keep your specs in a different directory, just set the --default_path option to that directory on the command line, or in a .rspec config file.

The rake task now lets Bundler manage Bundler

The RSpec::Core::RakeTask invokes the rspec command in a subshell. In recent releases, it assumed that you wanted it prefixed with bundle exec if it saw a Gemfile. We then added gemfile and skip_bundler options to the task, so you could manage this in different ways.

It turns out that Bundler manages this quite well without any help from RSpec. If you activate Bundler in the parent shell, via the command line or Bundler.setup, it sets environment variables that activate Bundler in the subshell with the correct gemfile.

The gemfile and skip_bundler options are therefore deprecated and have no effect.

Release Notes

rspec-core-2.7.0

full changelog

NOTE: RSpec’s release policy dictates that there should not be any backward incompatible changes in minor releases, but we’re making an exception to release a change to how RSpec interacts with other command line tools.

As of 2.7.0, you must explicity require "rspec/autorun" unless you use the rspec command (which already does this for you).

  • Enhancements

    • Add example.exception (David Chelimsky)
    • --default_path command line option (Justin Ko)
    • support multiple --line_number options (David J. Hamilton)
      • also supports path/to/file.rb:5:9 (runs examples on lines 5 and 9)
    • Allow classes/modules to be used as shared example group identifiers (Arthur Gunn)
    • Friendly error message when shared context cannot be found (Sławosz Sławiński)
    • Clear formatters when resetting config (John Bintz)
    • Add xspecify and xexample as temp-pending methods (David Chelimsky)
    • Add --no-drb option (Iain Hecker)
    • Provide more accurate run time by registering start time before code is loaded (David Chelimsky)
    • Rake task default pattern finds specs in symlinked dirs (Kelly Felkins)
    • Rake task no longer does anything to invoke bundler since Bundler already handles it for us. Thanks to Andre Arko for the tip.
    • Add --failure-exit-code option (Chris Griego)
  • Bug fixes

    • Include Rake::DSL to remove deprecation warnings in Rake > 0.8.7 (Pivotal Casebook)
    • Only eval let block once even if it returns nil (Adam Meehan)
    • Fix --pattern option (wasn’t being recognized) (David Chelimsky)
    • Only implicitly require "rspec/autorun" with the rspec command (David Chelimsky)
    • Ensure that rspec’s at_exit defines the exit code (Daniel Doubrovkine)
    • Show the correct snippet in the HTML and TextMate formatters (Brian Faherty)

rspec-expectations-2.7.0

full changelog

  • Enhancements

    • HaveMatcher converts argument using to_i (Alex Bepple & Pat Maddox)
    • Improved failure message for the have_xxx matcher (Myron Marston)
    • HaveMatcher supports count (Matthew Bellantoni)
    • Change matcher dups Enumerable before the action, supporting custom Enumerable types like CollectionProxy in Rails (David Chelimsky)
  • Bug fixes

    • Fix typo in have(n).xyz documentation (Jean Boussier)
    • fix safe_sort for ruby 1.9.2 (Kernel now defines <=> for Object) (Peter van Hardenberg)

rspec-mocks-2.7.0

full changelog

  • Enhancements

    • Use __send__ rather than send (alextk)
    • Add support for any_instance.stub_chain (Sidu Ponnappa)
    • Add support for any_instance argument matching based on with (Sidu Ponnappa and Andy Lindeman)
  • Changes

    • Check for failure_message_for_should or failure_message instead of description to detect a matcher (Tibor Claassen)
  • Bug fixes

    • pass a hash to any_instance.stub. (Justin Ko)
    • allow to_ary to be called without raising NoMethodError (Mikhail Dieterle)
    • any_instance properly restores private methods (Sidu Ponnappa)

rspec-rails-2.7.0

full changelog

  • Enhancments

    • ActiveRecord::Relation can use the =~ matcher (Andy Lindeman)
    • Make generated controller spec more consistent with regard to ids (Brent J. Nordquist)
    • Less restrictive autotest mapping between spec and implementation files (José Valim)
    • require 'rspec/autorun' from generated spec_helper.rb (David Chelimsky)
    • add bypass_rescue (Lenny Marks)
    • route_to accepts query string (Marc Weil)
  • Internal

    • Added specs for generators using ammeter (Alex Rothenberg)
  • Bug fixes

    • Fix configuration/integration bug with rails 3.0 (fixed in 3.1) in which fixure_file_upload reads from ActiveSupport::TestCase.fixture_path and misses RSpec’s configuration (David Chelimsky)
    • Support nested resource in view spec generator (David Chelimsky)
    • Define primary_key on class generated by mock_model("WithAString") (David Chelimsky)

In a github issue reported to the rspec-mocks project, the user had run into a problem in a Rails’ controller spec in which an RSpec-generated test double didn’t behave as expected. What follows is an edited version of the issue and my response, with the hope that it reaches a wider audience and/or sparks some conversation.

The reported problem: ActiveSupport::JSON::Encoding::CircularReferenceError using doubles

This spec …

require 'spec_helper'
 
describe ListsController do
  let(:list) { double("List") }
 
  describe "GET 'index'" do
    let(:expected) { [{id: "1", name: "test"}] }
 
    before do
      list.stub(:id){ "1" }
      list.stub(:name){ "test" }
      List.stub(:select){ [ list ] }
    end
 
    it "should return the list of lists" do
      get :index, format: :json
      response.body.should == expected.to_json
    end
  end
end

… plus this implementation …

class ListsController < ApplicationController
  respond_to :json
 
  expose(:lists) { List.select("id, name") }
 
  def index
    respond_with(lists)
  end
end

… produces this failure:

  Failure/Error: get :index, format: :json
     ActiveSupport::JSON::Encoding::CircularReferenceError:
       object references itself

The deeper problem: this is a great example of when not to use stubs.

Here’s why: there are three incorrect assumptions hiding behind the stubs!

  1. select takes an Array: List.select(["id","name"]), but the example stubs it incorrectly.
  2. the id is numeric, but the example uses String.
  3. the json is wrapped: {"list":{"id":1,"name":"test"}}, but the example doesn’t wrap it.

Even if the stubs were properly aligned with reality, the reason for the error is that respond_with(lists) eventually calls as_json on the list object, which, in this example, is an RSpec double that doesn’t implement as_json. We need to either use a stub_model (which does implement as_json), or explicitly stub it in the example:

list.stub(:as_json) { { list: {id: 1, name: "test"} } }

But I’d avoid stubs altogether in this case. Stubs are great for well defined (and understood) public APIs which are invoked by the code being specified. In this case, we’re stubbing an API (as_json) that is invoked by the Rails framework, not the code being specified. If the Rails framework ever changes how it renders json, this example would continue to pass, but it would be a false positive.

One possible remedy

Here’s how I’d approach this outside-in (based on my own flow, design preferences, and target outcomes. YMMV.)

Start with a request spec:

require 'spec_helper'
 
describe "Lists" do
  describe "GET 'index.json'" do
    it "returns the list of lists" do
      list = List.create!(name: "test")
      get "/lists.json"
      response.body.should == [{list: {id: list.id, name: "test"}}].to_json
    end
  end
end

This shows exactly what to expect, so when working on clients we can refer directly to this without having to dig into internals.

Run this and it fails with uninitialized constant List, so generate the list resource:

rails generate resource list name:string
rake db:migrate
rake db:test:prepare

Run it again and it fails with ActionView::MissingTemplate. Now we have a couple of choices. The purist view says “write a controller spec”, but some people say controller specs are unnecessary if there are already request specs (or cukes) as they just add duplication.

For me, the answer depends upon the complexity of the requirement as it compares to what we get for free from Rails. In this case, the only difference between the requirement and what Rails gives us for free is that we constrain the fields to id and name This is something we can implement in the model, so I’d just implement this very simple controller code and move on:

class ListsController < ApplicationController
  respond_to :json
 
  def index
    respond_with List.all
  end
end

Now the request spec fails with:

expected: "[{\"list\":{\"id\":1,\"name\":\"test\"}}]"
     got: "[{\"list\":{\"created_at\":\"2011-08-27T14:56:19Z\",\"id\":1,\"name\":\"test\",\"updated_at\":\"2011-08-27T14:56:19Z\"}}]"

We’re getting more key/value pairs than we want. I want the model responsible for constraining the keys in the json (Rails implements json transformations in the context of the model, so why shouldn’t we?), so I’d add a model spec:

require 'spec_helper'
 
describe List do
  describe "#as_json" do
    it "constrains keys to id and name" do
      list = List.new(:name => "things")
      list.as_json['list'].keys.should eq(%w[id name])
    end
  end
end

This fails with:

expected ["id", "name"]
     got ["created_at", "name", "updated_at"]

I expect to see created_at and updated_at, but I’m surprised (initially) to see that id is missing. Thinking this through, it makes sense because the example generates the list using new, so no id is generated. To get id to show up in the list of keys, we can use create instead of new, or we can explicitly set it. I’m going to go with setting the id explicitly to avoid the db hit, accepting the self-imposed leaky abstraction. It’s all trade-offs.

it "constrains fields to id and name" do
  list = List.new(:name => "things")
  list.id = 37
  list.as_json['list'].keys.should eq(%w[id name])
end

Now it fails with:

expected ["id", "name"]
     got ["created_at", "id", "name", "updated_at"]

Now we can implement the constraint:

class List < ActiveRecord::Base
  def as_json
    super({ only: %w[id name]})
  end
end

Now the model spec passes, but the request spec fails with:

ArgumentError:
  wrong number of arguments (1 for 0)

This is because the as_json implementation fails to honor the Rails API:

as_json(options = nil)

as_json is called by the Rails framework with an options hash. Had we done this without the request spec and weren’t aware of this information, we’d have a bunch of passing specs but the app would blow up. Hooray for testing at multiple levels!

So we add a new example to the model spec:

it "honors the submitted options hash" do
  list = List.new(:name => "things")
  list.id = 37
  list.as_json(:only => :name)['list'].keys.should eq(%w[name])
end

This fails with wrong number of arguments (1 for 0) as well, so now we adjust the model implementation:

def as_json(opts={})
  super({ only: %w[id name]}.merge(opts))
end

Now the model spec passes again, and so does the request spec! DONE!

The result is a very nice balance of clarity, speed (in spite of the one db hit in the request spec) and flexibility. Any new endpoints we add will get the same json representation because it is expressed in the model (heeding the principle of least surprise). The model spec not only specifies how the model should represent itself as json, but it helps to explain how the rails framework uses the model. All of this with no stubbing at all, and especially no stubbing of APIs our code isn’t invoking.

This is a bug fix release that is compatible with the rails-3.0.0 to 3.0.7, 3.0.8.rc1, and 3.1.0.rc1 (it is mostly, but not fully compatible with but not rails-3.1.0.beta1).

rspec-rails-2.6.1 / 2011-05-25

full changelog

  • Bug fixes
    • fix controller specs with anonymous controllers with around filters
    • exclude spec directory from rcov metrics (Rodrigo Navarro)
    • guard against calling prerequisites on nil default rake task (Jack Dempsey)

This is a beta release intended to provide something that works with rails-3.1.0.rc1. It is not compatible with rails-3.1.0.beta1 or rake-0.9.0 (make sure you specify rake-0.8.7 in your Gemfile), but it is compatible with every other release of rails from 3.0.0 through 3.1.0.rc1.

rspec-rails-2.6.1.beta1 / 2011-05-22

full changelog

This release is compatible with rails-3.1.0.rc1, but not rails-3.1.0.beta1

  • Bug fixes
    • fix controller specs with anonymous controllers with around filters
    • exclude spec directory from rcov metrics
    • guard against calling prerequisites on nil default rake task (Jack Dempsey)

rspec-2.6.0.rc3 is released!

April 30th, 2011

UPDATE: there was a problem related to rubygems that made this release uninstallable, so it’s been yanked and rc4 has been released.

This release addresses issues that were raised in the rspec-core-2.6.0.rc2 release.

rspec-core-2.6.0.rc3

full changelog

Enhancements

  • Clean up messages for filters/tags.

rspec-mocks-2.6.0.rc3

full changelog

Bug fixes

  • Support multiple calls to any_instance in the same example (Sidu Ponnappa)

rspec-rails-2.6.0.rc3

full changelog

Enhancements

  • Update the controller spec generated by the rails scaffold generator:
    • Add documentation to the generated spec
    • Use any_instance to avoid stubbing finders
    • Use real objects instead of mock_model
  • Update capybara integration to work with capy 0.4 and 1.0.0.beta
  • Decorate paths passed to [append|prepend]_view_paths with empty templates unless rendering views. (Mark Turner)

rspec-2.6.0.rc2 is released!

April 18th, 2011

We’re releasing rspec-2.6.0.rc2 as a release candidate as there are some internal changes that we’d like to see put through their paces before doing a final release. Note that the changes I speak of are internal. There are no new deprecations in this release, nor any backward-incompatible changes.

There are, however, some new features that we’re really excited about. Please do check it out and please do report any issues to the appropriate github issue tracker:

rspec-core-2.6.0.rc2

full changelog

  • Enhancements

    • shared_context (Damian Nurzynski)
      • extend groups matching specific metadata with:
        • method definitions
        • subject declarations
        • let/let! declarations
        • etc (anything you can do in a group)
    • its([:key]) works for any subject with #[]. (Peter Jaros)
    • treat_symbols_as_metadata_keys_with_true_values (Myron Marston)
    • Print a deprecation warning when you configure RSpec after defining an example. All configuration should happen before any examples are defined. (Myron Marston)
    • Pass the exit status of a DRb run to the invoking process. This causes specs run via DRb to not just return true or false. (Ilkka Laukkanen)
    • Refactoring of ConfigurationOptions#parse_options (Rodrigo Rosenfeld Rosas)
    • Report excluded filters in runner output (tip from andyl)
  • Bug fixes

    • Don’t stumble over an exception without a message (Hans Hasselberg)
    • Remove non-ascii characters from comments that were choking rcov (Geoffrey Byers)
    • Fixed backtrace so it doesn’t include lines from before the autorun at_exit hook (Myron Marston)
    • Include RSpec::Matchers when first example group is defined, rather than just before running the examples. This works around an obscure bug in ruby 1.9 that can cause infinite recursion. (Myron Marston)
    • Don’t send example_group_[started|finished] to formatters for empty groups.
    • Get specs passing on jruby (Sidu Ponnappa)
    • Fix bug where mixing nested groups and outer-level examples gave unpredictable :line_number behavior (Artur Małecki)
    • Regexp.escape the argument to –example (tip from Elliot Winkler)
    • Correctly pass/fail pending block with message expectations

rspec-expectations-2.6.0.rc2

full changelog

  • Enhancments

    • change matcher accepts Regexps (Robert Davis)
    • better descriptions for have_xxx matchers (Magnus Bergmark)
  • Bug fixes

    • Removed non-ascii characters that were choking rcov (Geoffrey Byers)
    • change matcher dups arrays and hashes so their before/after states can be compared correctly.
    • Fix the order of inclusion of RSpec::Matchers in Test::Unit::TestCase and MiniTest::Unit::TestCase to prevent a SystemStackError (Myron Marston)

rspec-mocks-2.6.0.rc2

full changelog

  • Enhancements

    • Add support for any_instance.stub and any_instance.should_receive (Sidu Ponnappa and Andy Lindeman)
  • Bug fixes

    • fix bug in which multiple chains with shared messages ending in hashes failed to return the correct value

rspec-rails-2.6.0.rc2

full changelog

  • Enhancments

    • rails 3 shortcuts for routing specs (Joe Fiorini)
    • support nested resources in generators (Tim McEwan)
    • require ‘rspec/rails/mocks’ to use mock_model without requiring the whole rails framework
  • Bug fixes

    • fix typo in “rake spec:statsetup” (Curtis Schofield)
    • expose named routes in anonymous controller specs (Andy Lindeman)
    • error when generating namespaced scaffold resources (Andy Lindeman)

rspec-2.5.0 is released!

February 6th, 2011

rspec-2.5 is a minor upgrade, and is fully backward compatible with rspec-2.4. It includes several bug fixes, enhancements, and one deprecation. See the changelog below for details.

We had a little glitch publishing the docs to http://relishapp.com/rspec, so the 2.5 docs won’t be up for another day or two, so I’ll detail the noticable differences here.

Autotest/Bundler integration

UPDATE: the –skip-bundler option does not work, and is removed from rspec-core-2.5.1. See the post on the 2.5.1 release for more information.

–skip-bundler

RSpec’s Autotest integration assumes that you want bundle exec in the shell command generated by Autotest if you have a Gemfile. This works fine for some situations, but not all, so we added an opt-out for rspec-2.5:

autotest -- --skip-bundler

Autotest ignores everything after the initial --, so RSpec’s Autotest extension handles the --skip-bundler option.

Autotest’s bundler plugin

Autotest ships with a plugin for bundler. Just add the following to a .autotest file in the project’s root directory, or your home directory:

require 'autotest/bundler'

This prefixes the generated shell command with ‘bundle exec’.

UPDATE: The implicit detection of Gemfile is removed from rspec-core-2.5.1. See the post on the 2.5.1 release for more information.

Implicit detection of Gemfile is deprecated

Given that Autotest has its own way of dealing with Bundler (see above), we deprecated the implicit assumption that Gemfile means “use bundler”. You’ll see a deprecation notice if you are relying on that, but it still works. It’s just a deprecation warning. To silence the warning, either use the --skip-bundler option or Autotest’s bundler plugin, described above.

HTML Formatter

The HTML formatter now has a set of checkboxes in the header that allow you to filter what you’re looking at:

to not, or not to not

Are you the sort of person for whom “expect this block of code to not raise an error” is like nails on chalkboard? If so, relief has arrived. You may now type either of the following, and RSpec will happily service you:

expect { ... }.to_not raise_error
expect { ... }.not_to raise_error

Changelog

rspec-core-2.5.0

full changelog

  • Enhancements

    • Autotest::Rspec2 parses command line args passed to autotest after ‘–’
    • –skip-bundler option for autotest command
    • Autotest regexp fixes (Jon Rowe)
    • Add filters to html and textmate formatters (Daniel Quimper)
    • Explicit passing of block (need for JRuby 1.6) (John Firebaugh)
  • Bug fixes

    • fix dom IDs in HTML formatter (Brian Faherty)
    • fix bug with –drb + formatters when not running in drb
    • include –tag options in drb args (monocle)
    • fix regression so now SPEC_OPTS take precedence over CLI options again (Roman Chernyatchik)
    • only call its(:attribute) once (failing example from Brian Dunn)
    • fix bizarre bug where rspec would hang after String.alias :to_int :to_i (Damian Nurzynski)
  • Deprecations

    • implicit inclusion of ‘bundle exec’ when Gemfile present (use autotest’s bundler plugin instead)

rspec-expectations-2.5.0

full changelog

  • Enhancements

    • should exist works with exist? or exists? (Myron Marston)
    • expect { ... }.not_to do_something (in addition to to_not)
  • Documentation

    • improved docs for raise_error matcher (James Almond)

rspec-mocks-2.5.0

full changelog

  • Bug fixes
    • message expectation counts now work in combination with a stub (Damian Nurzynski)
    • fix failure message when message received with incorrect args (Josep M. Bach)

rspec-rails-2.5.0

full changelog

  • Enhancements

    • use index_helper instead of table_name when generating specs (Reza Primardiansyah)
  • Bug fixes

    • fixed bug in which render_views in a nested group set the value in its parent group.
    • only include MailerExampleGroup when it is defiend (Steve Sloan)
    • mock_model.as_null_object.attribute.blank? returns false (Randy Schmidt)
    • fix typo in request specs (Paco Guzman)

rspec-2.4.0 is released!

January 2nd, 2011

Changes in rspec-core and rspec-rails are listed below. There are no changes to rspec-mocks and rspec-expectations for this release.

rspec-core-2.4.0 / 2011-01-02

full changelog

  • Enhancements

    • start the debugger on -d so the stack trace is visible when it stops (Clifford Heath)
    • apply hook filtering to examples as well as groups (Myron Marston)
    • support multiple formatters, each with their own output
    • show exception classes in failure messages unless they come from RSpec matchers or message expectations
    • before(:all) { pending } sets all examples to pending
  • Bug fixes

    • fix bug due to change in behavior of reject in Ruby 1.9.3-dev (Shota Fukumori)
    • fix bug when running in jruby: be explicit about passing block to super (John Firebaugh)
    • rake task doesn’t choke on paths with quotes (Janmejay Singh)
    • restore –options option from rspec-1
    • require ‘ostruct’ to fix bug with its([key]) (Kim Burgestrand)
    • –configure option generates .rspec file instead of autotest/discover.rb

rspec-rails-2.4.0 / 2011-01-02

full changelog

  • Enhancements

    • include ApplicationHelper in helper object in helper specs
    • include request spec extensions in files in spec/integration
    • include controller spec extensions in groups that use :type => :controller
    • same for :model, :view, :helper, :mailer, :request, :routing
  • Bug fixes

    • restore global config.render_views so you only need to say it once
    • support overriding render_views in nested groups
    • matchers that delegate to Rails’ assertions capture ActiveSupport::TestCase::Assertion (so they work properly now with should_not in Ruby 1.8.7 and 1.9.1)
  • Deprecations

    • include_self_when_dir_matches