From b04729aa4d562313458b38b3e5c1611debdef9e1 Mon Sep 17 00:00:00 2001 From: satanTime Date: Mon, 5 Sep 2022 14:19:54 +0300 Subject: [PATCH] fix(ngMocks.faster): support of angular 14.2.0 #3466 --- libs/ng-mocks/src/lib/common/core.helpers.ts | 1 + .../lib/common/ng-mocks-global-overrides.ts | 8 +- .../mock-builder/mock-builder.promise.spec.ts | 20 +++-- .../lib/mock-builder/mock-builder.promise.ts | 2 +- .../mock-helper/mock-helper.faster-install.ts | 36 ++++++--- tests/abstract-methods-provider/test.spec.ts | 4 +- tests/ng-mocks-faster/idea.spec.ts | 81 +++++++++++++++++++ tests/ng-mocks-faster/test.spec.ts | 6 +- 8 files changed, 130 insertions(+), 28 deletions(-) create mode 100644 tests/ng-mocks-faster/idea.spec.ts diff --git a/libs/ng-mocks/src/lib/common/core.helpers.ts b/libs/ng-mocks/src/lib/common/core.helpers.ts index e624266b4c..f7c6152956 100644 --- a/libs/ng-mocks/src/lib/common/core.helpers.ts +++ b/libs/ng-mocks/src/lib/common/core.helpers.ts @@ -8,6 +8,7 @@ import funcGetName from './func.get-name'; /** * It will be removed from public interface with the next release: A14 + * Use ngMocks.get(token) instead. * * @deprecated * @internal diff --git a/libs/ng-mocks/src/lib/common/ng-mocks-global-overrides.ts b/libs/ng-mocks/src/lib/common/ng-mocks-global-overrides.ts index f3d9e2cd46..b70cbc4e4b 100644 --- a/libs/ng-mocks/src/lib/common/ng-mocks-global-overrides.ts +++ b/libs/ng-mocks/src/lib/common/ng-mocks-global-overrides.ts @@ -176,7 +176,7 @@ const applyPlatformOverrides = (testBed: TestBed, touches: Set) => { }; const configureTestingModule = - (original: TestBedStatic['configureTestingModule']): TestBedStatic['configureTestingModule'] => + (original: TestBedStatic['configureTestingModule'], instance: TestBed): TestBedStatic['configureTestingModule'] => (moduleDef: TestModuleMetadata) => { initTestBed(); @@ -202,18 +202,18 @@ const configureTestingModule = applyPlatformOverrides(testBed, touches); } - return original.call(TestBed, moduleDef); + return original.call(instance, moduleDef); }; const resetTestingModule = - (original: TestBedStatic['resetTestingModule']): TestBedStatic['resetTestingModule'] => + (original: TestBedStatic['resetTestingModule'], instance: TestBed): TestBedStatic['resetTestingModule'] => () => { ngMocksUniverse.global.delete('builder:config'); ngMocksUniverse.global.delete('builder:module'); (TestBed as any).ngMocksSelectors = undefined; applyNgMocksOverrides(TestBed); - return original.call(TestBed); + return original.call(instance); }; const viewContainerInstall = () => { diff --git a/libs/ng-mocks/src/lib/mock-builder/mock-builder.promise.spec.ts b/libs/ng-mocks/src/lib/mock-builder/mock-builder.promise.spec.ts index 32bbc4f554..ae3c4d35fe 100644 --- a/libs/ng-mocks/src/lib/mock-builder/mock-builder.promise.spec.ts +++ b/libs/ng-mocks/src/lib/mock-builder/mock-builder.promise.spec.ts @@ -8,8 +8,8 @@ import { PipeTransform, } from '@angular/core'; -import { getTestBedInjection } from '../common/core.helpers'; import mockHelperConsoleThrow from '../mock-helper/mock-helper.console-throw'; +import mockHelperGet from '../mock-helper/mock-helper.get'; import { MockBuilder } from './mock-builder'; @@ -50,24 +50,28 @@ describe('MockBuilderPromise', () => { it('skips dependencies in kept providers', async () => { await MockBuilder().keep(TargetService, { dependency: true }); - expect(getTestBedInjection(TargetService)).toBeFalsy(); + expect(() => mockHelperGet(TargetService)).toThrowError( + /Cannot find an instance/, + ); }); it('adds non dependencies in kept providers', async () => { await MockBuilder().keep(TargetService); - expect(getTestBedInjection(TargetService)).toBeTruthy(); + expect(mockHelperGet(TargetService)).toBeTruthy(); }); it('skips dependencies in mock providers', async () => { await MockBuilder().mock(TargetService, TargetService, { dependency: true, }); - expect(getTestBedInjection(TargetService)).toBeFalsy(); + expect(() => mockHelperGet(TargetService)).toThrowError( + /Cannot find an instance/, + ); }); it('adds non dependencies in mock providers', async () => { await MockBuilder().mock(TargetService); - expect(getTestBedInjection(TargetService)).toBeTruthy(); + expect(mockHelperGet(TargetService)).toBeTruthy(); }); it('respects several kept overloads', async () => { @@ -92,7 +96,7 @@ describe('MockBuilderPromise', () => { }, ], }); - expect(getTestBedInjection(TARGET_TOKEN)).toEqual([1, 2]); + expect(mockHelperGet(TARGET_TOKEN)).toEqual([1, 2]); }); it('respects several mock overloads', async () => { @@ -117,7 +121,9 @@ describe('MockBuilderPromise', () => { }, ], }); - expect(getTestBedInjection(TARGET_TOKEN)).toBeUndefined(); + expect(() => mockHelperGet(TARGET_TOKEN)).toThrowError( + /Cannot find an instance/, + ); }); it('throws an error on a services replacement', () => { diff --git a/libs/ng-mocks/src/lib/mock-builder/mock-builder.promise.ts b/libs/ng-mocks/src/lib/mock-builder/mock-builder.promise.ts index 8d38c55272..480057aeb5 100644 --- a/libs/ng-mocks/src/lib/mock-builder/mock-builder.promise.ts +++ b/libs/ng-mocks/src/lib/mock-builder/mock-builder.promise.ts @@ -188,7 +188,7 @@ export class MockBuilderPromise implements IMockBuilder { reject?: ((reason: any) => PromiseLike) | undefined | null, ): Promise { const promise = new Promise((resolve: (value: IMockBuilderResult) => void): void => { - const testBed = TestBed.configureTestingModule(this.build()); + const testBed: TestBedStatic = TestBed.configureTestingModule(this.build()) as never; for (const callback of mapValues(this.beforeCC)) { callback(testBed); } diff --git a/libs/ng-mocks/src/lib/mock-helper/mock-helper.faster-install.ts b/libs/ng-mocks/src/lib/mock-helper/mock-helper.faster-install.ts index 9c8d439bac..1f1d0239ff 100644 --- a/libs/ng-mocks/src/lib/mock-helper/mock-helper.faster-install.ts +++ b/libs/ng-mocks/src/lib/mock-helper/mock-helper.faster-install.ts @@ -1,11 +1,15 @@ -import { TestBed, TestBedStatic, TestModuleMetadata } from '@angular/core/testing'; +import { getTestBed, TestBed, TestBedStatic, TestModuleMetadata } from '@angular/core/testing'; import coreDefineProperty from '../common/core.define-property'; import ngMocksUniverse from '../common/ng-mocks-universe'; const hooks: { - after: Array<(original: TestBedStatic['resetTestingModule']) => TestBedStatic['resetTestingModule']>; - before: Array<(original: TestBedStatic['configureTestingModule']) => TestBedStatic['configureTestingModule']>; + after: Array< + (original: TestBedStatic['resetTestingModule'], instance: TestBed) => TestBedStatic['resetTestingModule'] + >; + before: Array< + (original: TestBedStatic['configureTestingModule'], instance: TestBed) => TestBedStatic['configureTestingModule'] + >; } = ngMocksUniverse.global.get('faster-hooks') || { after: [], before: [], @@ -13,44 +17,52 @@ const hooks: { ngMocksUniverse.global.set('faster-hooks', hooks); const configureTestingModule = - (original: TestBedStatic['configureTestingModule']): TestBedStatic['configureTestingModule'] => + (original: TestBedStatic['configureTestingModule'], instance: TestBed): TestBedStatic['configureTestingModule'] => (moduleDef: TestModuleMetadata) => { ngMocksUniverse.global.set('bullet:customized', true); let final = original; for (const callback of hooks.before) { - final = callback(final); + final = callback(final, instance); } - return final.call(TestBed, moduleDef); + return final.call(instance, moduleDef); }; const resetTestingModule = - (original: TestBedStatic['resetTestingModule']): TestBedStatic['resetTestingModule'] => + (original: TestBedStatic['resetTestingModule'], instance: TestBed): TestBedStatic['resetTestingModule'] => () => { if (ngMocksUniverse.global.has('bullet')) { if (ngMocksUniverse.global.has('bullet:customized')) { ngMocksUniverse.global.set('bullet:reset', true); } - return TestBed; + return instance; } ngMocksUniverse.global.delete('bullet:customized'); ngMocksUniverse.global.delete('bullet:reset'); + let final = original; for (const callback of hooks.after) { - final = callback(final); + final = callback(final, instance); } - return final.call(TestBed); + return final.call(instance); }; export default () => { if (!(TestBed as any).ngMocksFasterInstalled) { - TestBed.configureTestingModule = configureTestingModule(TestBed.configureTestingModule); - TestBed.resetTestingModule = resetTestingModule(TestBed.resetTestingModule); + TestBed.configureTestingModule = configureTestingModule(TestBed.configureTestingModule, TestBed); + TestBed.resetTestingModule = resetTestingModule(TestBed.resetTestingModule, TestBed); coreDefineProperty(TestBed, 'ngMocksFasterInstalled', true); } + const testBed = getTestBed(); + if (!(testBed as any).ngMocksFasterInstalled) { + testBed.configureTestingModule = configureTestingModule(testBed.configureTestingModule, testBed); + testBed.resetTestingModule = resetTestingModule(testBed.resetTestingModule, testBed); + coreDefineProperty(testBed, 'ngMocksFasterInstalled', true); + } + return hooks; }; diff --git a/tests/abstract-methods-provider/test.spec.ts b/tests/abstract-methods-provider/test.spec.ts index 341707c254..a3d5ed3a2b 100644 --- a/tests/abstract-methods-provider/test.spec.ts +++ b/tests/abstract-methods-provider/test.spec.ts @@ -1,6 +1,6 @@ import { Injectable, NgModule } from '@angular/core'; -import { getTestBedInjection, MockBuilder } from 'ng-mocks'; +import { MockBuilder, ngMocks } from 'ng-mocks'; @Injectable() abstract class LoggerInterface { @@ -30,7 +30,7 @@ describe('abstract-methods-provider', () => { beforeEach(() => MockBuilder().mock(TargetModule)); it('provides a mock copy with an implemented abstract method', () => { - const actual = getTestBedInjection(LoggerInterface); + const actual = ngMocks.get(LoggerInterface); expect(actual && actual.log).toBeDefined(); }); }); diff --git a/tests/ng-mocks-faster/idea.spec.ts b/tests/ng-mocks-faster/idea.spec.ts new file mode 100644 index 0000000000..7731a54124 --- /dev/null +++ b/tests/ng-mocks-faster/idea.spec.ts @@ -0,0 +1,81 @@ +import { InjectionToken } from '@angular/core'; +import { getTestBed, TestBed } from '@angular/core/testing'; + +import { ngMocks } from 'ng-mocks'; + +const TOKEN = new InjectionToken('TOKEN'); + +describe('ngMocks.faster:idea', () => { + it('does have access to token before optimization', () => { + expect(() => ngMocks.get(TOKEN)).toThrowError( + /Cannot find an instance/, + ); + }); + + describe('optimization', () => { + const backup: Partial = {}; + const backupInstance: Partial = {}; + + beforeAll(() => { + backup.configureTestingModule = TestBed.configureTestingModule; + backup.resetTestingModule = TestBed.resetTestingModule; + + const testBed = getTestBed(); + backupInstance.configureTestingModule = + testBed.configureTestingModule; + backupInstance.resetTestingModule = testBed.resetTestingModule; + }); + + afterAll(() => { + if (backup.configureTestingModule) { + TestBed.configureTestingModule = + backup.configureTestingModule; + } + if (backup.resetTestingModule) { + TestBed.resetTestingModule = backup.resetTestingModule; + } + + const testBed = getTestBed(); + if (backupInstance.configureTestingModule) { + testBed.configureTestingModule = + backupInstance.configureTestingModule; + } + if (backupInstance.resetTestingModule) { + testBed.resetTestingModule = + backupInstance.resetTestingModule; + } + TestBed.resetTestingModule(); + }); + + describe('suite with faster logic', () => { + beforeAll(() => { + TestBed.resetTestingModule = () => getTestBed() as never; + const testBed = getTestBed(); + testBed.resetTestingModule = () => getTestBed() as never; + + return TestBed.configureTestingModule({ + providers: [ + { + provide: TOKEN, + useValue: true, + }, + ], + }).compileComponents(); + }); + + it('has access to token after configuration', () => { + expect(ngMocks.get(TOKEN)).toEqual(true); + }); + + it('has access to token after supressed reset', () => { + expect(ngMocks.get(TOKEN)).toEqual(true); + }); + }); + }); + + it('does have access to token after optimization', () => { + expect(() => ngMocks.get(TOKEN)).toThrowError( + /Cannot find an instance/, + ); + }); +}); diff --git a/tests/ng-mocks-faster/test.spec.ts b/tests/ng-mocks-faster/test.spec.ts index 1ece823ca9..c9694539f5 100644 --- a/tests/ng-mocks-faster/test.spec.ts +++ b/tests/ng-mocks-faster/test.spec.ts @@ -1,7 +1,7 @@ import { InjectionToken } from '@angular/core'; import { TestBed } from '@angular/core/testing'; -import { getTestBedInjection, ngMocks } from 'ng-mocks'; +import { ngMocks } from 'ng-mocks'; const TOKEN = new InjectionToken('TOKEN'); @@ -33,7 +33,9 @@ describe('ngMocks.faster', () => { ngMocks.faster(); it('works in clear reset', () => { - expect(getTestBedInjection(TOKEN)).toBeUndefined(); + expect(() => ngMocks.get(TOKEN)).toThrowError( + /Cannot find an instance/, + ); }); }); });