[rspec-devel] [ rspec-Bugs-10594 ] Failing Custom Matcher show NAME NOT GENERATED description

noreply at rubyforge.org noreply at rubyforge.org
Fri May 4 22:37:45 EDT 2007

Bugs item #10594, was opened at 2007-05-04 20:34
You can respond by visiting: 

Category: None
Group: None
Status: Open
Resolution: None
Priority: 3
Submitted By: Luis Lavena (luislavena)
Assigned to: Aslak Hellesøy (aslak_hellesoy)
Summary: Failing Custom Matcher show NAME NOT GENERATED description

Initial Comment:
By request of aslak hellesoy:

Also, auto-generated names for the examples is very helpful, I'm
trying to take advantage of it.

Since I often prior code/define all the "examples", I have created a
few matchers to fulfill associations and validations of attributes.

describe "A User (in general)" do
 before(:each) do
   @user = User.new

 it { @user.should have_many(:contest_public_votes) }
 it { @user.should have_many(:design_industry_user_interests) }
 it { @user.should have_one(:user_extension) }

That creates the following descriptions:

A User (in general)
- should has_many contest_public_votes
- should has_many design_industry_user_interests
- should has_one user_extension

A new User
- should not be valid without first_name
- should not be valid without last_name
- should not be valid without login
- should not be valid without email
- should not be valid without password
- should not be valid without password_confirmation
- should not be valid without city
- should not be valid without postal_code
- should not be valid without country
- should not be valid with duplicate login
- should not be valid with duplicate email

Anyway, the problem started with latest release, which if someone my
matcher shows a problem, NAME NOT GENERATED was put in the description
instead of my fancy, nicely done name ;-)

Attached I have included a faulty matcher that shows the issue.


>Comment By: Luis Lavena (luislavena)
Date: 2007-05-04 23:37

Thank you Aslak for the explanation.

Actually I'm not trying to raise an exception from my
matcher, but trying to track errors on them during creation.

A lot of things about matchers are missing in docs, but
tried to mimic existing ones (and the examples too).

Anyway, the case I'm dealing with is this:

I'm trying to validate attributes and the "validations"
(validates_presence_of, validates_uniqueness_of, etc.)
Also associations through these matchers.

module ModelSpecHelper
  class Present
    def initialize(attr)
      @attr = attr
    def matches?(model)
      @model = model
      model.send("#{@attr.to_s}=".to_sym, nil)
      return !model.errors.on("#{@attr.to_s}".to_sym).nil?
    def failure_message; "expected #{@model.inspect} to have
present #{@attr.inspect}"; end
    def description; "not be valid without #{@attr}"; end

  # Here start the accessor for examples:
  #  it { model.should have_present(:attr) } => should not
be valid without :attr
  def have_present(attr)

describe "An Asset" do
  before(:each) do
    @asset = Asset.new

  [:title, :content_type, :basename].each do |attr|
    it { @asset.should have_present(attr) }

  it { @asset.should have_one(:attachment) }
  it { @asset.should have_present(:something) }

has_one :attachment nor something attribute are present in
the model.

in the has_one association, the displayed message is this:
'An Asset should has_one attachment' FAILED
expected Asset to has_one :attachment

But, in the have_present(:something):
NoMethodError in 'An Asset NAME NOT GENERATED'
undefined method `pepe=' for #<Asset:0x4688e78>
./spec/my_helpers.rb:9:in `send'
./spec/my_helpers.rb:9:in `matches?'

Is easy to track down the error, but is not visually
appealing if I made a typo or something. If i put everything
into a begin ... rescue could workaround this, now I know.

Wanted to know if I'm doing something wrong (like breaking
rspec, I'm used to crash things) ;-)

made some corrections:

    def matches?(model)
      @model = model
      if model.respond_to?("#{@attr.to_s}=".to_sym)
        model.send("#{@attr.to_s}=".to_sym, nil)

and that avoids the exception.

Thanks again for your time



Comment By: Aslak Hellesøy (aslak_hellesoy)
Date: 2007-05-04 21:40

This is a little trickier to solve than I had first thought. Just so I understand you correctly: You want the automatic description to be set even when your matcher's #matches? method raises an exception?

Such behaviour is actually in violation of the general contract for matchers (which I admit is not clearly documented). #matches? is not allowed to raise exceptions - it must always return true or false. 

In addition to this it is recommended that #matches? creates an instance reference to the +actual+ argument so that it can be used later in the #description method (if appliccable). This is what happens in most of RSpec's built-in matchers.

RSpec can only assume that if #matches? raised an exception, then calling #description would most likely return gibberish (we must assume that @actual was never set), and it doesn't even try to call it. This happens in handler.rb.

This is why you don't get a generated description for your examples without names.

The solution should be simple - just add a rescue in your #matches? method and have it return false when something goes wrong.

Maybe David has something to add.


You can respond by visiting: 

More information about the rspec-devel mailing list