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:
Alex Rickabaugh 2019-01-10 13:44:17 -08:00 committed by Andrew Kushnir
parent 8c3f98fdbb
commit 6c6d43086f
1 changed files with 4 additions and 4 deletions

View File

@ -35,12 +35,12 @@ const modules = new Map<string, NgModuleFactory<any>|NgModuleType>();
*/
export function registerModuleFactory(id: string, factory: 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);
}
function assertNotExisting(id: string, type: Type<any>| null): void {
if (type) {
function assertSameOrNotExisting(id: string, type: Type<any>| null, incoming: Type<any>): void {
if (type && type !== incoming) {
throw new Error(
`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) {
const existing = modules.get(id) as NgModuleType | null;
assertNotExisting(id, existing);
assertSameOrNotExisting(id, existing, ngModuleType);
modules.set(id, ngModuleType);
}