-
Notifications
You must be signed in to change notification settings - Fork 1
/
mock-component.ts
44 lines (33 loc) · 1.59 KB
/
mock-component.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import {Component, EventEmitter, Input, Output, Type} from "@angular/core"
import {selectorOf} from "./selector-of"
import {extend, keys, keysIn, reduce, set, some} from "lodash"
import {stub} from "sinon"
import {propertyMetadata} from "./reflection"
let _mockProvider = stub
function propertiesDecoratedWith(decorator: any, propertyMetadata: any): string[] {
return keys(propertyMetadata).filter((key: any) => instanceExistsIn(decorator, propertyMetadata[key]))
}
function instanceExistsIn<T>(object: Type<T>, list: any[]): boolean {
return some(list, (dec: any) => dec instanceof object)
}
export type MockSetup = (mock: any) => void
export function mockProvider(mockProvider: () => any) {
_mockProvider = mockProvider
}
export function mockComponent<T>(constructor: Type<T>, mockSetup: MockSetup = () => {}): any {
const componentPropertyMetadata = propertyMetadata(constructor)
const options = {
selector: selectorOf(constructor),
template: "<ng-content></ng-content>",
inputs: propertiesDecoratedWith(Input, componentPropertyMetadata),
outputs: propertiesDecoratedWith(Output, componentPropertyMetadata),
}
const MockComponent = () => {
const outputs = reduce(options.outputs, (obj, property) => set(obj, property, new EventEmitter<any>()), {})
const mockedMethods = keysIn(constructor.prototype).reduce((obj, property) => set(obj, property, _mockProvider()), {})
const mocked = extend({}, outputs, mockedMethods)
mockSetup(mocked)
return mocked
}
return Component(options as Component)(MockComponent)
}