[rspec-users] syntax for custom messages

David Chelimsky dchelimsky at gmail.com
Mon Mar 5 14:10:01 UTC 2012


On Mon, Mar 5, 2012 at 2:18 AM, ruud144 <r.grosmann at gmail.com> wrote:
> hi group,
>
> I read that expectations can print a custom message on failure using a
> syntax like
>
> cars.should be_empty, "Cars left"
>
> But when I try this syntax for this expectation:
>
> string.should == 'Cars left', 'Yippee, no cars anymore'
>
> I get a syntax error:
>
> syntax error, unexpected ',', expecting keyword_end (SyntaxError)
>
> I want two things:
> - I want a syntax error free expectation for should ==

Can't have it because Ruby won't parse it. The reason `a.should == b`
works is because Ruby parses that as `a.should.==(b)`.

There is an `eq` matcher, which is the recommended approach these days
for this (and other similar) reason(s):

string.should eq('Cars left'), 'Yippee, no cars anymore'

> - I want to understand what the mechanism is. I am afraid that my ruby
> knowledge is not sufficient. Clearly, should is a function, but what
> are be_empty and == then? Parameters? Can I use parentheses?

Here are the bits of code relevant to your question:

https://github.com/rspec/rspec-expectations/blob/master/lib/rspec/expectations/extensions/kernel.rb#L11-13

https://github.com/rspec/rspec-expectations/blob/master/lib/rspec/expectations/handler.rb#L4-7

The `should` method delegates to `handle_matcher`, passing along the
matcher (which might be nil), optional message (also might be nil),
and optional block (again, might be nil).

When you use `a.should == b`, the matcher itself is nil, and the
`handle_matcher` method delegates to a `PositiveOperatorMatcher`
(there is also a `NegativeOperatorMatcher` for `should_not`),
otherwise it handles the matcher itself.

Parens won't help you here because everything after `==` is bound to
`==`, not should - there's no way (that I know of) to bind the message
to `should`. It's feasible to pass an array to `==`:

  string.should == ['Cars left', 'Yippee, no cars anymore']

... but then we'd be comparing `string` with the list, so that
wouldn't work either (nor would it make any sense).

Your best bet is using the `eq` matcher, as described above.

HTH,
David

>
> Thanks for helping me!
>
> Ruud


More information about the rspec-users mailing list