Skip to content

Commit

Permalink
feat: mock directives now have event emitter bound outputs
Browse files Browse the repository at this point in the history
  • Loading branch information
ike18t committed Mar 25, 2018
1 parent fee5a03 commit bac1ca5
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 5 deletions.
17 changes: 14 additions & 3 deletions lib/mock-directive/mock-directive.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Directive, Input } from '@angular/core';
import { Component, Directive, EventEmitter, Input, Output } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormControlDirective } from '@angular/forms';
import { By } from '@angular/platform-browser';
Expand All @@ -10,17 +10,20 @@ import { MockDirective } from './mock-directive';
})
export class ExampleDirective {
@Input() exampleDirective: string;
@Output() someOutput = new EventEmitter<boolean>();
@Input('bah') something: string;
}

@Component({
selector: 'example-component-container',
template: `
<div [exampleDirective]="'bye'" [bah]="'hi'" #f="foo"></div>
<div [exampleDirective]="'bye'" [bah]="'hi'" #f="foo" (someOutput)="emitted = $event"></div>
<div exampleDirective></div>
`
})
export class ExampleComponentContainer {} // tslint:disable-line:max-classes-per-file
export class ExampleComponentContainer {
emitted = false;
} // tslint:disable-line:max-classes-per-file

describe('MockComponent', () => {
let fixture: ComponentFixture<ExampleComponentContainer>;
Expand Down Expand Up @@ -52,6 +55,14 @@ describe('MockComponent', () => {
expect(element.exampleDirective).toEqual('bye');
});

it('triggers output bound behavior for extended outputs', () => {
const debugElement = fixture.debugElement.query(By.directive(MockDirective(ExampleDirective)));
const element = debugElement.injector.get(MockDirective(ExampleDirective));

element.someOutput.emit(true);
expect(fixture.componentInstance.emitted).toEqual(true);
});

it('should memoize the return value by argument', () => {
expect(MockDirective(ExampleDirective)).toEqual(MockDirective(ExampleDirective));
expect(MockDirective(ExampleDirective)).not.toEqual(ExampleDirective);
Expand Down
13 changes: 11 additions & 2 deletions lib/mock-directive/mock-directive.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Directive, Type } from '@angular/core';
import { Directive, EventEmitter, Type } from '@angular/core';
import { getInputsOutputs } from '../common/reflect';

const cache = new Map<Type<Directive>, Type<Directive>>();
Expand Down Expand Up @@ -31,7 +31,16 @@ export function MockDirective<TDirective>(directive: Type<TDirective>): Type<TDi
selector: annotation.selector
};

const mockedDirective = Directive(options)(class DirectiveMock {} as Type<TDirective>);
// tslint:disable-next-line:no-unnecessary-class
class DirectiveMock {
constructor() {
(options.outputs || []).forEach((output) => {
(this as any)[output.split(':')[0]] = new EventEmitter<any>();
});
}
}

const mockedDirective = Directive(options)(DirectiveMock as Type<TDirective>);
cache.set(directive, mockedDirective);

return mockedDirective;
Expand Down

0 comments on commit bac1ca5

Please sign in to comment.