fix(ivy): make module registration by id idempotent (#28033)
An @NgModule with an 'id' property has its type registered in a global map of modules by id. This happens during compilation of the module. In Ivy, modules are first compiled when the @NgModule decorator executes. In tests, they might be passed again through the TestBed's compiler, resulting in a second compilation and registration. Before this fix, this second registration would cause an error, as the id was previously registered. This commit makes the registration idempotent, so if the same module type is being registered for the same id then no error is thrown. Testing strategy: future commits change the way the TestBed compiles modules, causing tests to become sensitive to this bug if not fixed. PR Close #28033
This commit is contained in:
parent
8c3f98fdbb
commit
6c6d43086f
|
@ -35,12 +35,12 @@ const modules = new Map<string, NgModuleFactory<any>|NgModuleType>();
|
||||||
*/
|
*/
|
||||||
export function registerModuleFactory(id: string, factory: NgModuleFactory<any>) {
|
export function registerModuleFactory(id: string, factory: NgModuleFactory<any>) {
|
||||||
const existing = modules.get(id) as NgModuleFactory<any>;
|
const existing = modules.get(id) as NgModuleFactory<any>;
|
||||||
assertNotExisting(id, existing && existing.moduleType);
|
assertSameOrNotExisting(id, existing && existing.moduleType, factory.moduleType);
|
||||||
modules.set(id, factory);
|
modules.set(id, factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
function assertNotExisting(id: string, type: Type<any>| null): void {
|
function assertSameOrNotExisting(id: string, type: Type<any>| null, incoming: Type<any>): void {
|
||||||
if (type) {
|
if (type && type !== incoming) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Duplicate module registered for ${id} - ${stringify(type)} vs ${stringify(type.name)}`);
|
`Duplicate module registered for ${id} - ${stringify(type)} vs ${stringify(type.name)}`);
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ function assertNotExisting(id: string, type: Type<any>| null): void {
|
||||||
|
|
||||||
export function registerNgModuleType(id: string, ngModuleType: NgModuleType) {
|
export function registerNgModuleType(id: string, ngModuleType: NgModuleType) {
|
||||||
const existing = modules.get(id) as NgModuleType | null;
|
const existing = modules.get(id) as NgModuleType | null;
|
||||||
assertNotExisting(id, existing);
|
assertSameOrNotExisting(id, existing, ngModuleType);
|
||||||
modules.set(id, ngModuleType);
|
modules.set(id, ngModuleType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue