diff --git a/lib/mock_directive.spec.ts b/lib/mock_directive.spec.ts index a8b5db96f1..02aa8a2827 100644 --- a/lib/mock_directive.spec.ts +++ b/lib/mock_directive.spec.ts @@ -1,4 +1,5 @@ import { Component, Directive, Input } from '@angular/core'; +import { FormControlDirective } from '@angular/forms'; import { async, ComponentFixture, getTestBed, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { @@ -64,4 +65,14 @@ describe('MockComponent', () => { expect(MockDirective(ExampleDirective)).toEqual(MockDirective(ExampleDirective)); expect(MockDirective(ExampleDirective)).not.toEqual(ExampleDirective); }); + + it('can mock formControlDirective from angular', () => { + // Some angular directives set up their metadata in a different way than @Directive does + // I found that FormControlDirective is one of those weird directives. + // Since I don't know how they did it, I don't know how to test it except to write this + // test around a known-odd directive. + expect(() => { + MockDirective(FormControlDirective); + }).not.toThrow(); + }); }); diff --git a/lib/mock_directive.ts b/lib/mock_directive.ts index 24c798b574..a3ca3d340c 100644 --- a/lib/mock_directive.ts +++ b/lib/mock_directive.ts @@ -8,15 +8,25 @@ export function MockDirective(directive: Type): Type; } - const annotations = (directive as any).__annotations__[0] || {}; + let annotation: any = {}; + const annotations: any[] = (directive as any).__annotations__; + if (annotations) { + annotation = annotations[0]; + } else { + if (!directive.hasOwnProperty('decorators')) { + throw new Error(`Cannot find the annotations/decorators for directive ${directive.name}`); + } + return (directive as any).decorators[0].args[0]; + } + const propertyMetadata = (directive as any).__prop__metadata__ || {}; const options: Directive = { - exportAs: annotations.exportAs, + exportAs: annotation.exportAs, inputs: Object.keys(propertyMetadata) .filter((meta) => isInput(propertyMetadata[meta])) .map((meta) => [meta, propertyMetadata[meta][0].bindingPropertyName || meta].join(':')), - selector: annotations.selector + selector: annotation.selector }; const mockedDirective = Directive(options)(class DirectiveMock {} as Type); diff --git a/package-lock.json b/package-lock.json index 08e84fa95f..42a2ca067d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,15 @@ "tslib": "1.8.0" } }, + "@angular/forms": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-5.2.4.tgz", + "integrity": "sha512-0k6rs2k85wcBq0WPAjxNbtBu1wq/1fUSFaBLbpnrwwHeCLJI5aAjG2/f3jv/17a/ek7/WZ3lxXtHzNMMdaD/Iw==", + "dev": true, + "requires": { + "tslib": "1.8.0" + } + }, "@angular/platform-browser": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-5.1.2.tgz", diff --git a/package.json b/package.json index 0ed9349561..3675dad34c 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "@angular/common": "5.x", "@angular/compiler": "5.x", "@angular/core": "5.x", + "@angular/forms": "5.x", "@angular/platform-browser": "5.x", "@angular/platform-browser-dynamic": "5.x", "@types/core-js": "^0.9.43",