fix(core): Deprecate TestBed.get(...):any (#29290)

Adds an overload to TestBed.get making parameters strongly typed and
deprecated previous signature that accepted types `any`. The function
still returns `any` to prevent build breakages, but eventually stronger
type checks will be added so a future Angular version will break builds
due to additional type checks.
See previous breaking change - #13785

Issue #26491

PR Close #29290
This commit is contained in:
Carlos Ortiz García 2019-04-03 10:23:46 -07:00 committed by Igor Minar
parent 9c056b974a
commit 609024f93d
4 changed files with 69 additions and 26 deletions

View File

@ -13,6 +13,8 @@
import { import {
Component, Component,
Directive, Directive,
InjectFlags,
InjectionToken,
Injector, Injector,
NgModule, NgModule,
NgZone, NgZone,
@ -167,7 +169,14 @@ export class TestBedRender3 implements Injector, TestBed {
return TestBedRender3 as any as TestBedStatic; return TestBedRender3 as any as TestBedStatic;
} }
static get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND): any { static get<T>(token: Type<T>|InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): any;
/**
* @deprecated from v8.0.0 use Type<T> or InjectionToken<T>
*/
static get(token: any, notFoundValue?: any): any;
static get(
token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND,
flags: InjectFlags = InjectFlags.Default): any {
return _getTestBedRender3().get(token, notFoundValue); return _getTestBedRender3().get(token, notFoundValue);
} }
@ -254,12 +263,18 @@ export class TestBedRender3 implements Injector, TestBed {
compileComponents(): Promise<any> { return this.compiler.compileComponents(); } compileComponents(): Promise<any> { return this.compiler.compileComponents(); }
get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND): any { get<T>(token: Type<T>|InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): any;
/**
* @deprecated from v8.0.0 use Type<T> or InjectionToken<T>
*/
get(token: any, notFoundValue?: any): any;
get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND,
flags: InjectFlags = InjectFlags.Default): any {
if (token === TestBedRender3) { if (token === TestBedRender3) {
return this; return this;
} }
const result = this.testModuleRef.injector.get(token, UNDEFINED); const result = this.testModuleRef.injector.get(token, UNDEFINED, flags);
return result === UNDEFINED ? this.compiler.injector.get(token, notFoundValue) : result; return result === UNDEFINED ? this.compiler.injector.get(token, notFoundValue, flags) : result;
} }
execute(tokens: any[], fn: Function, context?: any): any { execute(tokens: any[], fn: Function, context?: any): any {
@ -338,9 +353,11 @@ export class TestBedRender3 implements Injector, TestBed {
`It looks like '${stringify(type)}' has not been IVY compiled - it has no 'ngComponentDef' field`); `It looks like '${stringify(type)}' has not been IVY compiled - it has no 'ngComponentDef' field`);
} }
const noNgZone: boolean = this.get(ComponentFixtureNoNgZone, false); // TODO: Don't cast as `any`, proper type is boolean[]
const autoDetect: boolean = this.get(ComponentFixtureAutoDetect, false); const noNgZone = this.get(ComponentFixtureNoNgZone as any, false);
const ngZone: NgZone = noNgZone ? null : this.get(NgZone, null); // TODO: Don't cast as `any`, proper type is boolean[]
const autoDetect: boolean = this.get(ComponentFixtureAutoDetect as any, false);
const ngZone: NgZone|null = noNgZone ? null : this.get(NgZone as Type<NgZone|null>, null);
const componentFactory = new ComponentFactory(componentDef); const componentFactory = new ComponentFactory(componentDef);
const initComponent = () => { const initComponent = () => {
const componentRef = const componentRef =

View File

@ -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 {ApplicationInitStatus, CompilerOptions, Component, Directive, Injector, NgModule, NgModuleFactory, NgModuleRef, NgZone, Optional, Pipe, PlatformRef, Provider, SchemaMetadata, SkipSelf, StaticProvider, Type, ɵAPP_ROOT as APP_ROOT, ɵDepFlags as DepFlags, ɵInjectableDef as InjectableDef, ɵNodeFlags as NodeFlags, ɵclearOverrides as clearOverrides, ɵgetInjectableDef as getInjectableDef, ɵivyEnabled as ivyEnabled, ɵoverrideComponentView as overrideComponentView, ɵoverrideProvider as overrideProvider, ɵstringify as stringify} from '@angular/core'; import {ApplicationInitStatus, CompilerOptions, Component, Directive, InjectFlags, InjectionToken, Injector, NgModule, NgModuleFactory, NgModuleRef, NgZone, Optional, Pipe, PlatformRef, Provider, SchemaMetadata, SkipSelf, StaticProvider, Type, ɵAPP_ROOT as APP_ROOT, ɵDepFlags as DepFlags, ɵInjectableDef as InjectableDef, ɵNodeFlags as NodeFlags, ɵclearOverrides as clearOverrides, ɵgetInjectableDef as getInjectableDef, ɵivyEnabled as ivyEnabled, ɵoverrideComponentView as overrideComponentView, ɵoverrideProvider as overrideProvider, ɵstringify as stringify} from '@angular/core';
import {AsyncTestCompleter} from './async_test_completer'; import {AsyncTestCompleter} from './async_test_completer';
import {ComponentFixture} from './component_fixture'; import {ComponentFixture} from './component_fixture';
@ -56,6 +56,10 @@ export interface TestBed {
compileComponents(): Promise<any>; compileComponents(): Promise<any>;
get<T>(token: Type<T>|InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): any;
/**
* @deprecated from v8.0.0 use Type<T> or InjectionToken<T>
*/
get(token: any, notFoundValue?: any): any; get(token: any, notFoundValue?: any): any;
execute(tokens: any[], fn: Function, context?: any): any; execute(tokens: any[], fn: Function, context?: any): any;
@ -239,8 +243,16 @@ export class TestBedViewEngine implements Injector, TestBed {
return TestBedViewEngine as any as TestBedStatic; return TestBedViewEngine as any as TestBedStatic;
} }
static get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND) { static get<T>(token: Type<T>|InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): any;
return _getTestBedViewEngine().get(token, notFoundValue); /**
* @deprecated from v8.0.0 use Type<T> or InjectionToken<T>
* @suppress {duplicate}
*/
static get(token: any, notFoundValue?: any): any;
static get(
token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND,
flags: InjectFlags = InjectFlags.Default): any {
return _getTestBedViewEngine().get(token, notFoundValue, flags);
} }
static createComponent<T>(component: Type<T>): ComponentFixture<T> { static createComponent<T>(component: Type<T>): ComponentFixture<T> {
@ -469,15 +481,21 @@ export class TestBedViewEngine implements Injector, TestBed {
} }
} }
get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND): any { get<T>(token: Type<T>|InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): any;
/**
* @deprecated from v8.0.0 use Type<T> or InjectionToken<T>
*/
get(token: any, notFoundValue?: any): any;
get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND,
flags: InjectFlags = InjectFlags.Default): any {
this._initIfNeeded(); this._initIfNeeded();
if (token === TestBed) { if (token === TestBed) {
return this; return this;
} }
// Tests can inject things from the ng module and from the compiler, // Tests can inject things from the ng module and from the compiler,
// but the ng module can't inject things from the compiler and vice versa. // but the ng module can't inject things from the compiler and vice versa.
const result = this._moduleRef.injector.get(token, UNDEFINED); const result = this._moduleRef.injector.get(token, UNDEFINED, flags);
return result === UNDEFINED ? this._compiler.injector.get(token, notFoundValue) : result; return result === UNDEFINED ? this._compiler.injector.get(token, notFoundValue, flags) : result;
} }
execute(tokens: any[], fn: Function, context?: any): any { execute(tokens: any[], fn: Function, context?: any): any {
@ -599,9 +617,11 @@ export class TestBedViewEngine implements Injector, TestBed {
`Cannot create the component ${stringify(component)} as it was not imported into the testing module!`); `Cannot create the component ${stringify(component)} as it was not imported into the testing module!`);
} }
const noNgZone = this.get(ComponentFixtureNoNgZone, false); // TODO: Don't cast as `any`, proper type is boolean[]
const autoDetect: boolean = this.get(ComponentFixtureAutoDetect, false); const noNgZone = this.get(ComponentFixtureNoNgZone as any, false);
const ngZone: NgZone = noNgZone ? null : this.get(NgZone, null); // TODO: Don't cast as `any`, proper type is boolean[]
const autoDetect: boolean = this.get(ComponentFixtureAutoDetect as any, false);
const ngZone: NgZone|null = noNgZone ? null : this.get(NgZone as Type<NgZone|null>, null);
const testComponentRenderer: TestComponentRenderer = this.get(TestComponentRenderer); const testComponentRenderer: TestComponentRenderer = this.get(TestComponentRenderer);
const rootElId = `root${_nextRootElementId++}`; const rootElId = `root${_nextRootElementId++}`;
testComponentRenderer.insertRootElement(rootElId); testComponentRenderer.insertRootElement(rootElId);
@ -732,4 +752,4 @@ export function withModule(moduleDef: TestModuleMetadata, fn?: Function | null):
}; };
} }
return new InjectSetupWrapper(() => moduleDef); return new InjectSetupWrapper(() => moduleDef);
} }

