diff --git a/projects/ngx-speculoos/src/lib/matchers.spec.ts b/projects/ngx-speculoos/src/lib/matchers.spec.ts new file mode 100644 index 00000000..3147c11e --- /dev/null +++ b/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: ` +
Hello
+
Hello
+ ` +}) +class TestComponent { +} + +class TestComponentTester extends ComponentTester { + 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`); + }); +}); diff --git a/projects/ngx-speculoos/src/lib/matchers.ts b/projects/ngx-speculoos/src/lib/matchers.ts new file mode 100644 index 00000000..f6baad60 --- /dev/null +++ b/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.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 }; diff --git a/projects/ngx-speculoos/src/matchers-types.d.ts b/projects/ngx-speculoos/src/matchers-types.d.ts new file mode 100644 index 00000000..ecc1a626 --- /dev/null +++ b/projects/ngx-speculoos/src/matchers-types.d.ts @@ -0,0 +1,5 @@ +declare namespace jasmine { + interface Matchers { + toHaveClass(className: string): boolean; + } +} diff --git a/projects/ngx-speculoos/src/public_api.ts b/projects/ngx-speculoos/src/public_api.ts index f1f56d98..009425bf 100644 --- a/projects/ngx-speculoos/src/public_api.ts +++ b/projects/ngx-speculoos/src/public_api.ts @@ -1,6 +1,7 @@ /* * Public API Surface of ngx-speculoos */ +/// export * from './lib/component-tester'; export * from './lib/test-element'; @@ -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'; diff --git a/projects/ngx-speculoos/tsconfig.lib.json b/projects/ngx-speculoos/tsconfig.lib.json index 19338590..9f4f6dc1 100644 --- a/projects/ngx-speculoos/tsconfig.lib.json +++ b/projects/ngx-speculoos/tsconfig.lib.json @@ -12,7 +12,9 @@ "experimentalDecorators": true, "importHelpers": true, "strict": true, - "types": [], + "types": [ + "@types/jasmine" + ], "lib": [ "dom", "es2015"