fix(core): run `APP_INITIALIZER`s before accessing `LOCALE_ID` token in Ivy TestBed (#36237)
Prior to this commit, Ivy TestBed was accessing locale ID before `APP_INITIALIZER` functions were called. This execution order is not consistent with the app bootstrap logic in `application_ref.ts`. This commit updates Ivy TestBed execution order to call initializers first (since they might affect `LOCALE_ID` token value) and accessing and setting locale ID after that. Fixes #36230. PR Close #36237
This commit is contained in:
parent
b54db86f43
commit
16497438d6
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ChangeDetectorRef, Compiler, Component, Directive, ErrorHandler, Inject, Injectable, InjectionToken, Injector, Input, ModuleWithProviders, NgModule, Optional, Pipe, Type, ViewChild, ɵsetClassMetadata as setClassMetadata, ɵɵdefineComponent as defineComponent, ɵɵdefineInjector as defineInjector, ɵɵdefineNgModule as defineNgModule, ɵɵsetNgModuleScope as setNgModuleScope, ɵɵtext as text} from '@angular/core';
|
import {APP_INITIALIZER, ChangeDetectorRef, Compiler, Component, Directive, ErrorHandler, Inject, Injectable, InjectionToken, Injector, Input, LOCALE_ID, ModuleWithProviders, NgModule, Optional, Pipe, Type, ViewChild, ɵsetClassMetadata as setClassMetadata, ɵɵdefineComponent as defineComponent, ɵɵdefineInjector as defineInjector, ɵɵdefineNgModule as defineNgModule, ɵɵsetNgModuleScope as setNgModuleScope, ɵɵtext as text} from '@angular/core';
|
||||||
import {TestBed, getTestBed} from '@angular/core/testing/src/test_bed';
|
import {TestBed, getTestBed} from '@angular/core/testing/src/test_bed';
|
||||||
import {By} from '@angular/platform-browser';
|
import {By} from '@angular/platform-browser';
|
||||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||||
|
@ -245,6 +245,21 @@ describe('TestBed', () => {
|
||||||
expect(hello.nativeElement).toHaveText('Hello World!');
|
expect(hello.nativeElement).toHaveText('Hello World!');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should run `APP_INITIALIZER` before accessing `LOCALE_ID` provider', () => {
|
||||||
|
let locale: string = '';
|
||||||
|
@NgModule({
|
||||||
|
providers: [
|
||||||
|
{provide: APP_INITIALIZER, useValue: () => locale = 'fr-FR', multi: true},
|
||||||
|
{provide: LOCALE_ID, useFactory: () => locale}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
class TestModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({imports: [TestModule]});
|
||||||
|
expect(TestBed.inject(LOCALE_ID)).toBe('fr-FR');
|
||||||
|
});
|
||||||
|
|
||||||
it('allow to override a provider', () => {
|
it('allow to override a provider', () => {
|
||||||
TestBed.overrideProvider(NAME, {useValue: 'injected World!'});
|
TestBed.overrideProvider(NAME, {useValue: 'injected World!'});
|
||||||
const hello = TestBed.createComponent(HelloWorld);
|
const hello = TestBed.createComponent(HelloWorld);
|
||||||
|
|
|
@ -257,14 +257,16 @@ export class R3TestBedCompiler {
|
||||||
const parentInjector = this.platform.injector;
|
const parentInjector = this.platform.injector;
|
||||||
this.testModuleRef = new NgModuleRef(this.testModuleType, parentInjector);
|
this.testModuleRef = new NgModuleRef(this.testModuleType, parentInjector);
|
||||||
|
|
||||||
// Set the locale ID, it can be overridden for the tests
|
|
||||||
const localeId = this.testModuleRef.injector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
|
|
||||||
setLocaleId(localeId);
|
|
||||||
|
|
||||||
// ApplicationInitStatus.runInitializers() is marked @internal to core.
|
// ApplicationInitStatus.runInitializers() is marked @internal to core.
|
||||||
// Cast it to any before accessing it.
|
// Cast it to any before accessing it.
|
||||||
(this.testModuleRef.injector.get(ApplicationInitStatus) as any).runInitializers();
|
(this.testModuleRef.injector.get(ApplicationInitStatus) as any).runInitializers();
|
||||||
|
|
||||||
|
// Set locale ID after running app initializers, since locale information might be updated while
|
||||||
|
// running initializers. This is also consistent with the execution order while bootstrapping an
|
||||||
|
// app (see `packages/core/src/application_ref.ts` file).
|
||||||
|
const localeId = this.testModuleRef.injector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
|
||||||
|
setLocaleId(localeId);
|
||||||
|
|
||||||
return this.testModuleRef;
|
return this.testModuleRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue