diff --git a/packages/core/src/linker/ng_module_factory_registration.ts b/packages/core/src/linker/ng_module_factory_registration.ts index 78b7e61652..92ec31e420 100644 --- a/packages/core/src/linker/ng_module_factory_registration.ts +++ b/packages/core/src/linker/ng_module_factory_registration.ts @@ -14,14 +14,13 @@ import {stringify} from '../util/stringify'; import {NgModuleFactory} from './ng_module_factory'; -export type ModuleRegistrationMap = Map|NgModuleType>; /** * Map of module-id to the corresponding NgModule. * - In pre Ivy we track NgModuleFactory, * - In post Ivy we track the NgModuleType */ -let modules: ModuleRegistrationMap = new Map(); +const modules = new Map|NgModuleType>(); /** * Registers a loaded module. Should only be called from generated NgModuleFactory code. @@ -57,18 +56,10 @@ export function registerNgModuleType(ngModuleType: NgModuleType) { } } -export function clearRegisteredModuleState(): void { +export function clearModuleRegistry(): void { modules.clear(); } -export function getRegisteredModulesState(): ModuleRegistrationMap { - return new Map(modules); -} - -export function restoreRegisteredModulesState(moduleMap: ModuleRegistrationMap) { - modules = new Map(moduleMap); -} - export function getRegisteredNgModuleType(id: string) { return modules.get(id) || autoRegisterModuleById[id]; } diff --git a/packages/core/test/linker/ng_module_integration_spec.ts b/packages/core/test/linker/ng_module_integration_spec.ts index bdc52b9621..28b79a9107 100644 --- a/packages/core/test/linker/ng_module_integration_spec.ts +++ b/packages/core/test/linker/ng_module_integration_spec.ts @@ -17,7 +17,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers'; import {modifiedInIvy, obsoleteInIvy, onlyInIvy} from '@angular/private/testing'; import {InternalNgModuleRef, NgModuleFactory} from '../../src/linker/ng_module_factory'; -import {clearRegisteredModuleState} from '../../src/linker/ng_module_factory_registration'; +import {clearModuleRegistry} from '../../src/linker/ng_module_factory_registration'; import {stringify} from '../../src/util/stringify'; class Engine {} @@ -294,7 +294,11 @@ function declareTests(config?: {useJit: boolean}) { describe('id', () => { const token = 'myid'; - afterEach(() => clearRegisteredModuleState()); + // Ivy TestBed clears module registry in resetTestingModule so this afterEach is not needed + // for Ivy + if (!ivyEnabled) { + afterEach(() => clearModuleRegistry()); + } it('should register loaded modules', () => { @NgModule({id: token}) diff --git a/packages/core/test/test_bed_spec.ts b/packages/core/test/test_bed_spec.ts index 0696e50dc2..eccb23344d 100644 --- a/packages/core/test/test_bed_spec.ts +++ b/packages/core/test/test_bed_spec.ts @@ -6,9 +6,13 @@ * found in the LICENSE file at https://angular.io/license */ +<<<<<<< HEAD import {Compiler, Component, Directive, ErrorHandler, Inject, Injectable, InjectionToken, Injector, Input, ModuleWithProviders, NgModule, Optional, Pipe, getModuleFactory, ɵsetClassMetadata as setClassMetadata, ɵɵdefineComponent as defineComponent, ɵɵdefineNgModule as defineNgModule, ɵɵtext as text} from '@angular/core'; import {registerModuleFactory} from '@angular/core/src/linker/ng_module_factory_registration'; import {NgModuleFactory} from '@angular/core/src/render3'; +======= +import {Compiler, Component, Directive, ErrorHandler, Inject, Injectable, InjectionToken, Input, ModuleWithProviders, NgModule, Optional, Pipe, getModuleFactory, ɵsetClassMetadata as setClassMetadata, ɵɵdefineComponent as defineComponent, ɵɵdefineNgModule as defineNgModule, ɵɵtext as text} from '@angular/core'; +>>>>>>> parent of 63256b511a... fix(ivy): Only restore registered modules if user compiles modules with TestBed (#32944) import {TestBed, getTestBed} from '@angular/core/testing/src/test_bed'; import {By} from '@angular/platform-browser'; import {expect} from '@angular/platform-browser/testing/src/matchers'; @@ -909,30 +913,15 @@ describe('TestBed', () => { }); onlyInIvy('Ivy module registration happens when NgModuleFactory is created') - .describe('cleans up registered modules - ', () => { - it('removes modules registered with TestBed', async() => { - @NgModule({id: 'my_module'}) - class MyModule { - } + .it('cleans up registered modules', async() => { + @NgModule({id: 'my_module'}) + class MyModule { + } - expect(() => getModuleFactory('my_module')).toThrowError(); - await TestBed.inject(Compiler).compileModuleAsync(MyModule); - expect(() => getModuleFactory('my_module')).not.toThrowError(); - TestBed.resetTestingModule(); - expect(() => getModuleFactory('my_module')).toThrowError(); - }); - - it('does not remove modules registered outside TestBed (i.e., side effect registration in ngfactory files)', - () => { - @NgModule({id: 'auto_module'}) - class AutoModule { - } - - expect(() => getModuleFactory('auto_module')).toThrowError(); - registerModuleFactory('auto_module', new NgModuleFactory(AutoModule)); - expect(() => getModuleFactory('auto_module')).not.toThrowError(); - TestBed.resetTestingModule(); - expect(() => getModuleFactory('auto_module')).not.toThrowError(); - }); + expect(() => getModuleFactory('my_module')).toThrowError(); + await TestBed.inject(Compiler).compileModuleAsync(MyModule); + expect(() => getModuleFactory('my_module')).not.toThrowError(); + TestBed.resetTestingModule(); + expect(() => getModuleFactory('my_module')).toThrowError(); }); }); diff --git a/packages/core/testing/src/r3_test_bed.ts b/packages/core/testing/src/r3_test_bed.ts index a4d98146be..5ea00a5188 100644 --- a/packages/core/testing/src/r3_test_bed.ts +++ b/packages/core/testing/src/r3_test_bed.ts @@ -35,7 +35,7 @@ import {MetadataOverride} from './metadata_override'; import {TestBed} from './test_bed'; import {ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, TestBedStatic, TestComponentRenderer, TestModuleMetadata} from './test_bed_common'; import {R3TestBedCompiler} from './r3_test_bed_compiler'; -import {clearRegisteredModuleState} from '../../src/linker/ng_module_factory_registration'; +import {clearModuleRegistry} from '../../src/linker/ng_module_factory_registration'; let _nextRootElementId = 0; @@ -229,6 +229,7 @@ export class TestBedRender3 implements TestBed { } resetTestingModule(): void { + clearModuleRegistry(); this.checkGlobalCompilationFinished(); resetCompiledComponents(); if (this._compiler !== null) { diff --git a/packages/core/testing/src/r3_test_bed_compiler.ts b/packages/core/testing/src/r3_test_bed_compiler.ts index ff5402140a..b6a832ff30 100644 --- a/packages/core/testing/src/r3_test_bed_compiler.ts +++ b/packages/core/testing/src/r3_test_bed_compiler.ts @@ -9,7 +9,6 @@ import {ResourceLoader} from '@angular/compiler'; import {ApplicationInitStatus, COMPILER_OPTIONS, Compiler, Component, Directive, Injector, InjectorType, LOCALE_ID, ModuleWithComponentFactories, ModuleWithProviders, NgModule, NgModuleFactory, NgZone, Pipe, PlatformRef, Provider, Type, ɵDEFAULT_LOCALE_ID as DEFAULT_LOCALE_ID, ɵDirectiveDef as DirectiveDef, ɵNG_COMP_DEF as NG_COMP_DEF, ɵNG_DIR_DEF as NG_DIR_DEF, ɵNG_INJ_DEF as NG_INJ_DEF, ɵNG_MOD_DEF as NG_MOD_DEF, ɵNG_PIPE_DEF as NG_PIPE_DEF, ɵNgModuleFactory as R3NgModuleFactory, ɵNgModuleTransitiveScopes as NgModuleTransitiveScopes, ɵNgModuleType as NgModuleType, ɵRender3ComponentFactory as ComponentFactory, ɵRender3NgModuleRef as NgModuleRef, ɵcompileComponent as compileComponent, ɵcompileDirective as compileDirective, ɵcompileNgModuleDefs as compileNgModuleDefs, ɵcompilePipe as compilePipe, ɵgetInjectableDef as getInjectableDef, ɵpatchComponentDefWithScope as patchComponentDefWithScope, ɵsetLocaleId as setLocaleId, ɵtransitiveScopesFor as transitiveScopesFor, ɵɵInjectableDef as InjectableDef} from '@angular/core'; -import {ModuleRegistrationMap, getRegisteredModulesState, restoreRegisteredModulesState} from '../../src/linker/ng_module_factory_registration'; import {clearResolutionOfComponentResourcesQueue, isComponentDefPendingResolution, resolveComponentResources, restoreComponentResolutionQueue} from '../../src/metadata/resource_loading'; import {MetadataOverride} from './metadata_override'; @@ -42,7 +41,6 @@ interface CleanupOperation { export class R3TestBedCompiler { private originalComponentResolutionQueue: Map, Component>|null = null; - private originalRegisteredModules: null|ModuleRegistrationMap = null; // Testing module configuration private declarations: Type[] = []; @@ -277,9 +275,6 @@ export class R3TestBedCompiler { * @internal */ async _compileNgModuleAsync(moduleType: Type): Promise { - if (this.originalRegisteredModules === null) { - this.originalRegisteredModules = getRegisteredModulesState(); - } this.queueTypesFromModulesArray([moduleType]); await this.compileComponents(); this.applyProviderOverrides(); @@ -567,10 +562,6 @@ export class R3TestBedCompiler { this.initialNgDefs.clear(); this.moduleProvidersOverridden.clear(); this.restoreComponentResolutionQueue(); - if (this.originalRegisteredModules) { - restoreRegisteredModulesState(this.originalRegisteredModules); - this.originalRegisteredModules = null; - } // Restore the locale ID to the default value, this shouldn't be necessary but we never know setLocaleId(DEFAULT_LOCALE_ID); }