Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jasmine: How can I reuse other matchers in my custom matchers

I'm writing a custom matcher in Jasmine (1.3, but the question also applies for 2.0), that extends on the functionality of a built-in matcher. How can I call the built-in matcher with another actual value? I've tried to just do expect(otherActual).toEqual(expected), but this returns undefined.

The actual code I've tried:

var customMatchers = {
  toHaveAttributes: function (expected) {
    if(!this.actual) {
        throw new Error("Test parameter is " + this.actual);
    }
    if(!(this.actual instanceof Backbone.Model)) {
        throw new Error("Test parameter must be a Backbone Model");
    }
    var notText = this.isNot ? " not" : "";
    var actualAttrs = this.actual.attributes;
    this.message = function () {
        return "Expected model to" + notText + " have attributes " + jasmine.pp(expected) +
        ", but was " + jasmine.pp(actualAttrs);
    };
    // return expect(actualAttrs).toEqual(expected); // Returns undefined
    // return this.env.currentSpec.expect(actualAttrs).toEqual(expected); // Also returns undefined
    return this.env.equals_(actualAttrs, expected); // Works, but copied from jasmine.Matchers.prototype.toEqual
  }
}

The matcher is a Backbone-specific shorthand-function to check the attributes of a Model. The two return-lines I've commented out returns undefined. The third return works, but is copy-paste code and uses jasmine internals so is prone to breaking.

like image 630
Wonko Avatar asked Nov 23 '22 21:11

Wonko


1 Answers

In Jasmine 2.x at least, factory functions for each registered matcher can be found on the jasmine.matchers global object.

To make use of the functionality behind toEqual you could write

var toEqual = jasmine.matchers.toEqual();
var result = toEqual.compare('foo', 'bar');

and in this case value of result here would be;

{
    pass: false
}

because "foo" does not equal "bar".

like image 197
Jamie Mason Avatar answered Jan 05 '23 00:01

Jamie Mason