diff --git a/README.md b/README.md index 23dd9c99e1..a925c5fbb9 100644 --- a/README.md +++ b/README.md @@ -2501,10 +2501,11 @@ describe('MockInstance', () => { - [`.guts()`](#ngmocksguts) - [`.defaultMock()`](#ngmocksdefaultmock) -- [`.defaultExclude()`](#ngmocksdefaultexclude) -- [`.defaultKeep()`](#ngmocksdefaultkeep) -- [`.defaultReplace()`](#ngmocksdefaultreplace) -- [`.defaultWipe()`](#ngmocksdefaultwipe) +- [`.globalExclude()`](#ngmocksglobalexclude) +- [`.globalKeep()`](#ngmocksglobalkeep) +- [`.globalMock()`](#ngmocksglobalmock) +- [`.globalReplace()`](#ngmocksglobalreplace) +- [`.globalWipe()`](#ngmocksglobalwipe) - [`.get()`](#ngmocksget) - [`.findInstance()`](#ngmocksfindinstance) - [`.findInstances()`](#ngmocksfindinstances) @@ -2602,9 +2603,9 @@ ngMocks.defaultMock(MyComponent, (_, injector) => ({ ngMocks.defaultMock(MyComponent); ``` -#### ngMocks.defaultExclude +#### ngMocks.globalExclude -`ngMocks.defaultExclude` marks declarations, services and tokens to be excluded during creating mock modules. +`ngMocks.globalExclude` marks declarations, services and tokens to be excluded during creating mock modules. The best place to do that is in `src/test.ts` for jasmine or in `src/setupJest.ts` for jest. @@ -2619,7 +2620,7 @@ If we import a module that imports `TranslationModule` in tests, then this effect of `initTestEnvironment` will be overloaded. To keep the effect, we need to exclude `TranslationModule` during the mocking process. -That is where `ngMocks.defaultExclude` comes for help. +That is where `ngMocks.globalExclude` comes for help. ```ts // test.ts @@ -2634,16 +2635,16 @@ getTestBed().initTestEnvironment( platformBrowserDynamicTesting(), ); -ngMocks.defaultExclude(TranslationModule); +ngMocks.globalExclude(TranslationModule); ``` Now, if we call `MockModule(ModuleWithTranslationModule)`, the `TranslationModule` will be excluded out of the final mock module, and, consequently, the version from `initTestEnvironment` will be used. -#### ngMocks.defaultKeep +#### ngMocks.globalKeep -`ngMocks.defaultExclude` marks declarations, services and tokens to be avoided from the mocking process during creating mock modules. +`ngMocks.globalExclude` marks declarations, services and tokens to be avoided from the mocking process during creating mock modules. The best place to do that is in `src/test.ts` for jasmine or in `src/setupJest.ts` for jest. @@ -2651,7 +2652,7 @@ Let's mark the `APP_URL` token in order to be kept in mock modules. ```ts // test.ts -ngMocks.defaultKeep(APP_URL); +ngMocks.globalKeep(APP_URL); ``` ```ts @@ -2665,9 +2666,35 @@ const url = TestBed.inject(APP_URL); The `url` is the original one. -#### ngMocks.defaultReplace +#### ngMocks.globalMock -`ngMocks.defaultReplace` marks declarations and modules (but not services and tokens) to be replaced during creating mock modules. +`ngMocks.globalMock` marks declarations, services and tokens to be mocked if they are appearing in kept modules during creating mock modules. + +The best place to do that is in `src/test.ts` for jasmine or in `src/setupJest.ts` for jest. + +Let's mark the `APP_URL` token in order to be mocked in its kept modules. + +```ts +// test.ts +ngMocks.globalKeep(AppModule); +ngMocks.globalMock(APP_URL); +ngMocks.defaultMock(APP_URL, () => 'mock'); +``` + +```ts +// test.spec.ts +// ... +MockModule(AppModule); +// ... +const url = TestBed.inject(APP_URL); +// ... +``` + +The `url` is `mock`. + +#### ngMocks.globalReplace + +`ngMocks.globalReplace` marks declarations and modules (but not services and tokens) to be replaced during creating mock modules. The best place to do that is in `src/test.ts` for jasmine or in `src/setupJest.ts` for jest. @@ -2676,27 +2703,27 @@ we could do it like that: ```ts // test.ts -ngMocks.defaultReplace(BrowserAnimationsModule, NoopAnimationsModule); +ngMocks.globalReplace(BrowserAnimationsModule, NoopAnimationsModule); ``` Now, all mock modules which import `BrowserAnimationsModule` have `NoopAnimationsModule` instead. -#### ngMocks.defaultWipe +#### ngMocks.globalWipe -`ngMocks.defaultWipe` resets all customizations which have been done by any `ngMocks.default` function. +`ngMocks.globalWipe` resets all customizations which have been done by any `ngMocks.default` function. ```ts ngMocks.defaultMock(Service, () => ({ stream$: EMPTY, })); -ngMocks.defaultExclude(Component); -ngMocks.defaultKeep(Directive); -ngMocks.defaultReplace(Pipe, FakePipe); - -ngMocks.defaultWipe(Service); -ngMocks.defaultWipe(Component); -ngMocks.defaultWipe(Directive); -ngMocks.defaultWipe(Pipe); +ngMocks.globalExclude(Component); +ngMocks.globalKeep(Directive); +ngMocks.globalReplace(Pipe, FakePipe); + +ngMocks.globalWipe(Service); +ngMocks.globalWipe(Component); +ngMocks.globalWipe(Directive); +ngMocks.globalWipe(Pipe); // All the things above will be mocked as usual ``` diff --git a/lib/common/ng-mocks-universe.ts b/lib/common/ng-mocks-universe.ts index a91dfa1ada..18075059b2 100644 --- a/lib/common/ng-mocks-universe.ts +++ b/lib/common/ng-mocks-universe.ts @@ -23,7 +23,7 @@ interface NgMocksUniverse { configInstance: Map; flags: Set; getBuildDeclaration: (def: any) => any | undefined; - getDefaults: () => Map; + getDefaults: () => Map; getLocalMocks: () => Array<[any, any]>; getOverrides: () => Map; getResolution: (def: any) => undefined | 'mock' | 'keep' | 'replace' | 'exclude'; @@ -58,7 +58,7 @@ ngMocksUniverse.getLocalMocks = () => { ngMocksUniverse.getOverrides = globalMap('overrides'); ngMocksUniverse.getDefaults = globalMap('defaults'); -ngMocksUniverse.getResolution = (def: any) => { +ngMocksUniverse.getResolution = (def: any): undefined | 'mock' | 'keep' | 'replace' | 'exclude' => { const set = ngMocksUniverse.config.get('ngMocksDepsResolution'); if (set?.has(def)) { return set.get(def); @@ -68,35 +68,43 @@ ngMocksUniverse.getResolution = (def: any) => { return undefined; } - const value = ngMocksUniverse.getDefaults().get(def); - if (!value) { - return 'exclude'; - } - if (def === value) { - return 'keep'; - } + const [value] = ngMocksUniverse.getDefaults().get(def); - return 'replace'; + return value; }; -ngMocksUniverse.getBuildDeclaration = (def: any) => { +ngMocksUniverse.getBuildDeclaration = (def: any): undefined | null | any => { if (ngMocksUniverse.builtDeclarations.has(def)) { return ngMocksUniverse.builtDeclarations.get(def); } - if (ngMocksUniverse.getDefaults().has(def)) { - return ngMocksUniverse.getDefaults().get(def); + if (!ngMocksUniverse.getDefaults().has(def)) { + return; + } + + const [mode, replacement] = ngMocksUniverse.getDefaults().get(def); + + if (mode === 'exclude') { + return null; + } + if (mode === 'keep') { + return def; + } + if (mode === 'replace') { + return replacement; } }; -ngMocksUniverse.hasBuildDeclaration = (def: any) => { +ngMocksUniverse.hasBuildDeclaration = (def: any): boolean => { if (ngMocksUniverse.builtDeclarations.has(def)) { return true; } - if (ngMocksUniverse.getDefaults().has(def)) { - return true; + if (!ngMocksUniverse.getDefaults().has(def)) { + return false; } - return false; + const [mode] = ngMocksUniverse.getDefaults().get(def); + + return mode !== 'mock'; }; const hasBuildDeclaration = (def: any): boolean => ngMocksUniverse.hasBuildDeclaration(def); diff --git a/lib/mock-helper/func.global-prepare.ts b/lib/mock-helper/func.global-prepare.ts new file mode 100644 index 0000000000..37b33a8f11 --- /dev/null +++ b/lib/mock-helper/func.global-prepare.ts @@ -0,0 +1,6 @@ +import ngMocksUniverse from '../common/ng-mocks-universe'; + +export default () => { + ngMocksUniverse.cacheDeclarations.clear(); + ngMocksUniverse.config.get('ngMocksDepsSkip')?.clear(); +}; diff --git a/lib/mock-helper/mock-helper.default-exclude.spec.ts b/lib/mock-helper/mock-helper.global-exclude.spec.ts similarity index 82% rename from lib/mock-helper/mock-helper.default-exclude.spec.ts rename to lib/mock-helper/mock-helper.global-exclude.spec.ts index 74b7a3dfa7..2c762b7e41 100644 --- a/lib/mock-helper/mock-helper.default-exclude.spec.ts +++ b/lib/mock-helper/mock-helper.global-exclude.spec.ts @@ -2,7 +2,7 @@ import { Component } from '@angular/core'; import ngMocksUniverse from '../common/ng-mocks-universe'; -import mockHelperDefaultExclude from './mock-helper.default-exclude'; +import mockHelperGlobalExclude from './mock-helper.global-exclude'; @Component({ selector: 'target', @@ -19,7 +19,7 @@ describe('mock-helper.default-exclude', () => { it('resets cacheDeclarations', () => { ngMocksUniverse.cacheDeclarations.set(TargetComponent, null); - mockHelperDefaultExclude(TargetComponent); + mockHelperGlobalExclude(TargetComponent); expect(ngMocksUniverse.cacheDeclarations.size).toEqual(0); }); @@ -27,7 +27,7 @@ describe('mock-helper.default-exclude', () => { const config = new Set(); config.add(TargetComponent); ngMocksUniverse.config.set('ngMocksDepsSkip', config); - mockHelperDefaultExclude(TargetComponent); + mockHelperGlobalExclude(TargetComponent); expect( ngMocksUniverse.config.get('ngMocksDepsSkip').size, ).toEqual(0); diff --git a/lib/mock-helper/mock-helper.default-exclude.ts b/lib/mock-helper/mock-helper.global-exclude.ts similarity index 60% rename from lib/mock-helper/mock-helper.default-exclude.ts rename to lib/mock-helper/mock-helper.global-exclude.ts index c1c5f28c08..8f75b2206f 100644 --- a/lib/mock-helper/mock-helper.default-exclude.ts +++ b/lib/mock-helper/mock-helper.global-exclude.ts @@ -3,8 +3,9 @@ import { InjectionToken } from '@angular/core'; import { AnyType } from '../common/core.types'; import ngMocksUniverse from '../common/ng-mocks-universe'; +import funcGlobalPrepare from './func.global-prepare'; + export default (source: AnyType | InjectionToken): void => { - ngMocksUniverse.cacheDeclarations.clear(); - ngMocksUniverse.config.get('ngMocksDepsSkip')?.clear(); - ngMocksUniverse.getDefaults().set(source, null); + funcGlobalPrepare(); + ngMocksUniverse.getDefaults().set(source, ['exclude']); }; diff --git a/lib/mock-helper/mock-helper.default-keep.spec.ts b/lib/mock-helper/mock-helper.global-keep.spec.ts similarity index 83% rename from lib/mock-helper/mock-helper.default-keep.spec.ts rename to lib/mock-helper/mock-helper.global-keep.spec.ts index 73d83fc780..faf57cf7f5 100644 --- a/lib/mock-helper/mock-helper.default-keep.spec.ts +++ b/lib/mock-helper/mock-helper.global-keep.spec.ts @@ -2,7 +2,7 @@ import { Component } from '@angular/core'; import ngMocksUniverse from '../common/ng-mocks-universe'; -import mockHelperDefaultKeep from './mock-helper.default-keep'; +import mockHelperGlobalKeep from './mock-helper.global-keep'; @Component({ selector: 'target', @@ -19,7 +19,7 @@ describe('mock-helper.default-keep', () => { it('resets cacheDeclarations', () => { ngMocksUniverse.cacheDeclarations.set(TargetComponent, null); - mockHelperDefaultKeep(TargetComponent); + mockHelperGlobalKeep(TargetComponent); expect(ngMocksUniverse.cacheDeclarations.size).toEqual(0); }); @@ -27,7 +27,7 @@ describe('mock-helper.default-keep', () => { const config = new Set(); config.add(TargetComponent); ngMocksUniverse.config.set('ngMocksDepsSkip', config); - mockHelperDefaultKeep(TargetComponent); + mockHelperGlobalKeep(TargetComponent); expect( ngMocksUniverse.config.get('ngMocksDepsSkip').size, ).toEqual(0); diff --git a/lib/mock-helper/mock-helper.default-keep.ts b/lib/mock-helper/mock-helper.global-keep.ts similarity index 59% rename from lib/mock-helper/mock-helper.default-keep.ts rename to lib/mock-helper/mock-helper.global-keep.ts index 5dee3d88bd..43e555f1fa 100644 --- a/lib/mock-helper/mock-helper.default-keep.ts +++ b/lib/mock-helper/mock-helper.global-keep.ts @@ -3,8 +3,9 @@ import { InjectionToken } from '@angular/core'; import { AnyType } from '../common/core.types'; import ngMocksUniverse from '../common/ng-mocks-universe'; +import funcGlobalPrepare from './func.global-prepare'; + export default (source: AnyType | InjectionToken): void => { - ngMocksUniverse.cacheDeclarations.clear(); - ngMocksUniverse.config.get('ngMocksDepsSkip')?.clear(); - ngMocksUniverse.getDefaults().set(source, source); + funcGlobalPrepare(); + ngMocksUniverse.getDefaults().set(source, ['keep']); }; diff --git a/lib/mock-helper/mock-helper.global-mock.spec.ts b/lib/mock-helper/mock-helper.global-mock.spec.ts new file mode 100644 index 0000000000..1a7530546e --- /dev/null +++ b/lib/mock-helper/mock-helper.global-mock.spec.ts @@ -0,0 +1,35 @@ +import { Component } from '@angular/core'; + +import ngMocksUniverse from '../common/ng-mocks-universe'; + +import mockHelperGlobalMock from './mock-helper.global-mock'; + +@Component({ + selector: 'target', + template: '{{ name }}', +}) +class TargetComponent { + public readonly name = 'target'; +} + +describe('mock-helper.default-mock', () => { + afterAll(() => { + ngMocksUniverse.config.delete('ngMocksDepsSkip'); + }); + + it('resets cacheDeclarations', () => { + ngMocksUniverse.cacheDeclarations.set(TargetComponent, null); + mockHelperGlobalMock(TargetComponent); + expect(ngMocksUniverse.cacheDeclarations.size).toEqual(0); + }); + + it('resets ngMocksDepsSkip', () => { + const config = new Set(); + config.add(TargetComponent); + ngMocksUniverse.config.set('ngMocksDepsSkip', config); + mockHelperGlobalMock(TargetComponent); + expect( + ngMocksUniverse.config.get('ngMocksDepsSkip').size, + ).toEqual(0); + }); +}); diff --git a/lib/mock-helper/mock-helper.global-mock.ts b/lib/mock-helper/mock-helper.global-mock.ts new file mode 100644 index 0000000000..36c0980305 --- /dev/null +++ b/lib/mock-helper/mock-helper.global-mock.ts @@ -0,0 +1,11 @@ +import { InjectionToken } from '@angular/core'; + +import { AnyType } from '../common/core.types'; +import ngMocksUniverse from '../common/ng-mocks-universe'; + +import funcGlobalPrepare from './func.global-prepare'; + +export default (source: AnyType | InjectionToken): void => { + funcGlobalPrepare(); + ngMocksUniverse.getDefaults().set(source, ['mock']); +}; diff --git a/lib/mock-helper/mock-helper.default-replace.spec.ts b/lib/mock-helper/mock-helper.global-replace.spec.ts similarity index 82% rename from lib/mock-helper/mock-helper.default-replace.spec.ts rename to lib/mock-helper/mock-helper.global-replace.spec.ts index c6fd48fb94..ed18acedb6 100644 --- a/lib/mock-helper/mock-helper.default-replace.spec.ts +++ b/lib/mock-helper/mock-helper.global-replace.spec.ts @@ -2,7 +2,7 @@ import { Component } from '@angular/core'; import ngMocksUniverse from '../common/ng-mocks-universe'; -import mockHelperDefaultReplace from './mock-helper.default-replace'; +import mockHelperGlobalReplace from './mock-helper.global-replace'; @Component({ selector: 'target', @@ -27,7 +27,7 @@ describe('mock-helper.default-replace', () => { it('resets cacheDeclarations', () => { ngMocksUniverse.cacheDeclarations.set(TargetComponent, null); - mockHelperDefaultReplace(TargetComponent, FakeComponent); + mockHelperGlobalReplace(TargetComponent, FakeComponent); expect(ngMocksUniverse.cacheDeclarations.size).toEqual(0); }); @@ -35,7 +35,7 @@ describe('mock-helper.default-replace', () => { const config = new Set(); config.add(TargetComponent); ngMocksUniverse.config.set('ngMocksDepsSkip', config); - mockHelperDefaultReplace(TargetComponent, FakeComponent); + mockHelperGlobalReplace(TargetComponent, FakeComponent); expect( ngMocksUniverse.config.get('ngMocksDepsSkip').size, ).toEqual(0); diff --git a/lib/mock-helper/mock-helper.default-replace.ts b/lib/mock-helper/mock-helper.global-replace.ts similarity index 81% rename from lib/mock-helper/mock-helper.default-replace.ts rename to lib/mock-helper/mock-helper.global-replace.ts index 747c586563..a38c46ff86 100644 --- a/lib/mock-helper/mock-helper.default-replace.ts +++ b/lib/mock-helper/mock-helper.global-replace.ts @@ -2,6 +2,8 @@ import { AnyType } from '../common/core.types'; import { isNgDef } from '../common/func.is-ng-def'; import ngMocksUniverse from '../common/ng-mocks-universe'; +import funcGlobalPrepare from './func.global-prepare'; + export default (source: AnyType, destination: AnyType): void => { let fail = true; if (isNgDef(source, 'm') && isNgDef(destination, 'm')) { @@ -18,7 +20,6 @@ export default (source: AnyType, destination: AnyType): void => { throw new Error('Cannot replace the declaration, both have to be a Module, a Component, a Directive or a Pipe'); } - ngMocksUniverse.cacheDeclarations.clear(); - ngMocksUniverse.config.get('ngMocksDepsSkip')?.clear(); - ngMocksUniverse.getDefaults().set(source, destination); + funcGlobalPrepare(); + ngMocksUniverse.getDefaults().set(source, ['replace', destination]); }; diff --git a/lib/mock-helper/mock-helper.default-wipe.spec.ts b/lib/mock-helper/mock-helper.global-wipe.spec.ts similarity index 83% rename from lib/mock-helper/mock-helper.default-wipe.spec.ts rename to lib/mock-helper/mock-helper.global-wipe.spec.ts index fa208b5f2c..bc4d1d77d8 100644 --- a/lib/mock-helper/mock-helper.default-wipe.spec.ts +++ b/lib/mock-helper/mock-helper.global-wipe.spec.ts @@ -2,7 +2,7 @@ import { Component } from '@angular/core'; import ngMocksUniverse from '../common/ng-mocks-universe'; -import mockHelperDefaultWipe from './mock-helper.default-wipe'; +import mockHelperGlobalWipe from './mock-helper.global-wipe'; @Component({ selector: 'target', @@ -19,7 +19,7 @@ describe('mock-helper.default-wipe', () => { it('resets cacheDeclarations', () => { ngMocksUniverse.cacheDeclarations.set(TargetComponent, null); - mockHelperDefaultWipe(TargetComponent); + mockHelperGlobalWipe(TargetComponent); expect(ngMocksUniverse.cacheDeclarations.size).toEqual(0); }); @@ -27,7 +27,7 @@ describe('mock-helper.default-wipe', () => { const config = new Set(); config.add(TargetComponent); ngMocksUniverse.config.set('ngMocksDepsSkip', config); - mockHelperDefaultWipe(TargetComponent); + mockHelperGlobalWipe(TargetComponent); expect( ngMocksUniverse.config.get('ngMocksDepsSkip').size, ).toEqual(0); diff --git a/lib/mock-helper/mock-helper.default-wipe.ts b/lib/mock-helper/mock-helper.global-wipe.ts similarity index 78% rename from lib/mock-helper/mock-helper.default-wipe.ts rename to lib/mock-helper/mock-helper.global-wipe.ts index 2a17da92c4..5a6abc1f96 100644 --- a/lib/mock-helper/mock-helper.default-wipe.ts +++ b/lib/mock-helper/mock-helper.global-wipe.ts @@ -3,11 +3,11 @@ import { InjectionToken } from '@angular/core'; import { AnyType } from '../common/core.types'; import ngMocksUniverse from '../common/ng-mocks-universe'; +import funcGlobalPrepare from './func.global-prepare'; import mockHelperDefaultMock from './mock-helper.default-mock'; export default (source: AnyType | InjectionToken): void => { - ngMocksUniverse.cacheDeclarations.clear(); - ngMocksUniverse.config.get('ngMocksDepsSkip')?.clear(); + funcGlobalPrepare(); ngMocksUniverse.getDefaults().delete(source); mockHelperDefaultMock(source); }; diff --git a/lib/mock-helper/mock-helper.guts.ts b/lib/mock-helper/mock-helper.guts.ts index 63651e8ce5..31023bfb15 100644 --- a/lib/mock-helper/mock-helper.guts.ts +++ b/lib/mock-helper/mock-helper.guts.ts @@ -1,6 +1,6 @@ import { TestModuleMetadata } from '@angular/core/testing'; -import { flatten, mapEntries, mapValues } from '../common/core.helpers'; +import { flatten, mapKeys, mapValues } from '../common/core.helpers'; import coreReflectModuleResolve from '../common/core.reflect.module-resolve'; import funcGetProvider from '../common/func.get-provider'; import { isNgDef } from '../common/func.is-ng-def'; @@ -178,7 +178,8 @@ const resolve = (data: Data, proto: any, skipDestruction = true): void => { }; const generateDataWithUniverse = (keep: Set, mock: Set, exclude: Set, optional: Map): void => { - for (const [k, v] of mapEntries(ngMocksUniverse.getDefaults())) { + for (const k of mapKeys(ngMocksUniverse.getDefaults())) { + const v = ngMocksUniverse.getBuildDeclaration(k); if (keep.has(k) || mock.has(k) || exclude.has(k)) { continue; } @@ -186,6 +187,8 @@ const generateDataWithUniverse = (keep: Set, mock: Set, exclude: Set { const data: Data = generateData(keep, mock, exclude); + ngMocksUniverse.config.set('mockNgDefResolver', new Map()); for (const def of mapValues(data.mock)) { + if (data.optional.has(def)) { + continue; + } resolve(data, def, false); } + const meta = createMeta(data); + ngMocksUniverse.config.delete('mockNgDefResolver'); - return createMeta(data); + return meta; }; diff --git a/lib/mock-helper/mock-helper.ts b/lib/mock-helper/mock-helper.ts index 80185e3057..47062a52d0 100644 --- a/lib/mock-helper/mock-helper.ts +++ b/lib/mock-helper/mock-helper.ts @@ -9,11 +9,7 @@ import { MockedDebugElement, MockedDebugNode } from '../mock-render/types'; import { CustomMockFunction, MockedFunction } from '../mock-service/types'; import mockHelperAutoSpy from './mock-helper.auto-spy'; -import mockHelperDefaultExclude from './mock-helper.default-exclude'; -import mockHelperDefaultKeep from './mock-helper.default-keep'; import mockHelperDefaultMock from './mock-helper.default-mock'; -import mockHelperDefaultReplace from './mock-helper.default-replace'; -import mockHelperDefaultWipe from './mock-helper.default-wipe'; import mockHelperFaster from './mock-helper.faster'; import mockHelperFind from './mock-helper.find'; import mockHelperFindAll from './mock-helper.find-all'; @@ -21,6 +17,11 @@ import mockHelperFindInstance from './mock-helper.find-instance'; import mockHelperFindInstances from './mock-helper.find-instances'; import mockHelperFlushTestBed from './mock-helper.flush-test-bed'; import mockHelperGet from './mock-helper.get'; +import mockHelperGlobalExclude from './mock-helper.global-exclude'; +import mockHelperGlobalKeep from './mock-helper.global-keep'; +import mockHelperGlobalMock from './mock-helper.global-mock'; +import mockHelperGlobalReplace from './mock-helper.global-replace'; +import mockHelperGlobalWipe from './mock-helper.global-wipe'; import mockHelperGuts from './mock-helper.guts'; import mockHelperInput from './mock-helper.input'; import mockHelperOutput from './mock-helper.output'; @@ -43,16 +44,6 @@ export const ngMocks: { */ autoSpy(type: CustomMockFunction): void; - /** - * @see https://github.com/ike18t/ng-mocks#ngmocksdefaultexclude - */ - defaultExclude(source: AnyType | InjectionToken): void; - - /** - * @see https://github.com/ike18t/ng-mocks#ngmocksdefaultkeep - */ - defaultKeep(source: AnyType | InjectionToken): void; - /** * @see https://github.com/ike18t/ng-mocks#ngmocksdefaultmock */ @@ -74,16 +65,6 @@ export const ngMocks: { */ defaultMock(def: AnyType, handler?: (value: T, injector: Injector) => void | Partial): void; - /** - * @see https://github.com/ike18t/ng-mocks#ngmocksdefaultreplace - */ - defaultReplace(source: AnyType, destination: AnyType): void; - - /** - * @see https://github.com/ike18t/ng-mocks#ngmocksdefaultwipe - */ - defaultWipe(source: AnyType | InjectionToken): void; - /** * @see https://github.com/ike18t/ng-mocks#making-angular-tests-faster */ @@ -212,6 +193,31 @@ export const ngMocks: { */ get(debugNode: MockedDebugNode, directive: Type, notFoundValue: D): D | T; + /** + * @see https://github.com/ike18t/ng-mocks#ngmocksglobalexclude + */ + globalExclude(source: AnyType | InjectionToken): void; + + /** + * @see https://github.com/ike18t/ng-mocks#ngmocksglobalkeep + */ + globalKeep(source: AnyType | InjectionToken): void; + + /** + * @see https://github.com/ike18t/ng-mocks#ngmocksglobalmock + */ + globalMock(source: AnyType | InjectionToken): void; + + /** + * @see https://github.com/ike18t/ng-mocks#ngmocksglobalreplace + */ + globalReplace(source: AnyType, destination: AnyType): void; + + /** + * @see https://github.com/ike18t/ng-mocks#ngmocksglobalwipe + */ + globalWipe(source: AnyType | InjectionToken): void; + /** * @see https://github.com/ike18t/ng-mocks#ngmocksguts */ @@ -302,11 +308,7 @@ export const ngMocks: { throwOnConsole(): void; } = { autoSpy: mockHelperAutoSpy, - defaultExclude: mockHelperDefaultExclude, - defaultKeep: mockHelperDefaultKeep, defaultMock: mockHelperDefaultMock, - defaultReplace: mockHelperDefaultReplace, - defaultWipe: mockHelperDefaultWipe, faster: mockHelperFaster, find: mockHelperFind, findAll: mockHelperFindAll, @@ -314,6 +316,11 @@ export const ngMocks: { findInstances: mockHelperFindInstances, flushTestBed: mockHelperFlushTestBed, get: mockHelperGet, + globalExclude: mockHelperGlobalExclude, + globalKeep: mockHelperGlobalKeep, + globalMock: mockHelperGlobalMock, + globalReplace: mockHelperGlobalReplace, + globalWipe: mockHelperGlobalWipe, guts: mockHelperGuts, input: mockHelperInput, output: mockHelperOutput, diff --git a/lib/mock-module/mock-ng-def.ts b/lib/mock-module/mock-ng-def.ts index 3f515fdde2..d147b44d24 100644 --- a/lib/mock-module/mock-ng-def.ts +++ b/lib/mock-module/mock-ng-def.ts @@ -25,7 +25,7 @@ const processDef = (def: any) => { if (ngMocksUniverse.hasBuildDeclaration(def)) { return ngMocksUniverse.getBuildDeclaration(def); } - if (ngMocksUniverse.flags.has('skipMock')) { + if (ngMocksUniverse.flags.has('skipMock') && ngMocksUniverse.getResolution(def) !== 'mock') { return def; } for (const [flag, func] of processDefMap) { diff --git a/lib/mock-service/helper.resolve-provider.ts b/lib/mock-service/helper.resolve-provider.ts index 1dde74095e..130dac4d03 100644 --- a/lib/mock-service/helper.resolve-provider.ts +++ b/lib/mock-service/helper.resolve-provider.ts @@ -118,7 +118,7 @@ const createPredefinedMockProvider = (provider: any, provide: any): any => { const createMockProvider = (provider: any, provide: any, change: () => void) => { let mockDef = createPredefinedMockProvider(provider, provide); - if (!mockDef && ngMocksUniverse.flags.has('skipMock')) { + if (!mockDef && ngMocksUniverse.flags.has('skipMock') && ngMocksUniverse.getResolution(provide) !== 'mock') { ngMocksUniverse.config.get('ngMocksDepsSkip')?.add(provide); mockDef = provider; } diff --git a/tests/ng-mocks-default-exclude-modules/fixtures.ts b/tests/ng-mocks-global-exclude-modules/fixtures.ts similarity index 100% rename from tests/ng-mocks-default-exclude-modules/fixtures.ts rename to tests/ng-mocks-global-exclude-modules/fixtures.ts diff --git a/tests/ng-mocks-default-exclude-modules/test.spec.ts b/tests/ng-mocks-global-exclude-modules/test.spec.ts similarity index 85% rename from tests/ng-mocks-default-exclude-modules/test.spec.ts rename to tests/ng-mocks-global-exclude-modules/test.spec.ts index 23cf137309..4d0bb01d4f 100644 --- a/tests/ng-mocks-default-exclude-modules/test.spec.ts +++ b/tests/ng-mocks-global-exclude-modules/test.spec.ts @@ -3,10 +3,10 @@ import { MockModule, MockRender, ngMocks } from 'ng-mocks'; import { Target1Module } from './fixtures'; -ngMocks.defaultExclude(Target1Module); +ngMocks.globalExclude(Target1Module); // The root module we pass into MockModule isn't excluded despite the setting. -describe('ng-mocks-default-exclude-modules', () => { +describe('ng-mocks-global-exclude-modules', () => { beforeEach(() => { return TestBed.configureTestingModule({ imports: [MockModule(Target1Module)], diff --git a/tests/ng-mocks-default-exclude/test.override.spec.ts b/tests/ng-mocks-global-exclude/test.override.spec.ts similarity index 86% rename from tests/ng-mocks-default-exclude/test.override.spec.ts rename to tests/ng-mocks-global-exclude/test.override.spec.ts index d986dae62e..8ceccec421 100644 --- a/tests/ng-mocks-default-exclude/test.override.spec.ts +++ b/tests/ng-mocks-global-exclude/test.override.spec.ts @@ -24,17 +24,17 @@ class Target2Component { }) class TargetModule {} -describe('ng-mocks-default-exclude:override', () => { +describe('ng-mocks-global-exclude:override', () => { ngMocks.throwOnConsole(); afterAll(() => { - ngMocks.defaultWipe(Target1Component); - ngMocks.defaultWipe(Target2Component); + ngMocks.globalWipe(Target1Component); + ngMocks.globalWipe(Target2Component); }); describe('excluding Target1Component', () => { beforeEach(async () => { - ngMocks.defaultExclude(Target1Component); + ngMocks.globalExclude(Target1Component); return TestBed.configureTestingModule({ imports: [MockModule(TargetModule)], @@ -51,7 +51,7 @@ describe('ng-mocks-default-exclude:override', () => { describe('excluding Target2Component', () => { beforeEach(async () => { - ngMocks.defaultExclude(Target2Component); + ngMocks.globalExclude(Target2Component); return TestBed.configureTestingModule({ imports: [MockModule(TargetModule)], diff --git a/tests/ng-mocks-default-exclude/test.spec.ts b/tests/ng-mocks-global-exclude/test.spec.ts similarity index 97% rename from tests/ng-mocks-default-exclude/test.spec.ts rename to tests/ng-mocks-global-exclude/test.spec.ts index 84b399e92f..8d0157e522 100644 --- a/tests/ng-mocks-default-exclude/test.spec.ts +++ b/tests/ng-mocks-global-exclude/test.spec.ts @@ -30,9 +30,9 @@ class FakeComponent { }) class TargetModule {} -ngMocks.defaultExclude(TargetComponent); +ngMocks.globalExclude(TargetComponent); -describe('ng-mocks-default-exclude', () => { +describe('ng-mocks-global-exclude', () => { ngMocks.throwOnConsole(); describe('MockComponent', () => { diff --git a/tests/ng-mocks-default-keep-modules/fixtures.ts b/tests/ng-mocks-global-keep-modules/fixtures.ts similarity index 100% rename from tests/ng-mocks-default-keep-modules/fixtures.ts rename to tests/ng-mocks-global-keep-modules/fixtures.ts diff --git a/tests/ng-mocks-default-keep-modules/test.spec.ts b/tests/ng-mocks-global-keep-modules/test.spec.ts similarity index 82% rename from tests/ng-mocks-default-keep-modules/test.spec.ts rename to tests/ng-mocks-global-keep-modules/test.spec.ts index 7aba476dbb..8c5cfaa9d0 100644 --- a/tests/ng-mocks-default-keep-modules/test.spec.ts +++ b/tests/ng-mocks-global-keep-modules/test.spec.ts @@ -9,11 +9,11 @@ import { Target3Module, } from './fixtures'; -ngMocks.defaultExclude(Target2Component); -ngMocks.defaultKeep(Target2Module); -ngMocks.defaultReplace(Target1Component, Fake1Component); +ngMocks.globalExclude(Target2Component); +ngMocks.globalKeep(Target2Module); +ngMocks.globalReplace(Target1Component, Fake1Component); -describe('ng-mocks-default-keep-modules', () => { +describe('ng-mocks-global-keep-modules', () => { ngMocks.throwOnConsole(); beforeEach(() => { diff --git a/tests/ng-mocks-default-keep/test.override.spec.ts b/tests/ng-mocks-global-keep/test.override.spec.ts similarity index 87% rename from tests/ng-mocks-default-keep/test.override.spec.ts rename to tests/ng-mocks-global-keep/test.override.spec.ts index f1de768730..f09b8250c8 100644 --- a/tests/ng-mocks-default-keep/test.override.spec.ts +++ b/tests/ng-mocks-global-keep/test.override.spec.ts @@ -24,15 +24,15 @@ class Target2Component { }) class TargetModule {} -describe('ng-mocks-default-keep:override', () => { +describe('ng-mocks-global-keep:override', () => { afterAll(() => { - ngMocks.defaultWipe(Target1Component); - ngMocks.defaultWipe(Target2Component); + ngMocks.globalWipe(Target1Component); + ngMocks.globalWipe(Target2Component); }); describe('keeping Target1Component', () => { beforeEach(async () => { - ngMocks.defaultKeep(Target1Component); + ngMocks.globalKeep(Target1Component); return TestBed.configureTestingModule({ imports: [MockModule(TargetModule)], @@ -51,7 +51,7 @@ describe('ng-mocks-default-keep:override', () => { describe('keeping Target2Component', () => { beforeEach(async () => { - ngMocks.defaultKeep(Target2Component); + ngMocks.globalKeep(Target2Component); return TestBed.configureTestingModule({ imports: [MockModule(TargetModule)], diff --git a/tests/ng-mocks-default-keep/test.spec.ts b/tests/ng-mocks-global-keep/test.spec.ts similarity index 97% rename from tests/ng-mocks-default-keep/test.spec.ts rename to tests/ng-mocks-global-keep/test.spec.ts index 0032d87a37..0681e89b18 100644 --- a/tests/ng-mocks-default-keep/test.spec.ts +++ b/tests/ng-mocks-global-keep/test.spec.ts @@ -30,9 +30,9 @@ class FakeComponent { }) class TargetModule {} -ngMocks.defaultKeep(TargetComponent); +ngMocks.globalKeep(TargetComponent); -describe('ng-mocks-default-keep', () => { +describe('ng-mocks-global-keep', () => { ngMocks.throwOnConsole(); describe('MockComponent', () => { diff --git a/tests/ng-mocks-global-mock/test.spec.ts b/tests/ng-mocks-global-mock/test.spec.ts new file mode 100644 index 0000000000..cabb5477a5 --- /dev/null +++ b/tests/ng-mocks-global-mock/test.spec.ts @@ -0,0 +1,145 @@ +import { + Directive, + Inject, + Injectable, + InjectionToken, + NgModule, +} from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import { + isMockOf, + MockBuilder, + MockModule, + MockRender, + ngMocks, +} from 'ng-mocks'; + +const TOKEN = new InjectionToken('TOKEN'); + +@Injectable() +class TargetService { + public readonly name = 'target'; + + public constructor(@Inject(TOKEN) public token: string) {} +} + +@Directive({ + selector: 'target', +}) +class TargetDirective { + public constructor(public readonly service: TargetService) {} +} + +@Directive({ + selector: 'target', +}) +class MockDirective { + public constructor(public readonly service: TargetService) {} +} + +@NgModule({ + declarations: [TargetDirective, MockDirective], + exports: [TargetDirective, MockDirective], + providers: [ + TargetService, + { + provide: TOKEN, + useValue: 'target', + }, + ], +}) +class TargetModule {} + +@NgModule({ + exports: [TargetModule], + imports: [TargetModule], +}) +class EntryModule {} + +ngMocks.globalKeep(TargetModule); +ngMocks.globalMock(TOKEN); +ngMocks.globalMock(MockDirective); +ngMocks.defaultMock(TOKEN, () => 'mock'); + +describe('ng-mocks-global-mock', () => { + ngMocks.throwOnConsole(); + + describe('MockModule', () => { + beforeEach(() => + TestBed.configureTestingModule({ + imports: [MockModule(EntryModule)], + }), + ); + + it('get real service with a mock token', () => { + MockRender(''); + const dir1 = ngMocks.findInstance(TargetDirective); + const dir2 = ngMocks.findInstance(MockDirective); + + expect(isMockOf(dir1, TargetDirective)).toEqual(false); + expect(isMockOf(dir2, MockDirective)).toEqual(true); + expect(dir1.service.name).toEqual('target'); + expect(dir1.service.token).toEqual('mock'); + }); + }); + + describe('MockBuilder:default', () => { + beforeEach(() => MockBuilder(null, EntryModule)); + + it('get real service with a mock token', () => { + MockRender(''); + const dir1 = ngMocks.findInstance(TargetDirective); + const dir2 = ngMocks.findInstance(MockDirective); + + expect(isMockOf(dir1, TargetDirective)).toEqual(false); + expect(isMockOf(dir2, MockDirective)).toEqual(true); + expect(dir1.service.name).toEqual('target'); + expect(dir1.service.token).toEqual('mock'); + }); + }); + + describe('MockBuilder:exclude:token', () => { + beforeEach(() => MockBuilder(null, EntryModule).exclude(TOKEN)); + + it('switches to exclude', () => { + expect(() => MockRender('')).toThrow(); + }); + }); + + describe('MockBuilder:exclude:directive', () => { + beforeEach(() => + MockBuilder(null, EntryModule).exclude(MockDirective), + ); + + it('switches to exclude', () => { + MockRender(''); + expect(() => ngMocks.findInstance(MockDirective)).toThrow(); + }); + }); + + describe('MockBuilder:exclude:token', () => { + beforeEach(() => MockBuilder(null, EntryModule).keep(TOKEN)); + + it('switches to exclude', () => { + MockRender(''); + const dir1 = ngMocks.findInstance(TargetDirective); + + expect(dir1.service.token).toEqual('target'); + }); + }); + + describe('MockBuilder:exclude:directive', () => { + beforeEach(() => + MockBuilder(null, EntryModule).keep(MockDirective), + ); + + it('switches to exclude', () => { + MockRender(''); + const dir2 = ngMocks.findInstance(MockDirective); + + expect(isMockOf(dir2, MockDirective)).toEqual(false); + expect(dir2.service.name).toEqual('target'); + expect(dir2.service.token).toEqual('mock'); + }); + }); +}); diff --git a/tests/ng-mocks-default-replace-modules/fixtures.ts b/tests/ng-mocks-global-replace-modules/fixtures.ts similarity index 100% rename from tests/ng-mocks-default-replace-modules/fixtures.ts rename to tests/ng-mocks-global-replace-modules/fixtures.ts diff --git a/tests/ng-mocks-default-replace-modules/test.spec.ts b/tests/ng-mocks-global-replace-modules/test.spec.ts similarity index 83% rename from tests/ng-mocks-default-replace-modules/test.spec.ts rename to tests/ng-mocks-global-replace-modules/test.spec.ts index 0f22cd76f4..57f2141696 100644 --- a/tests/ng-mocks-default-replace-modules/test.spec.ts +++ b/tests/ng-mocks-global-replace-modules/test.spec.ts @@ -7,9 +7,9 @@ import { Target3Module, } from './fixtures'; -ngMocks.defaultReplace(Target1Module, Target2Module); +ngMocks.globalReplace(Target1Module, Target2Module); -describe('ng-mocks-default-replace-modules', () => { +describe('ng-mocks-global-replace-modules', () => { beforeEach(() => { return TestBed.configureTestingModule({ imports: [MockModule(Target3Module)], diff --git a/tests/ng-mocks-default-replace/test.component.spec.ts b/tests/ng-mocks-global-replace/test.component.spec.ts similarity index 97% rename from tests/ng-mocks-default-replace/test.component.spec.ts rename to tests/ng-mocks-global-replace/test.component.spec.ts index b688b0a035..3cde64089f 100644 --- a/tests/ng-mocks-default-replace/test.component.spec.ts +++ b/tests/ng-mocks-global-replace/test.component.spec.ts @@ -30,9 +30,9 @@ class FakeComponent { }) class TargetModule {} -ngMocks.defaultReplace(TargetComponent, FakeComponent); +ngMocks.globalReplace(TargetComponent, FakeComponent); -describe('ng-mocks-default-replace:component', () => { +describe('ng-mocks-global-replace:component', () => { ngMocks.throwOnConsole(); describe('MockComponent', () => { diff --git a/tests/ng-mocks-default-replace/test.directive.spec.ts b/tests/ng-mocks-global-replace/test.directive.spec.ts similarity index 97% rename from tests/ng-mocks-default-replace/test.directive.spec.ts rename to tests/ng-mocks-global-replace/test.directive.spec.ts index e1517a4b64..1b2b01aa73 100644 --- a/tests/ng-mocks-default-replace/test.directive.spec.ts +++ b/tests/ng-mocks-global-replace/test.directive.spec.ts @@ -30,9 +30,9 @@ class FakeDirective { }) class TargetModule {} -ngMocks.defaultReplace(TargetDirective, FakeDirective); +ngMocks.globalReplace(TargetDirective, FakeDirective); -describe('ng-mocks-default-replace:directive', () => { +describe('ng-mocks-global-replace:directive', () => { ngMocks.throwOnConsole(); describe('MockDirective', () => { diff --git a/tests/ng-mocks-default-replace/test.failures.spec.ts b/tests/ng-mocks-global-replace/test.failures.spec.ts similarity index 78% rename from tests/ng-mocks-default-replace/test.failures.spec.ts rename to tests/ng-mocks-global-replace/test.failures.spec.ts index b54cc825ac..8e9d003424 100644 --- a/tests/ng-mocks-default-replace/test.failures.spec.ts +++ b/tests/ng-mocks-global-replace/test.failures.spec.ts @@ -26,16 +26,16 @@ class Fake2Service { public readonly name = 'fake2'; } -describe('ng-mocks-default-replace:failures', () => { +describe('ng-mocks-global-replace:failures', () => { it('fails on services', () => { expect(() => - ngMocks.defaultReplace(Target2Service, Fake2Service), + ngMocks.globalReplace(Target2Service, Fake2Service), ).toThrow(); }); it('fails on wrong types', () => { expect(() => - ngMocks.defaultReplace(Target1Component, Fake1Directive), + ngMocks.globalReplace(Target1Component, Fake1Directive), ).toThrow(); }); }); diff --git a/tests/ng-mocks-default-replace/test.override.spec.ts b/tests/ng-mocks-global-replace/test.override.spec.ts similarity index 87% rename from tests/ng-mocks-default-replace/test.override.spec.ts rename to tests/ng-mocks-global-replace/test.override.spec.ts index da3f821968..e35f497fee 100644 --- a/tests/ng-mocks-default-replace/test.override.spec.ts +++ b/tests/ng-mocks-global-replace/test.override.spec.ts @@ -40,15 +40,15 @@ class Fake2Component { }) class TargetModule {} -describe('ng-mocks-default-replace:override', () => { +describe('ng-mocks-global-replace:override', () => { afterAll(() => { - ngMocks.defaultWipe(Target1Component); - ngMocks.defaultWipe(Target2Component); + ngMocks.globalWipe(Target1Component); + ngMocks.globalWipe(Target2Component); }); describe('replacing Target1Component', () => { beforeEach(async () => { - ngMocks.defaultReplace(Target1Component, Fake1Component); + ngMocks.globalReplace(Target1Component, Fake1Component); return TestBed.configureTestingModule({ imports: [MockModule(TargetModule)], @@ -67,7 +67,7 @@ describe('ng-mocks-default-replace:override', () => { describe('replacing Target2Component', () => { beforeEach(async () => { - ngMocks.defaultReplace(Target2Component, Fake2Component); + ngMocks.globalReplace(Target2Component, Fake2Component); return TestBed.configureTestingModule({ imports: [MockModule(TargetModule)], diff --git a/tests/ng-mocks-default-replace/test.pipe.spec.ts b/tests/ng-mocks-global-replace/test.pipe.spec.ts similarity index 97% rename from tests/ng-mocks-default-replace/test.pipe.spec.ts rename to tests/ng-mocks-global-replace/test.pipe.spec.ts index 3a057fecbb..8fa76038c3 100644 --- a/tests/ng-mocks-default-replace/test.pipe.spec.ts +++ b/tests/ng-mocks-global-replace/test.pipe.spec.ts @@ -32,9 +32,9 @@ class FakePipe implements PipeTransform { }) class TargetModule {} -ngMocks.defaultReplace(TargetPipe, FakePipe); +ngMocks.globalReplace(TargetPipe, FakePipe); -describe('ng-mocks-default-replace:pipe', () => { +describe('ng-mocks-global-replace:pipe', () => { ngMocks.throwOnConsole(); describe('MockPipe', () => { diff --git a/tests/ng-mocks-default-wipe/test.spec.ts b/tests/ng-mocks-global-wipe/test.spec.ts similarity index 93% rename from tests/ng-mocks-default-wipe/test.spec.ts rename to tests/ng-mocks-global-wipe/test.spec.ts index ee59eed6bf..e01b09e7f8 100644 --- a/tests/ng-mocks-default-wipe/test.spec.ts +++ b/tests/ng-mocks-global-wipe/test.spec.ts @@ -38,13 +38,13 @@ class ShadowComponent { }) class TargetModule {} -ngMocks.defaultExclude(TargetComponent); -ngMocks.defaultKeep(TargetComponent); +ngMocks.globalExclude(TargetComponent); +ngMocks.globalKeep(TargetComponent); ngMocks.defaultMock(TargetComponent, () => ({ name: 'mock' })); -ngMocks.defaultReplace(TargetComponent, FakeComponent); -ngMocks.defaultWipe(TargetComponent); +ngMocks.globalReplace(TargetComponent, FakeComponent); +ngMocks.globalWipe(TargetComponent); -describe('ng-mocks-default-replace', () => { +describe('ng-mocks-global-replace', () => { ngMocks.throwOnConsole(); describe('MockComponent', () => {