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
|
||||
*/
|
||||
|
||||
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 {By} from '@angular/platform-browser';
|
||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||
|
@ -245,6 +245,21 @@ describe('TestBed', () => {
|
|||
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', () => {
|
||||
TestBed.overrideProvider(NAME, {useValue: 'injected World!'});
|
||||
const hello = TestBed.createComponent(HelloWorld);
|
||||
|
|
|
@ -257,14 +257,16 @@ export class R3TestBedCompiler {
|
|||
const parentInjector = this.platform.injector;
|
||||
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.
|
||||
// Cast it to any before accessing it.
|
||||
(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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue