fix(core): use proper configuration to compile Injectable in JIT (#35706)
Prior to this change, the logic that compiles Injectable in JIT mode used incorrect configuration that triggers a problem when `ChangeDetectorRef` is used as a dependency. This commit updates the logic to generate correct inject instruction to add the `ChangeDetectorRef` dependency in case it's requested in @Injectable class. PR Close #35706
This commit is contained in:
parent
8fed1fe792
commit
7b13977c3a
|
@ -65,7 +65,7 @@ export function compileInjectable(type: Type<any>, srcMeta?: Injectable): void {
|
||||||
typeArgumentCount: metadata.typeArgumentCount,
|
typeArgumentCount: metadata.typeArgumentCount,
|
||||||
deps: reflectDependencies(type),
|
deps: reflectDependencies(type),
|
||||||
injectFn: 'inject',
|
injectFn: 'inject',
|
||||||
target: compiler.R3FactoryTarget.Pipe
|
target: compiler.R3FactoryTarget.Injectable
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return ngFactoryDef;
|
return ngFactoryDef;
|
||||||
|
|
|
@ -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 {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 {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 {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';
|
||||||
|
@ -485,6 +485,26 @@ describe('TestBed', () => {
|
||||||
expect(service.get()).toEqual('override');
|
expect(service.get()).toEqual('override');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle overrides for a provider that has `ChangeDetectorRef` as a dependency', () => {
|
||||||
|
// Note: we specifically check an @Injectable with `ChangeDetectorRef` here due to the fact that
|
||||||
|
// in Ivy there is a special instruction that injects `ChangeDetectorRef` token for Pipes
|
||||||
|
// (ɵɵinjectPipeChangeDetectorRef) and using that function for other types causes problems,
|
||||||
|
// for example when we try to override an @Injectable. The test below captures a use-case that
|
||||||
|
// triggers a problem in case incompatible function is used to inject `ChangeDetectorRef` as a
|
||||||
|
// dependency.
|
||||||
|
@Injectable({providedIn: 'root'})
|
||||||
|
class MyService {
|
||||||
|
token = 'original';
|
||||||
|
constructor(public cdr: ChangeDetectorRef) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
TestBed.overrideProvider(MyService, {useValue: {token: 'override'}});
|
||||||
|
|
||||||
|
const service = TestBed.inject(MyService);
|
||||||
|
expect(service.token).toBe('override');
|
||||||
|
});
|
||||||
|
|
||||||
it('should allow overriding a provider defined via ModuleWithProviders (using TestBed.configureTestingModule)',
|
it('should allow overriding a provider defined via ModuleWithProviders (using TestBed.configureTestingModule)',
|
||||||
() => {
|
() => {
|
||||||
const serviceOverride = {
|
const serviceOverride = {
|
||||||
|
|
Loading…
Reference in New Issue