refactor(testing): introduce new testing api to support ng modules

BREAKING CHANGE:
- deprecations:
  * `withProviders`, use `TestBed.withModule` instead
  * `addProviders`, use `TestBed.configureTestingModule` instead
  * `TestComponentBuilder`, use `TestBed.configureTestModule` / `TestBed.override...` / `TestBed.createComponent` instead.

Closes #10354
This commit is contained in:
Tobias Bosch
2016-07-28 04:54:49 -07:00
parent acc6c8d0b7
commit d0a95e35af
45 changed files with 1090 additions and 501 deletions

View File

@ -0,0 +1,18 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Type used for modifications to metadata
*
* @experimental
*/
export type MetadataOverride<T> = {
add?: T,
remove?: T,
set?: T
};

View File

@ -6,42 +6,205 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Compiler, CompilerFactory, CompilerOptions, ComponentStillLoadingError, Injector, NgModule, NgModuleFactory, NgModuleMetadata, NgModuleRef, PlatformRef, Provider, ReflectiveInjector, SchemaMetadata, Type, assertPlatform, createPlatform, getPlatform} from '../index';
import {CompilerOptions, ComponentFactory, ComponentMetadataType, ComponentStillLoadingError, DirectiveMetadataType, Injector, ModuleWithComponentFactories, NgModule, NgModuleFactory, NgModuleMetadataType, NgModuleRef, NgZone, OpaqueToken, PipeMetadataType, PlatformRef, Provider, ReflectiveInjector, SchemaMetadata, Type, assertPlatform, createPlatform, getPlatform} from '../index';
import {ListWrapper} from '../src/facade/collection';
import {BaseException} from '../src/facade/exceptions';
import {ConcreteType, FunctionWrapper, isPresent, stringify} from '../src/facade/lang';
import {AsyncTestCompleter} from './async_test_completer';
import {ComponentFixture} from './component_fixture';
import {MetadataOverride} from './metadata_override';
import {TestingCompiler, TestingCompilerFactory} from './test_compiler';
const UNDEFINED = new Object();
/**
* An abstract class for inserting the root test component element in a platform independent way.
*
* @experimental
*/
export class TestComponentRenderer {
insertRootElement(rootElementId: string) {}
}
var _nextRootElementId = 0;
/**
* @experimental
*/
export var ComponentFixtureAutoDetect = new OpaqueToken('ComponentFixtureAutoDetect');
/**
* @experimental
*/
export var ComponentFixtureNoNgZone = new OpaqueToken('ComponentFixtureNoNgZone');
/**
* @experimental
*/
export type TestModuleMetadata = {
providers?: any[]; declarations?: any[]; imports?: any[]; schemas?: Array<SchemaMetadata|any[]>;
}
/**
* @experimental
*/
export class TestBed implements Injector {
/**
* Initialize the environment for testing with a compiler factory, a PlatformRef, and an
* angular module. These are common to every test in the suite.
*
* This may only be called once, to set up the common providers for the current test
* suite on the current platform. If you absolutely need to change the providers,
* first use `resetTestEnvironment`.
*
* Test modules and platforms for individual platforms are available from
* 'angular2/platform/testing/<platform_name>'.
*
* @experimental
*/
static initTestEnvironment(ngModule: Type, platform: PlatformRef): TestBed {
const testBed = getTestBed();
getTestBed().initTestEnvironment(ngModule, platform);
return testBed;
}
/**
* Reset the providers for the test injector.
*
* @experimental
*/
static resetTestEnvironment() { getTestBed().resetTestEnvironment(); }
static resetTestingModule(): typeof TestBed {
getTestBed().resetTestingModule();
return TestBed;
}
/**
* Allows overriding default compiler providers and settings
* which are defined in test_injector.js
*/
static configureCompiler(config: {providers?: any[]; useJit?: boolean;}): typeof TestBed {
getTestBed().configureCompiler(config);
return TestBed;
}
/**
* Allows overriding default providers, directives, pipes, modules of the test injector,
* which are defined in test_injector.js
*/
static configureTestingModule(moduleDef: TestModuleMetadata): typeof TestBed {
getTestBed().configureTestingModule(moduleDef);
return TestBed;
}
/**
* Compile components with a `templateUrl` for the test's NgModule.
* It is necessary to call this function
* as fetching urls is asynchronous.
*/
static compileComponents(): Promise<any> { return getTestBed().compileComponents(); }
static overrideModule(
ngModule: ConcreteType<any>,
override: MetadataOverride<NgModuleMetadataType>): typeof TestBed {
getTestBed().overrideModule(ngModule, override);
return TestBed;
}
static overrideComponent(
component: ConcreteType<any>,
override: MetadataOverride<ComponentMetadataType>): typeof TestBed {
getTestBed().overrideComponent(component, override);
return TestBed;
}
static overrideDirective(
directive: ConcreteType<any>,
override: MetadataOverride<DirectiveMetadataType>): typeof TestBed {
getTestBed().overrideDirective(directive, override);
return TestBed;
}
static overridePipe(pipe: ConcreteType<any>, override: MetadataOverride<PipeMetadataType>):
typeof TestBed {
getTestBed().overridePipe(pipe, override);
return TestBed;
}
static createComponent<T>(component: ConcreteType<T>): ComponentFixture<T> {
return getTestBed().createComponent(component);
}
private _instantiated: boolean = false;
private _compiler: Compiler = null;
private _compiler: TestingCompiler = null;
private _moduleRef: NgModuleRef<any> = null;
private _ngModuleFactory: NgModuleFactory<any> = null;
private _moduleWithComponentFactories: ModuleWithComponentFactories<any> = null;
private _compilerOptions: CompilerOptions[] = [];
private _moduleOverrides: [ConcreteType<any>, MetadataOverride<NgModuleMetadataType>][] = [];
private _componentOverrides: [ConcreteType<any>, MetadataOverride<ComponentMetadataType>][] = [];
private _directiveOverrides: [ConcreteType<any>, MetadataOverride<DirectiveMetadataType>][] = [];
private _pipeOverrides: [ConcreteType<any>, MetadataOverride<PipeMetadataType>][] = [];
private _providers: Array<Type|Provider|any[]|any> = [];
private _declarations: Array<Type|any[]|any> = [];
private _imports: Array<Type|any[]|any> = [];
private _entryComponents: Array<Type|any[]|any> = [];
private _schemas: Array<SchemaMetadata|any[]> = [];
reset() {
/**
* Initialize the environment for testing with a compiler factory, a PlatformRef, and an
* angular module. These are common to every test in the suite.
*
* This may only be called once, to set up the common providers for the current test
* suite on the current platform. If you absolutely need to change the providers,
* first use `resetTestEnvironment`.
*
* Test modules and platforms for individual platforms are available from
* 'angular2/platform/testing/<platform_name>'.
*
* @experimental
*/
initTestEnvironment(ngModule: Type, platform: PlatformRef) {
if (this.platform || this.ngModule) {
throw new BaseException('Cannot set base providers because it has already been called');
}
this.platform = platform;
this.ngModule = ngModule;
}
/**
* Reset the providers for the test injector.
*
* @experimental
*/
resetTestEnvironment() {
this.resetTestingModule();
this.platform = null;
this.ngModule = null;
}
/**
* @deprecated use `resetTestingModule` instead
*/
reset() { this.resetTestingModule(); }
resetTestingModule() {
this._compiler = null;
this._moduleOverrides = [];
this._componentOverrides = [];
this._directiveOverrides = [];
this._pipeOverrides = [];
this._moduleRef = null;
this._ngModuleFactory = null;
this._moduleWithComponentFactories = null;
this._compilerOptions = [];
this._providers = [];
this._declarations = [];
this._imports = [];
this._entryComponents = [];
this._schemas = [];
this._instantiated = false;
}
@ -51,22 +214,12 @@ export class TestBed implements Injector {
ngModule: Type = null;
configureCompiler(config: {providers?: any[], useJit?: boolean}) {
if (this._instantiated) {
throw new BaseException('Cannot add configuration after test injector is instantiated');
}
this._assertNotInstantiated('TestBed.configureCompiler', 'configure the compiler');
this._compilerOptions.push(config);
}
configureModule(moduleDef: {
providers?: any[],
declarations?: any[],
imports?: any[],
entryComponents?: any[],
schemas?: Array<SchemaMetadata|any>
}) {
if (this._instantiated) {
throw new BaseException('Cannot add configuration after test injector is instantiated');
}
configureTestingModule(moduleDef: TestModuleMetadata) {
this._assertNotInstantiated('TestBed.configureTestingModule', 'configure the test module');
if (moduleDef.providers) {
this._providers = ListWrapper.concat(this._providers, moduleDef.providers);
}
@ -76,109 +229,141 @@ export class TestBed implements Injector {
if (moduleDef.imports) {
this._imports = ListWrapper.concat(this._imports, moduleDef.imports);
}
if (moduleDef.entryComponents) {
this._entryComponents = ListWrapper.concat(this._entryComponents, moduleDef.entryComponents);
}
if (moduleDef.schemas) {
this._schemas = ListWrapper.concat(this._schemas, moduleDef.schemas);
}
}
createModuleFactory(): Promise<NgModuleFactory<any>> {
if (this._instantiated) {
throw new BaseException(
'Cannot compile entryComponents when the test NgModule has already been instantiated. ' +
'Make sure you are not using `inject` before `doAsyncEntryPointCompilation`.');
}
if (this._ngModuleFactory) {
return Promise.resolve(this._ngModuleFactory);
compileComponents(): Promise<any> {
if (this._moduleWithComponentFactories || this._instantiated) {
return Promise.resolve(null);
}
const moduleType = this._createCompilerAndModule();
return this._compiler.compileModuleAsync(moduleType).then((ngModuleFactory) => {
this._ngModuleFactory = ngModuleFactory;
return ngModuleFactory;
});
return this._compiler.compileModuleAndAllComponentsAsync(moduleType)
.then((moduleAndComponentFactories) => {
this._moduleWithComponentFactories = moduleAndComponentFactories;
});
}
initTestModule() {
private _initIfNeeded() {
if (this._instantiated) {
return;
}
if (this._ngModuleFactory) {
this._createFromModuleFactory(this._ngModuleFactory);
} else {
let moduleType = this._createCompilerAndModule();
this._createFromModuleFactory(this._compiler.compileModuleSync(moduleType));
if (!this._moduleWithComponentFactories) {
try {
let moduleType = this._createCompilerAndModule();
this._moduleWithComponentFactories =
this._compiler.compileModuleAndAllComponentsSync(moduleType);
} catch (e) {
if (e instanceof ComponentStillLoadingError) {
throw new Error(
`This test module uses the component ${stringify(e.compType)} which is using a "templateUrl", but they were never compiled. ` +
`Please call "TestBed.compileComponents" before your test.`);
} else {
throw e;
}
}
}
}
/**
* @internal
*/
_createInjectorAsync(): Promise<Injector> {
if (this._instantiated) {
return Promise.resolve(this);
}
let ngModule = this._createCompilerAndModule();
return this._compiler.compileModuleAsync(ngModule).then(
(ngModuleFactory) => this._createFromModuleFactory(ngModuleFactory));
this._moduleRef =
this._moduleWithComponentFactories.ngModuleFactory.create(this.platform.injector);
this._instantiated = true;
}
private _createCompilerAndModule(): ConcreteType<any> {
const providers = this._providers.concat([{provide: TestBed, useValue: this}]);
const declarations = this._declarations;
const imports = [this.ngModule, this._imports];
const entryComponents = this._entryComponents;
const schemas = this._schemas;
@NgModule({
providers: providers,
declarations: declarations,
imports: imports,
entryComponents: entryComponents,
schemas: schemas
})
@NgModule(
{providers: providers, declarations: declarations, imports: imports, schemas: schemas})
class DynamicTestModule {
}
const compilerFactory: CompilerFactory = this.platform.injector.get(CompilerFactory);
const compilerFactory: TestingCompilerFactory =
this.platform.injector.get(TestingCompilerFactory);
this._compiler =
compilerFactory.createCompiler(this._compilerOptions.concat([{useDebug: true}]));
compilerFactory.createTestingCompiler(this._compilerOptions.concat([{useDebug: true}]));
this._moduleOverrides.forEach((entry) => this._compiler.overrideModule(entry[0], entry[1]));
this._componentOverrides.forEach(
(entry) => this._compiler.overrideComponent(entry[0], entry[1]));
this._directiveOverrides.forEach(
(entry) => this._compiler.overrideDirective(entry[0], entry[1]));
this._pipeOverrides.forEach((entry) => this._compiler.overridePipe(entry[0], entry[1]));
return DynamicTestModule;
}
private _createFromModuleFactory(ngModuleFactory: NgModuleFactory<any>): Injector {
this._moduleRef = ngModuleFactory.create(this.platform.injector);
this._instantiated = true;
return this;
private _assertNotInstantiated(methodName: string, methodDescription: string) {
if (this._instantiated) {
throw new BaseException(
`Cannot ${methodDescription} when the test module has already been instantiated. ` +
`Make sure you are not using \`inject\` before \`${methodName}\`.`);
}
}
get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND) {
if (!this._instantiated) {
throw new BaseException(
'Illegal state: The test bed\'s injector has not yet been created. Call initTestModule first!');
}
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.
let result = this._moduleRef.injector.get(token, UNDEFINED);
return result === UNDEFINED ? this._compiler._injector.get(token, notFoundValue) : result;
return result === UNDEFINED ? this._compiler.injector.get(token, notFoundValue) : result;
}
execute(tokens: any[], fn: Function): any {
if (!this._instantiated) {
throw new BaseException(
'Illegal state: The test bed\'s injector has not yet been created. Call initTestModule first!');
}
this._initIfNeeded();
var params = tokens.map(t => this.get(t));
return FunctionWrapper.apply(fn, params);
}
overrideModule(ngModule: ConcreteType<any>, override: MetadataOverride<NgModuleMetadataType>):
void {
this._assertNotInstantiated('overrideModule', 'override module metadata');
this._moduleOverrides.push([ngModule, override]);
}
overrideComponent(
component: ConcreteType<any>, override: MetadataOverride<ComponentMetadataType>): void {
this._assertNotInstantiated('overrideComponent', 'override component metadata');
this._componentOverrides.push([component, override]);
}
overrideDirective(
directive: ConcreteType<any>, override: MetadataOverride<DirectiveMetadataType>): void {
this._assertNotInstantiated('overrideDirective', 'override directive metadata');
this._directiveOverrides.push([directive, override]);
}
overridePipe(pipe: ConcreteType<any>, override: MetadataOverride<PipeMetadataType>): void {
this._assertNotInstantiated('overridePipe', 'override pipe metadata');
this._pipeOverrides.push([pipe, override]);
}
createComponent<T>(component: ConcreteType<T>): ComponentFixture<T> {
this._initIfNeeded();
const componentFactory = this._moduleWithComponentFactories.componentFactories.find(
(compFactory) => compFactory.componentType === component);
if (!componentFactory) {
throw new BaseException(
`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);
const testComponentRenderer: TestComponentRenderer = this.get(TestComponentRenderer);
const rootElId = `root${_nextRootElementId++}`;
testComponentRenderer.insertRootElement(rootElId);
const initComponent = () => {
var componentRef = componentFactory.create(this, [], `#${rootElId}`);
return new ComponentFixture<T>(componentRef, ngZone, autoDetect);
};
return ngZone == null ? initComponent() : ngZone.run(initComponent);
}
}
var _testBed: TestBed = null;
@ -211,7 +396,7 @@ export function getTestInjector() {
* Test modules and platforms for individual platforms are available from
* 'angular2/platform/testing/<platform_name>'.
*
* @deprecated Use initTestEnvironment instead
* @deprecated Use TestBed.initTestEnvironment instead
*/
export function setBaseTestProviders(
platformProviders: Array<Type|Provider|any[]>,
@ -220,65 +405,17 @@ export function setBaseTestProviders(
(<any>platformProviders[0])(applicationProviders);
} else {
throw new Error(
`setBaseTestProviders is deprecated and only supports platformProviders that are predefined by Angular. Use 'initTestEnvironment' instead.`);
`setBaseTestProviders is deprecated and only supports platformProviders that are predefined by Angular. Use 'TestBed.initTestEnvironment' instead.`);
}
}
/**
* Initialize the environment for testing with a compiler factory, a PlatformRef, and an
* angular module. These are common to every test in the suite.
*
* This may only be called once, to set up the common providers for the current test
* suite on the current platform. If you absolutely need to change the providers,
* first use `resetTestEnvironment`.
*
* Test modules and platforms for individual platforms are available from
* 'angular2/platform/testing/<platform_name>'.
*
* @experimental
*/
export function initTestEnvironment(ngModule: Type, platform: PlatformRef): Injector {
var testBed = getTestBed();
if (testBed.platform || testBed.ngModule) {
throw new BaseException('Cannot set base providers because it has already been called');
}
testBed.platform = platform;
testBed.ngModule = ngModule;
return testBed;
}
/**
* Reset the providers for the test injector.
*
* @deprecated Use resetTestEnvironment instead.
* @deprecated Use TestBed.resetTestEnvironment instead.
*/
export function resetBaseTestProviders() {
resetTestEnvironment();
}
/**
* Reset the providers for the test injector.
*
* @experimental
*/
export function resetTestEnvironment() {
var testBed = getTestBed();
testBed.platform = null;
testBed.ngModule = null;
testBed.reset();
}
/**
* Compile entryComponents with a `templateUrl` for the test's NgModule.
* It is necessary to call this function
* as fetching urls is asynchronous.
*
* @experimental
*/
export function doAsyncEntryPointCompilation(): Promise<any> {
let testBed = getTestBed();
return testBed.createModuleFactory();
TestBed.resetTestEnvironment();
}
/**
@ -308,30 +445,17 @@ export function doAsyncEntryPointCompilation(): Promise<any> {
export function inject(tokens: any[], fn: Function): () => any {
let testBed = getTestBed();
if (tokens.indexOf(AsyncTestCompleter) >= 0) {
return () => {
// Return an async test method that returns a Promise if AsyncTestCompleter is one of the
// injected tokens.
return testBed._createInjectorAsync().then(() => {
let completer: AsyncTestCompleter = testBed.get(AsyncTestCompleter);
testBed.execute(tokens, fn);
return completer.promise;
});
};
return () =>
// Return an async test method that returns a Promise if AsyncTestCompleter is one of
// the
// injected tokens.
testBed.compileComponents().then(() => {
let completer: AsyncTestCompleter = testBed.get(AsyncTestCompleter);
testBed.execute(tokens, fn);
return completer.promise;
});
} else {
return () => {
try {
testBed.initTestModule();
} catch (e) {
if (e instanceof ComponentStillLoadingError) {
throw new Error(
`This test module uses the entryComponents ${stringify(e.compType)} which is using a "templateUrl", but they were never compiled. ` +
`Please call "doAsyncEntryPointCompilation" before "inject".`);
} else {
throw e;
}
}
return testBed.execute(tokens, fn);
};
return () => testBed.execute(tokens, fn);
}
}
@ -339,17 +463,12 @@ export function inject(tokens: any[], fn: Function): () => any {
* @experimental
*/
export class InjectSetupWrapper {
constructor(private _moduleDef: () => {
providers?: any[],
declarations?: any[],
imports?: any[],
entryComponents?: any[]
}) {}
constructor(private _moduleDef: () => TestModuleMetadata) {}
private _addModule() {
var moduleDef = this._moduleDef();
const moduleDef = this._moduleDef();
if (moduleDef) {
getTestBed().configureModule(moduleDef);
getTestBed().configureTestingModule(moduleDef);
}
}
@ -362,21 +481,27 @@ export class InjectSetupWrapper {
}
/**
* @experimental
* @deprecated Use `TestBed.configureTestingModule instead.
*/
export function withProviders(providers: () => any) {
return new InjectSetupWrapper(() => {{return {providers: providers()};}});
return new InjectSetupWrapper(() => { return {providers: providers()}; });
}
/**
* @experimental
*/
export function withModule(moduleDef: () => {
providers?: any[],
declarations?: any[],
imports?: any[],
entryComponents?: any[],
schemas?: Array<SchemaMetadata|any[]>
}) {
return new InjectSetupWrapper(moduleDef);
export function withModule(moduleDef: TestModuleMetadata): InjectSetupWrapper;
export function withModule(moduleDef: TestModuleMetadata, fn: Function): () => any;
export function withModule(moduleDef: TestModuleMetadata, fn: Function = null): (() => any)|
InjectSetupWrapper {
if (fn) {
return () => {
const testBed = getTestBed();
if (moduleDef) {
testBed.configureTestingModule(moduleDef);
}
return fn();
};
}
return new InjectSetupWrapper(() => moduleDef);
}

View File

@ -0,0 +1,45 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {Compiler, CompilerOptions, ComponentMetadataType, DirectiveMetadataType, Injector, NgModuleFactory, NgModuleMetadataType, PipeMetadataType} from '../index';
import {unimplemented} from '../src/facade/exceptions';
import {ConcreteType} from '../src/facade/lang';
import {MetadataOverride} from './metadata_override';
/**
* Special interface to the compiler only used by testing
*
* @experimental
*/
export class TestingCompiler extends Compiler {
get injector(): Injector { throw unimplemented(); }
overrideModule(module: ConcreteType<any>, overrides: MetadataOverride<NgModuleMetadataType>):
void {
throw unimplemented();
}
overrideDirective(
directive: ConcreteType<any>, overrides: MetadataOverride<DirectiveMetadataType>): void {
throw unimplemented();
}
overrideComponent(
component: ConcreteType<any>, overrides: MetadataOverride<ComponentMetadataType>): void {
throw unimplemented();
}
overridePipe(directive: ConcreteType<any>, overrides: MetadataOverride<PipeMetadataType>): void {
throw unimplemented();
}
}
/**
* A factory for creating a Compiler
*
* @experimental
*/
export abstract class TestingCompilerFactory {
abstract createTestingCompiler(options?: CompilerOptions[]): TestingCompiler;
}

View File

@ -13,32 +13,15 @@ import {ConcreteType, IS_DART, Type, isPresent} from '../src/facade/lang';
import {ComponentFixture} from './component_fixture';
import {tick} from './fake_async';
/**
* An abstract class for inserting the root test component element in a platform independent way.
*
* @experimental
*/
export class TestComponentRenderer {
insertRootElement(rootElementId: string) {}
}
/**
* @experimental
*/
export var ComponentFixtureAutoDetect = new OpaqueToken('ComponentFixtureAutoDetect');
/**
* @experimental
*/
export var ComponentFixtureNoNgZone = new OpaqueToken('ComponentFixtureNoNgZone');
import {ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, TestComponentRenderer} from './test_bed';
var _nextRootElementId = 0;
/**
* Builds a ComponentFixture for use in component level tests.
* @stable
*
* @deprecated Use `TestBed.configureTestModule` / `TestBed.override...` / `TestBed.createComponent`
* instead.
*/
@Injectable()
export class TestComponentBuilder {
@ -119,27 +102,25 @@ export class TestComponentBuilder {
/**
* Builds and returns a ComponentFixture.
*/
createAsync<T>(rootComponentType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
Promise<ComponentFixture<T>> {
createAsync<T>(rootComponentType: ConcreteType<T>): Promise<ComponentFixture<T>> {
let noNgZone = IS_DART || this._injector.get(ComponentFixtureNoNgZone, false);
let ngZone: NgZone = noNgZone ? null : this._injector.get(NgZone, null);
let compiler: Compiler = this._injector.get(Compiler);
let initComponent = () => {
let promise: Promise<ComponentFactory<any>> =
compiler.compileComponentAsync(rootComponentType, ngModule);
compiler.compileComponentAsync(rootComponentType);
return promise.then(componentFactory => this.createFromFactory(ngZone, componentFactory));
};
return ngZone == null ? initComponent() : ngZone.run(initComponent);
}
createFakeAsync<T>(rootComponentType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
ComponentFixture<T> {
createFakeAsync<T>(rootComponentType: ConcreteType<T>): ComponentFixture<T> {
let result: any /** TODO #9100 */;
let error: any /** TODO #9100 */;
PromiseWrapper.then(
this.createAsync(rootComponentType, ngModule), (_result) => { result = _result; },
this.createAsync(rootComponentType), (_result) => { result = _result; },
(_error) => { error = _error; });
tick();
if (isPresent(error)) {
@ -148,15 +129,13 @@ export class TestComponentBuilder {
return result;
}
createSync<T>(rootComponentType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
ComponentFixture<T> {
createSync<T>(rootComponentType: ConcreteType<T>): ComponentFixture<T> {
let noNgZone = IS_DART || this._injector.get(ComponentFixtureNoNgZone, false);
let ngZone: NgZone = noNgZone ? null : this._injector.get(NgZone, null);
let compiler: Compiler = this._injector.get(Compiler);
let initComponent = () => {
return this.createFromFactory(
ngZone, compiler.compileComponentSync(rootComponentType, ngModule));
return this.createFromFactory(ngZone, compiler.compileComponentSync(rootComponentType));
};
return ngZone == null ? initComponent() : ngZone.run(initComponent);

View File

@ -13,75 +13,25 @@
*/
import {SchemaMetadata} from '../index';
import {TestBed, getTestBed} from './test_bed';
import {TestBed, TestModuleMetadata, getTestBed} from './test_bed';
declare var global: any;
var _global = <any>(typeof window === 'undefined' ? global : window);
var testBed: TestBed = getTestBed();
// Reset the test providers before each test.
if (_global.beforeEach) {
_global.beforeEach(() => { testBed.reset(); });
_global.beforeEach(() => { TestBed.resetTestingModule(); });
}
/**
* Allows overriding default providers of the test injector,
* which are defined in test_injector.js
*
* @stable
* @deprecated Use `TestBed.configureTestingModule instead.
*/
export function addProviders(providers: Array<any>): void {
if (!providers) return;
try {
testBed.configureModule({providers: providers});
} catch (e) {
throw new Error(
'addProviders can\'t be called after the injector has been already created for this test. ' +
'This is most likely because you\'ve already used the injector to inject a beforeEach or the ' +
'current `it` function.');
}
}
/**
* Allows overriding default providers, directives, pipes, modules of the test injector,
* which are defined in test_injector.js
*
* @stable
*/
export function configureModule(moduleDef: {
providers?: any[],
declarations?: any[],
imports?: any[],
entryComponents?: any[],
schemas?: Array<SchemaMetadata|any[]>
}): void {
if (!moduleDef) return;
try {
testBed.configureModule(moduleDef);
} catch (e) {
throw new Error(
'configureModule can\'t be called after the injector has been already created for this test. ' +
'This is most likely because you\'ve already used the injector to inject a beforeEach or the ' +
'current `it` function.');
}
}
/**
* Allows overriding default compiler providers and settings
* which are defined in test_injector.js
*
* @stable
*/
export function configureCompiler(config: {providers?: any[], useJit?: boolean}): void {
if (!config) return;
try {
testBed.configureCompiler(config);
} catch (e) {
throw new Error(
'configureCompiler can\'t be called after the injector has been already created for this test. ' +
'This is most likely because you\'ve already used the injector to inject a beforeEach or the ' +
'current `it` function.');
}
TestBed.configureTestingModule({providers: providers});
}

View File

@ -61,7 +61,7 @@ class BeforeEachRunner {
}
// Reset the test providers before each test
jsmBeforeEach(() => { testBed.reset(); });
jsmBeforeEach(() => { testBed.resetTestingModule(); });
function _describe(jsmFn: any /** TODO #9100 */, ...args: any[] /** TODO #9100 */) {
var parentRunner = runnerStack.length === 0 ? null : runnerStack[runnerStack.length - 1];
@ -110,7 +110,7 @@ export function beforeEachProviders(fn: any /** TODO #9100 */): void {
jsmBeforeEach(() => {
var providers = fn();
if (!providers) return;
testBed.configureModule({providers: providers});
testBed.configureTestingModule({providers: providers});
});
}
@ -138,7 +138,7 @@ function _it(jsmFn: Function, name: string, testFn: Function, testTimeOut: numbe
return new AsyncTestCompleter();
}
};
testBed.configureModule({providers: [completerProvider]});
testBed.configureTestingModule({providers: [completerProvider]});
runner.run();
inIt = true;