fix(ivy): Only restore registered modules if user compiles modules with TestBed (#32944)
There are a couple scenarios that are problematic and need special handling: 1. A user has a custom implementation of lazy-loaded modules, sets some provider overrides, then compiles the module so it can be loaded. In a follow-up test, the user sets different overrides for the module and then compiles. This is problematic because we need to be sure the module registered in the first test is not used, so we need to clear it out of the modules list in `ng_module_factory_registration`. 2. A user has a similar lazy-loaded module factory implementation but relies on the module being registered automatically. This can happen, for example, as a side effect of importing the ngfactory file. PR Close #32944
This commit is contained in:
@ -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 {clearModuleRegistry} from '../../src/linker/ng_module_factory_registration';
|
||||
import {clearRegisteredModuleState} from '../../src/linker/ng_module_factory_registration';
|
||||
import {stringify} from '../../src/util/stringify';
|
||||
|
||||
class Engine {}
|
||||
@ -294,11 +294,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||
describe('id', () => {
|
||||
const token = 'myid';
|
||||
|
||||
// Ivy TestBed clears module registry in resetTestingModule so this afterEach is not needed
|
||||
// for Ivy
|
||||
if (!ivyEnabled) {
|
||||
afterEach(() => clearModuleRegistry());
|
||||
}
|
||||
afterEach(() => clearRegisteredModuleState());
|
||||
|
||||
it('should register loaded modules', () => {
|
||||
@NgModule({id: token})
|
||||
|
@ -7,6 +7,8 @@
|
||||
*/
|
||||
|
||||
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';
|
||||
import {registerModuleFactory} from '@angular/core/src/linker/ng_module_factory_registration';
|
||||
import {NgModuleFactory} from '@angular/core/src/render3';
|
||||
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';
|
||||
@ -732,15 +734,30 @@ describe('TestBed', () => {
|
||||
});
|
||||
|
||||
onlyInIvy('Ivy module registration happens when NgModuleFactory is created')
|
||||
.it('cleans up registered modules', async() => {
|
||||
@NgModule({id: 'my_module'})
|
||||
class MyModule {
|
||||
}
|
||||
.describe('cleans up registered modules - ', () => {
|
||||
it('removes modules registered with TestBed', 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();
|
||||
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();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user