View File

@ -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 {Component, Directive, InjectionToken, NgModule, Pipe, PlatformRef, SchemaMetadata, Type} from '@angular/core'; import {Component, Directive, InjectFlags, InjectionToken, NgModule, Pipe, PlatformRef, SchemaMetadata, Type} from '@angular/core';
import {ComponentFixture} from './component_fixture'; import {ComponentFixture} from './component_fixture';
import {MetadataOverride} from './metadata_override'; import {MetadataOverride} from './metadata_override';
@ -130,6 +130,10 @@ export interface TestBedStatic {
deps?: any[], deps?: any[],
}): TestBedStatic; }): TestBedStatic;
get<T>(token: Type<T>|InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): any;
/**
* @deprecated from v8.0.0 use Type<T> or InjectionToken<T>
*/
get(token: any, notFoundValue?: any): any; get(token: any, notFoundValue?: any): any;
createComponent<T>(component: Type<T>): ComponentFixture<T>; createComponent<T>(component: Type<T>): ComponentFixture<T>;

View File

@ -62,15 +62,16 @@ export interface TestBed {
useValue?: any; useValue?: any;
deps?: any[]; deps?: any[];
}): void; }): void;
deprecatedOverrideProvider(token: any, provider: {
useValue: any;
}): void;
/** @deprecated */ deprecatedOverrideProvider(token: any, provider: { /** @deprecated */ deprecatedOverrideProvider(token: any, provider: {
useFactory: Function; useFactory: Function;
deps: any[]; deps: any[];
}): void; }): void;
deprecatedOverrideProvider(token: any, provider: {
useValue: any;
}): void;
execute(tokens: any[], fn: Function, context?: any): any; execute(tokens: any[], fn: Function, context?: any): any;
get(token: any, notFoundValue?: any): any; get<T>(token: Type<T> | InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): any;
/** @deprecated */ get(token: any, notFoundValue?: any): any;
initTestEnvironment(ngModule: Type<any> | Type<any>[], platform: PlatformRef, aotSummaries?: () => any[]): void; initTestEnvironment(ngModule: Type<any> | Type<any>[], platform: PlatformRef, aotSummaries?: () => any[]): void;
overrideComponent(component: Type<any>, override: MetadataOverride<Component>): void; overrideComponent(component: Type<any>, override: MetadataOverride<Component>): void;
overrideDirective(directive: Type<any>, override: MetadataOverride<Directive>): void; overrideDirective(directive: Type<any>, override: MetadataOverride<Directive>): void;
@ -82,11 +83,11 @@ export interface TestBed {
deps?: any[]; deps?: any[];
}): void; }): void;
overrideProvider(token: any, provider: { overrideProvider(token: any, provider: {
useFactory: Function; useValue: any;
deps: any[];
}): void; }): void;
overrideProvider(token: any, provider: { overrideProvider(token: any, provider: {
useValue: any; useFactory: Function;
deps: any[];
}): void; }): void;
overrideTemplateUsingTestingModule(component: Type<any>, template: string): void; overrideTemplateUsingTestingModule(component: Type<any>, template: string): void;
resetTestEnvironment(): void; resetTestEnvironment(): void;
@ -116,7 +117,8 @@ export interface TestBedStatic {
useFactory: Function; useFactory: Function;
deps: any[]; deps: any[];
}): void; }): void;
get(token: any, notFoundValue?: any): any; /** @deprecated */ get(token: any, notFoundValue?: any): any;
get<T>(token: Type<T> | InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): any;
initTestEnvironment(ngModule: Type<any> | Type<any>[], platform: PlatformRef, aotSummaries?: () => any[]): TestBed; initTestEnvironment(ngModule: Type<any> | Type<any>[], platform: PlatformRef, aotSummaries?: () => any[]): TestBed;
overrideComponent(component: Type<any>, override: MetadataOverride<Component>): TestBedStatic; overrideComponent(component: Type<any>, override: MetadataOverride<Component>): TestBedStatic;
overrideDirective(directive: Type<any>, override: MetadataOverride<Directive>): TestBedStatic; overrideDirective(directive: Type<any>, override: MetadataOverride<Directive>): TestBedStatic;