/
mock-builder.ts
94 lines (83 loc) · 3.36 KB
/
mock-builder.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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import coreDefineProperty from '../common/core.define-property';
import { flatten, mapKeys } from '../common/core.helpers';
import { AnyDeclaration } from '../common/core.types';
import { NgModuleWithProviders } from '../common/func.is-ng-module-def-with-providers';
import { isStandalone } from '../common/func.is-standalone';
import ngMocksUniverse from '../common/ng-mocks-universe';
import helperExtractPropertyDescriptor from '../mock-service/helper.extract-property-descriptor';
import { MockBuilderPerformance } from './mock-builder.performance';
import { IMockBuilder, IMockBuilderExtended } from './types';
export type MockBuilderParam = string | AnyDeclaration<any> | NgModuleWithProviders;
/**
* MockBuilder provides reach and simple interfaces of chain functions
* to build desired mock environment for tests.
*
* @see https://ng-mocks.sudo.eu/api/MockBuilder
*/
export function MockBuilder(
keepDeclaration?: MockBuilderParam | MockBuilderParam[] | null | undefined,
itsModuleToMock?: MockBuilderParam | MockBuilderParam[] | null | undefined,
): IMockBuilderExtended;
export function MockBuilder(...args: Array<MockBuilderParam | MockBuilderParam[] | null | undefined>): IMockBuilder {
const [keepDeclaration, itsModuleToMock] = args;
const instance = new MockBuilderPerformance(args.length < 2 ? { export: true } : { dependency: true });
const extensions: Map<any, any> = ngMocksUniverse.config.get('MockBuilderExtensions');
for (const func of extensions ? mapKeys(extensions) : []) {
if (helperExtractPropertyDescriptor(instance, func)) {
throw new Error(`MockBuilder.${func} is a base method and cannot be customized, please use a different name.`);
}
coreDefineProperty(instance, func, (...args: Array<any>) => {
extensions.get(func)(instance, args);
return instance;
});
}
if (keepDeclaration) {
for (const declaration of flatten(keepDeclaration)) {
instance.keep(declaration, {
export: true,
shallow: isStandalone(declaration),
});
}
}
if (itsModuleToMock) {
for (const declaration of flatten(itsModuleToMock)) {
instance.mock(declaration, declaration, {
export: true,
exportAll: true,
});
}
}
return instance;
}
function mockBuilderExtend<K extends keyof IMockBuilderExtended & string>(
func: K,
callback?: (builder: IMockBuilderExtended, parameters: never) => void,
): void {
const extensions: Map<string, typeof callback> = ngMocksUniverse.config.get('MockBuilderExtensions') ?? new Map();
if (callback) {
extensions.set(func, callback);
ngMocksUniverse.config.set('MockBuilderExtensions', extensions);
} else {
extensions.delete(func);
}
}
// istanbul ignore next: issue in istanbul https://github.com/istanbuljs/nyc/issues/1209
export namespace MockBuilder {
/**
* Adds a custom function to MockBuilder
*/
export function extend<K extends keyof IMockBuilderExtended & string>(
func: K,
callback: (builder: IMockBuilderExtended, parameters: never) => void,
): void;
/**
* Removes a custom function from MockBuilder
*/
export function extend<K extends keyof IMockBuilderExtended & string>(func: K): void;
export function extend<K extends keyof IMockBuilderExtended & string>(
func: K,
callback?: (builder: IMockBuilderExtended, parameters: never) => void,
): void {
mockBuilderExtend(func, callback);
}
}