Create custom jasmine matcher using Typescript

旧巷老猫 提交于 2019-12-01 15:47:17

Daf's answer mostly worked for me I just noticed an issue with his sample code and the way he named his files. I also happened upon another unrelated issue. Hence a new answer.

  • For some reason my app does not like it when the interface file has the same name as the matcher file. e.g foo.ts and foo.d.ts. For my app it needed to be foo.ts and foo-interface.d.ts or something like it.
  • Also don't import interfaces from foo.ts into foo-interface.d.ts it also does not seem to like this.

Sample custom matcher here: - https://github.com/vespertilian/wallaby-angular-node-yarn-workspaces/tree/master/api/src/test-helpers Sample specs here: - https://github.com/vespertilian/wallaby-angular-node-yarn-workspaces/blob/master/api/src/hello/hello.spec.ts

Matcher - custom-matchers.ts

import MatchersUtil = jasmine.MatchersUtil;
import CustomMatcherFactories = jasmine.CustomMatcherFactories;
import CustomEqualityTester = jasmine.CustomEqualityTester;
import CustomMatcher = jasmine.CustomMatcher;
import CustomMatcherResult = jasmine.CustomMatcherResult;

export const SomeCustomMatchers: CustomMatcherFactories = {
    toReallyEqual: function (util: MatchersUtil, customEqualityTester: CustomEqualityTester[]): CustomMatcher {
        return {
            compare: function (actual: any, expected: any): CustomMatcherResult {
                if(actual === expected) {
                    return {
                        pass: true,
                        message: `Actual equals expected`
                    }
                } else {
                    return {
                        pass: false,
                        message: `Actual does not equal expected`
                    }
                }

            }
        }
    }
};

Interface file - matcher-types.d.ts - cannot be the same name as your matcher file

declare namespace jasmine {
    interface Matchers<T> {
        toReallyEqual(expected: any, expectationFailOutput?: any): boolean;
    }
}

Custom matcher test

describe('Hello', () => {

    beforeEach(() => {
        jasmine.addMatchers(SomeCustomMatchers)
    });

    it('should allow custom matchers', () => {
        expect('foo').toReallyEqual('foo');
        expect('bar').not.toReallyEqual('test');
    })
});

Basically, your second example ("declare namespace") is the way to go, with your logic for the matchers somewhere else, of course.

You're welcome to take a look at https://github.com/fluffynuts/polymer-ts-scratch/tree/5eb799f7c8d144dd8239ab2d2bcc72821327cb24/src/specs/test-utils/jasmine-matchers where I have written some Jasmine matchers and typings to go along with them -- though technically I wrote the actual matchers in Javascript and just named the logic files .ts to placate my build process.

You will need to install @types/jasmine -- and keep it current.

Just bear in mind that different versions of @types/jasmine may break things; specifically, the commit linked above was when Jasmine types introduced the Matchers type having a type parameter (ie, Matchers<T>) which broke all my .d.ts files.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!