add support for chainable matchers (commits condensed) #194

wants to merge 4 commits into

4 participants


I condensed the commits from this pull request down into 4, and gave lengthier commit messages.

maxbrunsfeld added some commits Mar 3, 2012
@maxbrunsfeld maxbrunsfeld Add ability to update ExpectationResults after creating them.
This is to support chained matcher functions. A chain
of matcher functions needs to produce a single result.
So when a chained matcher executes, it needs to update
the message and pass/fail status of an existing expectation

Three new methods have been added:
- ExpectationResult#update. 
- NestedResults#updateResult
- Spec#updateExpectationResult

The last of these functions will be called from inside
chained matcher functions, instead of #addExpectationResult.
@maxbrunsfeld maxbrunsfeld Add utility method for creating subclasses.
When initializing and adding matchers, multiple
anonymous subclasses of jasmine.Matchers are created,
whose constructor functions just call 'super'. In order 
to support chainable matchers, more matchers classes
will have to be created, with the same behavior. 
This function reduces the repetition involved in doing this.
@maxbrunsfeld maxbrunsfeld allow Spec#addMatchers to create chained matchers classes
this adds three new ways off calling #addMatchers:

- with an additional string parameter that specifies
  which matcher the new matcher functions will be 
  chainable from.

- with an *array* of these matcher names. this allows
  a matcher to be made chainable from more than one
  matcher function.

- with a matchers hash whose keys contain multiple
  space-separated matcher names, e.g.
  "toHaveBeenCalled before": function() {...

A Spec object now has a hash of chained matchers
classes. Calling #addMatchers in the above ways
will create and add methods to these classes. 
When a chained matchers class exists for a given 
matcher function, that function will return an 
instance of that matchers class.
@maxbrunsfeld maxbrunsfeld Make chained matchers produce correct expectation results
The ExpectationResult created by the first matcher in
a chain is now passed to all of the successive matchers.
Each matcher updates the result's pass/fail status,
message and stack trace.

Normally, the chain of matchers will produce a passing
result iff *all* of the matchers in the chain match
successfully (i.e. their definition functions return

With a `not` at the beginning of the matcher chain,
the chain will produce a passing result iff *any*
of the matchers in the chain fail to match.

Do you guys have any feedback on this one? I wanted to build on it by adding these chainable matchers for spies:


They'd be usable in any combination with each other, and with people's custom spy matchers. Would you guys merge such a thing?


I am not from Pivotal, and I think this PR is nice, but a rare user should need it. So if you'll just keep it here and we'll just know that it exists, will be very fine.

For my cases I've created toHaveBeenCalledOnce and toHaveBeenCalledThisAmountOfTimes, they are in separate file and take no more than 10 lines, and it's enough for me.


This is something I'd like to see eventually make it in; can't be auto-merged any longer, but we'll keep it open to make sure we're tracking it.


We pondered this for 2.0 and decided to defer.

Saved this for posterity in this Tracker Story.

@infews infews closed this Jun 23, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment