Skip to content

Commit

Permalink
fix: Add support for directives with a different kind of meta
Browse files Browse the repository at this point in the history
  • Loading branch information
Brandon Domingue committed Feb 8, 2018
1 parent e0f27f6 commit 0bd38cc
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 3 deletions.
11 changes: 11 additions & 0 deletions lib/mock_directive.spec.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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();
});
});
16 changes: 13 additions & 3 deletions lib/mock_directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,25 @@ export function MockDirective<TDirective>(directive: Type<TDirective>): Type<TDi
return cacheHit as Type<TDirective>;
}

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<TDirective>);
Expand Down
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down

0 comments on commit 0bd38cc

Please sign in to comment.