From 609024f93dc2df038ca5c3d8bfc2406ca5a2a6ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Ortiz=20Garc=C3=ADa?= Date: Wed, 3 Apr 2019 10:23:46 -0700 Subject: [PATCH] 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 --- packages/core/testing/src/r3_test_bed.ts | 31 +++++++++++---- packages/core/testing/src/test_bed.ts | 40 +++++++++++++++----- packages/core/testing/src/test_bed_common.ts | 6 ++- tools/public_api_guard/core/testing.d.ts | 18 +++++---- 4 files changed, 69 insertions(+), 26 deletions(-) diff --git a/packages/core/testing/src/r3_test_bed.ts b/packages/core/testing/src/r3_test_bed.ts index 5c987de4c3..98d36d8bee 100644 --- a/packages/core/testing/src/r3_test_bed.ts +++ b/packages/core/testing/src/r3_test_bed.ts @@ -13,6 +13,8 @@ import { Component, Directive, + InjectFlags, + InjectionToken, Injector, NgModule, NgZone, @@ -167,7 +169,14 @@ export class TestBedRender3 implements Injector, TestBed { return TestBedRender3 as any as TestBedStatic; } - static get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND): any { + static get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + /** + * @deprecated from v8.0.0 use Type or InjectionToken + */ + 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); } @@ -254,12 +263,18 @@ export class TestBedRender3 implements Injector, TestBed { compileComponents(): Promise { return this.compiler.compileComponents(); } - get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND): any { + get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + /** + * @deprecated from v8.0.0 use Type or InjectionToken + */ + get(token: any, notFoundValue?: any): any; + get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND, + flags: InjectFlags = InjectFlags.Default): any { if (token === TestBedRender3) { return this; } - const result = this.testModuleRef.injector.get(token, UNDEFINED); - return result === UNDEFINED ? this.compiler.injector.get(token, notFoundValue) : result; + const result = this.testModuleRef.injector.get(token, UNDEFINED, flags); + return result === UNDEFINED ? this.compiler.injector.get(token, notFoundValue, flags) : result; } 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`); } - const noNgZone: boolean = this.get(ComponentFixtureNoNgZone, false); - const autoDetect: boolean = this.get(ComponentFixtureAutoDetect, false); - const ngZone: NgZone = noNgZone ? null : this.get(NgZone, null); + // TODO: Don't cast as `any`, proper type is boolean[] + const noNgZone = this.get(ComponentFixtureNoNgZone as any, false); + // 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, null); const componentFactory = new ComponentFactory(componentDef); const initComponent = () => { const componentRef = diff --git a/packages/core/testing/src/test_bed.ts b/packages/core/testing/src/test_bed.ts index 40edac623e..44e7c21355 100644 --- a/packages/core/testing/src/test_bed.ts +++ b/packages/core/testing/src/test_bed.ts @@ -6,7 +6,7 @@ * 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 {ComponentFixture} from './component_fixture'; @@ -56,6 +56,10 @@ export interface TestBed { compileComponents(): Promise; + get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + /** + * @deprecated from v8.0.0 use Type or InjectionToken + */ get(token: any, notFoundValue?: 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; } - static get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND) { - return _getTestBedViewEngine().get(token, notFoundValue); + static get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + /** + * @deprecated from v8.0.0 use Type or InjectionToken + * @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(component: Type): ComponentFixture { @@ -469,15 +481,21 @@ export class TestBedViewEngine implements Injector, TestBed { } } - get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND): any { + get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + /** + * @deprecated from v8.0.0 use Type or InjectionToken + */ + get(token: any, notFoundValue?: any): any; + get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND, + flags: InjectFlags = InjectFlags.Default): any { this._initIfNeeded(); if (token === TestBed) { return this; } // 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. - const result = this._moduleRef.injector.get(token, UNDEFINED); - return result === UNDEFINED ? this._compiler.injector.get(token, notFoundValue) : result; + const result = this._moduleRef.injector.get(token, UNDEFINED, flags); + return result === UNDEFINED ? this._compiler.injector.get(token, notFoundValue, flags) : result; } 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!`); } - const noNgZone = this.get(ComponentFixtureNoNgZone, false); - const autoDetect: boolean = this.get(ComponentFixtureAutoDetect, false); - const ngZone: NgZone = noNgZone ? null : this.get(NgZone, null); + // TODO: Don't cast as `any`, proper type is boolean[] + const noNgZone = this.get(ComponentFixtureNoNgZone as any, false); + // 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, null); const testComponentRenderer: TestComponentRenderer = this.get(TestComponentRenderer); const rootElId = `root${_nextRootElementId++}`; testComponentRenderer.insertRootElement(rootElId); @@ -732,4 +752,4 @@ export function withModule(moduleDef: TestModuleMetadata, fn?: Function | null): }; } return new InjectSetupWrapper(() => moduleDef); -} \ No newline at end of file +} diff --git a/packages/core/testing/src/test_bed_common.ts b/packages/core/testing/src/test_bed_common.ts index 493179ccaf..822cc15f9e 100644 --- a/packages/core/testing/src/test_bed_common.ts +++ b/packages/core/testing/src/test_bed_common.ts @@ -6,7 +6,7 @@ * 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 {MetadataOverride} from './metadata_override'; @@ -130,6 +130,10 @@ export interface TestBedStatic { deps?: any[], }): TestBedStatic; + get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + /** + * @deprecated from v8.0.0 use Type or InjectionToken + */ get(token: any, notFoundValue?: any): any; createComponent(component: Type): ComponentFixture; diff --git a/tools/public_api_guard/core/testing.d.ts b/tools/public_api_guard/core/testing.d.ts index 560fa43b94..6cf7bd65dd 100644 --- a/tools/public_api_guard/core/testing.d.ts +++ b/tools/public_api_guard/core/testing.d.ts @@ -62,15 +62,16 @@ export interface TestBed { useValue?: any; deps?: any[]; }): void; + deprecatedOverrideProvider(token: any, provider: { + useValue: any; + }): void; /** @deprecated */ deprecatedOverrideProvider(token: any, provider: { useFactory: Function; deps: any[]; }): void; - deprecatedOverrideProvider(token: any, provider: { - useValue: any; - }): void; execute(tokens: any[], fn: Function, context?: any): any; - get(token: any, notFoundValue?: any): any; + get(token: Type | InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + /** @deprecated */ get(token: any, notFoundValue?: any): any; initTestEnvironment(ngModule: Type | Type[], platform: PlatformRef, aotSummaries?: () => any[]): void; overrideComponent(component: Type, override: MetadataOverride): void; overrideDirective(directive: Type, override: MetadataOverride): void; @@ -82,11 +83,11 @@ export interface TestBed { deps?: any[]; }): void; overrideProvider(token: any, provider: { - useFactory: Function; - deps: any[]; + useValue: any; }): void; overrideProvider(token: any, provider: { - useValue: any; + useFactory: Function; + deps: any[]; }): void; overrideTemplateUsingTestingModule(component: Type, template: string): void; resetTestEnvironment(): void; @@ -116,7 +117,8 @@ export interface TestBedStatic { useFactory: Function; deps: any[]; }): void; - get(token: any, notFoundValue?: any): any; + /** @deprecated */ get(token: any, notFoundValue?: any): any; + get(token: Type | InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; initTestEnvironment(ngModule: Type | Type[], platform: PlatformRef, aotSummaries?: () => any[]): TestBed; overrideComponent(component: Type, override: MetadataOverride): TestBedStatic; overrideDirective(directive: Type, override: MetadataOverride): TestBedStatic;