How to write advanced matchers


#1

Hi Folks!

For any developers reading… thank you for RSpec… it’s wonderful!
I’ve been trying my darndest to get into it, spec everything ahead of
time, and it’s working out great.

The one thing I really have a hard time with though is writing more
advanced custom matchers. I can write simple ones, but the code for
the fancier matchers in RSpec is much more opaque. Often the code for
something like an_instance_of is shared across several matchers, or
it’s being done partly by the translator? It’s hard to tell. And so
it’s hard to write a custom matcher that does the same kind of job.

I was wondering if someone with better Ruby skillz than I have, and
more RSpec knowledge might explain how to structure some of the
slightly fancier types of matchers. Like how do you write…

  • a matcher that accepts a block and passes on some information, like
    has_tag?
  • a matcher that can go in that block and use that information, like
    with_tag?
  • a mock argument matcher like is_instance_of or hash_including?

It’d be wonderful if someone could post simple examples of how you’d
write custom matchers of those types. I’ve tried
(http://erikonrails.snowedin.net/?p=33) and failed.

All the best,

Erik P.


#2

“Erik P.” removed_email_address@domain.invalid writes:

  • a matcher that accepts a block and passes on some information, like has_tag?
  • a matcher that can go in that block and use that information, like with_tag?
  • a mock argument matcher like is_instance_of or hash_including?

It’d be wonderful if someone could post simple examples of how you’d
write custom matchers of those types

I hope this doesn’t come across as rude…but considering that RSpec is
open source, you just listed a bunch of examples for yourself to check
out! Now all you have to do is look at the source for them.

Pat


#3

Hey Pat,

Thanks for your response! Even if it’s just to say RTFC. :slight_smile: I have
been digging into the source regularly. It’s a bit too complicated
for me to understand right now, and I find often the way core matchers
are written is appropriate for code that is going to be distributed
with RSpec, but not for code that is going to be maintained outside of
RSpec.

But you’re right, once I understand the RSpec internals, It’ll be easy
to write matchers with a different architecture. It’s just slow going
sometimes.

best,

Erik


#4

On Mon, Nov 24, 2008 at 6:36 PM, Erik P. removed_email_address@domain.invalid
wrote:

I hope this doesn’t come across as rude…but considering that RSpec is
open source, you just listed a bunch of examples for yourself to check
out! Now all you have to do is look at the source for them.

Pat

Hey Pat,

Thanks for your response! Even if it’s just to say RTFC. :slight_smile: I have
been digging into the source regularly. It’s a bit too complicated
for me to understand right now, and I find often the way core matchers
are written is appropriate for code that is going to be distributed
with RSpec, but not for code that is going to be maintained outside of
RSpec.

Would you mind elaborating on this? What about the way it is written
makes it appropriate to ship w/ RSpec but inappropriate for your own
code?

Cheers,
David