Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to use Jasmine default matchers within custom matchers?

I have a custom matcher in some Jasmine test specs of the form:

this.addMatchers({
    checkContains: function(elem){
        var found = false;
        $.each( this.actual, function( actualItem ){

            // Check if these objects contain the same properties.
            found = found || actualItem.thing == elem;
        });
        return found;
    }
});

Of course, actualItem.thing == elem doesn't actually compare object contents- I have to use one of the more complex solutions in Object comparison in JavaScript.

I can't help but notice, though, that Jasmine already has a nice object equality checker: expect(x).toEqual(y). Is there any way to use that within a custom matcher? Is there any general way to use matchers within custom matchers?

like image 873
Fishtoaster Avatar asked Jan 20 '12 20:01

Fishtoaster


People also ask

How do I add a custom matcher to Jasmine?

Custom Matchers describe('This custom matcher example', function() { beforeEach(function() { // We should add custom matched in beforeEach() function. jasmine. addMatchers ({ validateAge: function() { Return { compare: function(actual,expected) { var result = {}; result. pass = (actual > = 13 && actual < = 19); result.

What is custom matcher?

Custom matcher helps in the AdapterView based test cases to match with the different type of underlying data. To simplify the current matchers by combining features of multiple matcher.

Which is a custom matcher in angular?

A custom matcher at its root is a comparison function that takes an actual value and expected value. This factory is passed to Jasmine, ideally in a call to beforeEach, and will be in scope and available for all of the specs inside a given call to describe. Custom matchers are torn down between specs.


1 Answers

Yes, it is slightly hacky but entirely possible.

The first thing we need to do is make the Jasmine.Env class available. Personally I have done this in my SpecRunner.html since its already setup there anyway. On the load of my SpecRunner I have the following script that runs:

(function() {
      var jasmineEnv = jasmine.getEnv();
      jasmineEnv.updateInterval = 1000;

      var trivialReporter = new jasmine.TrivialReporter();

      jasmineEnv.addReporter(trivialReporter);

      jasmineEnv.specFilter = function(spec) {
        return trivialReporter.specFilter(spec);
      };

      var currentWindowOnload = window.onload;

      window.onload = function() {
        if (currentWindowOnload) {
          currentWindowOnload();
        }
        execJasmine();
      };

      function execJasmine() {
        jasmineEnv.execute();
      };

    })();

So after the execJasmine function declaration I push the jasmineEnv into the global namespace by adding this:

this.jasmineEnv = jasmineEnv;

Now, in any of my spec files I can access the jasmineEnv variable and that is what contains the matchers core code.

Looking at toEqual specifically, toEqual calls the jasmine.Env.prototype.equals_ function. This means that in your customMatcher you can do the following:

beforeEach(function(){
    this.addMatchers({
        isJasmineAwesome    : function(expected){
            return jasmineEnv.equals_(this.actual, expected);
        }
    });
});

Unfortunately, using this method will only give you access to the following methods:

  1. compareObjects_
  2. equals_
  3. contains_

The rest of the matchers reside the jasmine.Matchers class but I have not been able to make that public yet. I hope this helps you out in someway or another

like image 107
StevenMcD Avatar answered Oct 05 '22 14:10

StevenMcD