Skip to content

Commit

Permalink
feat: add custom matcher for class
Browse files Browse the repository at this point in the history
  • Loading branch information
cexbrayat committed May 26, 2018
1 parent a0777a8 commit 39d1f3a
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 1 deletion.
67 changes: 67 additions & 0 deletions projects/ngx-speculoos/src/lib/matchers.spec.ts
@@ -0,0 +1,67 @@
import { Component } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ComponentTester } from './component-tester';
import { elementMatchers } from './matchers';

@Component({
template: `
<div id="classes" class="foo bar">Hello</div>
<div id="none">Hello</div>
`
})
class TestComponent {
}

class TestComponentTester extends ComponentTester<TestComponent> {
constructor() {
super(TestComponent);
}

get div() {
return this.element('#classes');
}

get none() {
return this.element('#none');
}
}

describe('Custom matchers', () => {

let tester: TestComponentTester;

beforeEach(() => {
TestBed.configureTestingModule({ declarations: [TestComponent] });
tester = new TestComponentTester();
tester.detectChanges();
jasmine.addMatchers(elementMatchers);
});

it('should check for a class', () => {
expect(tester.div).toHaveClass('foo');
expect(tester.div).not.toHaveClass('baz');

const matcher = elementMatchers.toHaveClass(undefined, undefined);

// missing class
let result = matcher.compare(tester.div, 'baz');
expect(result.pass).toBeFalsy();
expect(result.message).toBe(`Expected element to have class 'baz', but had 'foo, bar'`);

// no class
result = matcher.compare(tester.none, 'baz');
expect(result.pass).toBeFalsy();
expect(result.message).toBe(`Expected element to have class 'baz', but had none`);

// null element
result = matcher.compare(null, 'baz');
expect(result.pass).toBeFalsy();
expect(result.message).toBe(`Expected element to have class 'baz', but element was falsy`);

// not a TestElement
result = matcher.compare('hello', 'baz');
expect(result.pass).toBeFalsy();
expect(result.message).toBe(`Expected element to have class 'baz', but element was not a TestElement`);
});
});
25 changes: 25 additions & 0 deletions projects/ngx-speculoos/src/lib/matchers.ts
@@ -0,0 +1,25 @@
import { TestElement } from './test-element';
const elementMatchers: jasmine.CustomMatcherFactories = {

/**
* Checks that an element has the specified class
*/
toHaveClass: (util: jasmine.MatchersUtil, customEqualityTesters: Array<jasmine.CustomEqualityTester>): jasmine.CustomMatcher => {
return {
compare: (el: any, expected: string): jasmine.CustomMatcherResult => {
if (!el) {
return { pass: false, message: `Expected element to have class '${expected}', but element was falsy` };
}
if (!(el instanceof TestElement)) {
return { pass: false, message: `Expected element to have class '${expected}', but element was not a TestElement` };
}
const actual = el.classes;
const pass = actual.includes(expected);
const message = `Expected element to have class '${expected}', but had ${actual.length ? '\'' + actual.join(', ') + '\'' : 'none'}`;
return { pass, message };
}
};
}
};

export { elementMatchers };
5 changes: 5 additions & 0 deletions projects/ngx-speculoos/src/matchers-types.d.ts
@@ -0,0 +1,5 @@
declare namespace jasmine {
interface Matchers<T> {
toHaveClass(className: string): boolean;
}
}
2 changes: 2 additions & 0 deletions projects/ngx-speculoos/src/public_api.ts
@@ -1,6 +1,7 @@
/*
* Public API Surface of ngx-speculoos
*/
/// <reference path="./matchers-types.d.ts" />

export * from './lib/component-tester';
export * from './lib/test-element';
Expand All @@ -9,3 +10,4 @@ export * from './lib/test-input';
export * from './lib/test-button';
export * from './lib/test-select';
export * from './lib/route';
export * from './lib/matchers';
4 changes: 3 additions & 1 deletion projects/ngx-speculoos/tsconfig.lib.json
Expand Up @@ -12,7 +12,9 @@
"experimentalDecorators": true,
"importHelpers": true,
"strict": true,
"types": [],
"types": [
"@types/jasmine"
],
"lib": [
"dom",
"es2015"
Expand Down

0 comments on commit 39d1f3a

Please sign in to comment.