fix(ivy): error when using forwardRef in Injectable's useClass (#30532)

Fixes Ivy throwing an error when something is passed in as a `forwardRef` into `@Injectable`'s `useClass` option. The error was being thrown, because we were trying to get the provider factory off of the wrapper function, rather than the value itself.

This PR resolves FW-1335.

PR Close #30532
This commit is contained in:
Kristiyan Kostadinov
2019-05-18 10:10:19 +02:00
committed by Andrew Kushnir
parent 4da805243a
commit 40a0666651
6 changed files with 80 additions and 7 deletions

View File

@ -9,6 +9,7 @@
import {Component, Directive, Inject, Injectable, InjectionToken, Injector, NgModule, Optional, forwardRef} from '@angular/core';
import {TestBed, async, inject} from '@angular/core/testing';
import {By} from '@angular/platform-browser';
import {expect} from '@angular/platform-browser/testing/src/matchers';
import {onlyInIvy} from '@angular/private/testing';
describe('providers', () => {
@ -319,6 +320,54 @@ describe('providers', () => {
expect(fixture.componentInstance.myService.dep.value).toBe('one');
});
it('should support forward refs in useClass when impl version is also provided', () => {
@Injectable({providedIn: 'root', useClass: forwardRef(() => SomeProviderImpl)})
abstract class SomeProvider {
}
@Injectable()
class SomeProviderImpl extends SomeProvider {
}
@Component({selector: 'my-app', template: ''})
class App {
constructor(public foo: SomeProvider) {}
}
TestBed.configureTestingModule(
{declarations: [App], providers: [{provide: SomeProvider, useClass: SomeProviderImpl}]});
const fixture = TestBed.createComponent(App);
fixture.detectChanges();
expect(fixture.componentInstance.foo).toBeAnInstanceOf(SomeProviderImpl);
});
onlyInIvy('VE bug (see FW-1454)')
.it('should support forward refs in useClass when token is provided', () => {
@Injectable({providedIn: 'root', useClass: forwardRef(() => SomeProviderImpl)})
abstract class SomeProvider {
}
@Injectable()
class SomeProviderImpl extends SomeProvider {
}
@Component({selector: 'my-app', template: ''})
class App {
constructor(public foo: SomeProvider) {}
}
TestBed.configureTestingModule(
{declarations: [App], providers: [{provide: SomeProvider, useClass: SomeProvider}]});
const fixture = TestBed.createComponent(App);
fixture.detectChanges();
expect(fixture.componentInstance.foo).toBeAnInstanceOf(SomeProviderImpl);
});
});
describe('flags', () => {