pivotal/jasmine — pull request #434 by tjgrathwell (2013-09-27 04:08:02+00:00)
Title: Short-circuit 'eq' when custom matchers return true or false

I stumbled across this problem when I noticed that `expect({}).toEqual({})` returned false, but only when custom matchers were defined. Consider the following friendly matcher:

```
var backboneModelEqualityTester = function(a, b) {
if(a instanceof Backbone.Model && b instanceof Backbone.Model) {
if (a.constructor !== b.constructor) return false;
if (!_.isUndefined(a.id) && !_.isUndefined(b.id)) return (a.id === b.id);
if (!_.isUndefined(a.cid) && !_.isUndefined(b.cid)) return (a.cid === b.cid);
}
};
```

Our friend `backboneModelEqualityTester` wants to say "If these two objects are Backbone objects, they're equal if their 'id' or 'cid' properties are equal. Otherwise, who knows?".

In the current version of the code, the result of each custom matcher is written back into `eq`'s `result` var, possibly in error. This is what causes the `expect({}).toEqual({})` problem, because the success of that statement relies on the original value of `result` being preserved.

Additionally, instead of allowing matchers to say "yes/no/who knows?", only a result of `true` is really respected. There was a test asserting that a custom matcher returning `false` would trump the decision's of `eq`'s body, but it was typoed so as to be passing incorrectly.