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

@ -9,7 +9,7 @@
import {NgFor, NgIf} from '@angular/common'; import {NgFor, NgIf} from '@angular/common';
import {Control, ControlGroup, ControlValueAccessor, DeprecatedFormsModule, NG_ASYNC_VALIDATORS, NG_VALIDATORS, NgControl, NgForm, RadioButtonState, Validator, Validators} from '@angular/common/src/forms-deprecated'; import {Control, ControlGroup, ControlValueAccessor, DeprecatedFormsModule, NG_ASYNC_VALIDATORS, NG_VALIDATORS, NgControl, NgForm, RadioButtonState, Validator, Validators} from '@angular/common/src/forms-deprecated';
import {Component, Directive, EventEmitter, Input, Output, Provider, forwardRef} from '@angular/core'; import {Component, Directive, EventEmitter, Input, Output, Provider, forwardRef} from '@angular/core';
import {ComponentFixture, TestComponentBuilder, configureModule, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing'; import {ComponentFixture, TestBed, TestComponentBuilder, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing';
import {AsyncTestCompleter, afterEach, beforeEach, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal'; import {AsyncTestCompleter, afterEach, beforeEach, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal';
import {By} from '@angular/platform-browser/src/dom/debug/by'; import {By} from '@angular/platform-browser/src/dom/debug/by';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
@ -22,7 +22,7 @@ import {PromiseWrapper} from '../../src/facade/promise';
export function main() { export function main() {
describe('integration tests', () => { describe('integration tests', () => {
beforeEach(() => configureModule({imports: [DeprecatedFormsModule]})); beforeEach(() => TestBed.configureTestingModule({imports: [DeprecatedFormsModule]}));
it('should initialize DOM elements with the given form object', it('should initialize DOM elements with the given form object',
inject( inject(

View File

@ -0,0 +1,15 @@
/**
* @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 {__core_private_testing__ as r, __core_private_testing_types__ as t} from '@angular/core/testing';
export type TestingCompiler = t.TestingCompiler;
export var TestingCompiler: typeof t.TestingCompiler = r.TestingCompiler;
export type TestingCompilerFactory = t.TestingCompilerFactory;
export var TestingCompilerFactory: typeof t.TestingCompilerFactory = r.TestingCompilerFactory;

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 {Compiler, ComponentFactory, ComponentResolver, ComponentStillLoadingError, Injectable, Injector, NgModule, NgModuleFactory, NgModuleMetadata, OptionalMetadata, Provider, SchemaMetadata, SkipSelfMetadata} from '@angular/core'; import {Compiler, ComponentFactory, ComponentResolver, ComponentStillLoadingError, Injectable, Injector, ModuleWithComponentFactories, NgModule, NgModuleFactory, NgModuleMetadata, OptionalMetadata, Provider, SchemaMetadata, SkipSelfMetadata} from '@angular/core';
import {Console} from '../core_private'; import {Console} from '../core_private';
import {BaseException} from '../src/facade/exceptions'; import {BaseException} from '../src/facade/exceptions';
@ -44,13 +44,13 @@ export class RuntimeCompiler implements Compiler {
private _compiledNgModuleCache = new Map<Type, NgModuleFactory<any>>(); private _compiledNgModuleCache = new Map<Type, NgModuleFactory<any>>();
constructor( constructor(
private __injector: Injector, private _metadataResolver: CompileMetadataResolver, private _injector: Injector, private _metadataResolver: CompileMetadataResolver,
private _templateNormalizer: DirectiveNormalizer, private _templateParser: TemplateParser, private _templateNormalizer: DirectiveNormalizer, private _templateParser: TemplateParser,
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler, private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler,
private _ngModuleCompiler: NgModuleCompiler, private _compilerConfig: CompilerConfig, private _ngModuleCompiler: NgModuleCompiler, private _compilerConfig: CompilerConfig,
private _console: Console) {} private _console: Console) {}
get _injector(): Injector { return this.__injector; } get injector(): Injector { return this._injector; }
compileModuleSync<T>(moduleType: ConcreteType<T>): NgModuleFactory<T> { compileModuleSync<T>(moduleType: ConcreteType<T>): NgModuleFactory<T> {
return this._compileModuleAndComponents(moduleType, true).syncResult; return this._compileModuleAndComponents(moduleType, true).syncResult;
@ -60,6 +60,16 @@ export class RuntimeCompiler implements Compiler {
return this._compileModuleAndComponents(moduleType, false).asyncResult; return this._compileModuleAndComponents(moduleType, false).asyncResult;
} }
compileModuleAndAllComponentsSync<T>(moduleType: ConcreteType<T>):
ModuleWithComponentFactories<T> {
return this._compileModuleAndAllComponents(moduleType, true).syncResult;
}
compileModuleAndAllComponentsAsync<T>(moduleType: ConcreteType<T>):
Promise<ModuleWithComponentFactories<T>> {
return this._compileModuleAndAllComponents(moduleType, false).asyncResult;
}
compileComponentAsync<T>(compType: ConcreteType<T>, ngModule: ConcreteType<any> = null): compileComponentAsync<T>(compType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
Promise<ComponentFactory<T>> { Promise<ComponentFactory<T>> {
if (!ngModule) { if (!ngModule) {
@ -85,6 +95,34 @@ export class RuntimeCompiler implements Compiler {
return new SyncAsyncResult(ngModuleFactory, componentPromise.then(() => ngModuleFactory)); return new SyncAsyncResult(ngModuleFactory, componentPromise.then(() => ngModuleFactory));
} }
private _compileModuleAndAllComponents<T>(moduleType: ConcreteType<T>, isSync: boolean):
SyncAsyncResult<ModuleWithComponentFactories<T>> {
const componentPromise = this._compileComponents(moduleType, isSync);
const ngModuleFactory = this._compileModule(moduleType);
const moduleMeta = this._metadataResolver.getNgModuleMetadata(moduleType);
const componentFactories: ComponentFactory<any>[] = [];
const templates = new Set<CompiledTemplate>();
moduleMeta.transitiveModule.modules.forEach((moduleMeta) => {
moduleMeta.declaredDirectives.forEach((dirMeta) => {
if (dirMeta.isComponent) {
const template = this._createCompiledHostTemplate(dirMeta.type.runtime);
templates.add(template);
componentFactories.push(template.proxyComponentFactory);
}
});
});
const syncResult = new ModuleWithComponentFactories(ngModuleFactory, componentFactories);
// Note: host components themselves can always be compiled synchronously as they have an
// inline template. However, we still need to wait for the components that they
// reference to be loaded / compiled.
const compile = () => {
templates.forEach((template) => { this._compileTemplate(template); });
return syncResult;
};
const asyncResult = isSync ? Promise.resolve(compile()) : componentPromise.then(compile);
return new SyncAsyncResult(syncResult, asyncResult);
}
private _compileModule<T>(moduleType: ConcreteType<T>): NgModuleFactory<T> { private _compileModule<T>(moduleType: ConcreteType<T>): NgModuleFactory<T> {
let ngModuleFactory = this._compiledNgModuleCache.get(moduleType); let ngModuleFactory = this._compiledNgModuleCache.get(moduleType);
if (!ngModuleFactory) { if (!ngModuleFactory) {
@ -381,7 +419,7 @@ class ModuleBoundCompiler implements Compiler, ComponentResolver {
private _delegate: RuntimeCompiler, private _ngModule: ConcreteType<any>, private _delegate: RuntimeCompiler, private _ngModule: ConcreteType<any>,
private _parentComponentResolver: ComponentResolver, private _console: Console) {} private _parentComponentResolver: ComponentResolver, private _console: Console) {}
get _injector(): Injector { return this._delegate._injector; } get _injector(): Injector { return this._delegate.injector; }
resolveComponent(component: Type|string): Promise<ComponentFactory<any>> { resolveComponent(component: Type|string): Promise<ComponentFactory<any>> {
if (isString(component)) { if (isString(component)) {
@ -416,6 +454,15 @@ class ModuleBoundCompiler implements Compiler, ComponentResolver {
compileModuleAsync<T>(moduleType: ConcreteType<T>): Promise<NgModuleFactory<T>> { compileModuleAsync<T>(moduleType: ConcreteType<T>): Promise<NgModuleFactory<T>> {
return this._delegate.compileModuleAsync(moduleType); return this._delegate.compileModuleAsync(moduleType);
} }
compileModuleAndAllComponentsSync<T>(moduleType: ConcreteType<T>):
ModuleWithComponentFactories<T> {
return this._delegate.compileModuleAndAllComponentsSync(moduleType);
}
compileModuleAndAllComponentsAsync<T>(moduleType: ConcreteType<T>):
Promise<ModuleWithComponentFactories<T>> {
return this._delegate.compileModuleAndAllComponentsAsync(moduleType);
}
/** /**
* Clears all caches * Clears all caches

View File

@ -12,7 +12,7 @@ import {DirectiveNormalizer} from '@angular/compiler/src/directive_normalizer';
import {XHR} from '@angular/compiler/src/xhr'; import {XHR} from '@angular/compiler/src/xhr';
import {MockXHR} from '@angular/compiler/testing/xhr_mock'; import {MockXHR} from '@angular/compiler/testing/xhr_mock';
import {ViewEncapsulation} from '@angular/core/src/metadata/view'; import {ViewEncapsulation} from '@angular/core/src/metadata/view';
import {configureCompiler} from '@angular/core/testing'; import {TestBed} from '@angular/core/testing';
import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal'; import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal';
import {SpyXHR} from './spies'; import {SpyXHR} from './spies';
@ -23,7 +23,7 @@ export function main() {
var dirType: CompileTypeMetadata; var dirType: CompileTypeMetadata;
var dirTypeWithHttpUrl: CompileTypeMetadata; var dirTypeWithHttpUrl: CompileTypeMetadata;
beforeEach(() => { configureCompiler({providers: TEST_COMPILER_PROVIDERS}); }); beforeEach(() => { TestBed.configureCompiler({providers: TEST_COMPILER_PROVIDERS}); });
beforeEach(() => { beforeEach(() => {
dirType = new CompileTypeMetadata({moduleUrl: 'package:some/module/a.js', name: 'SomeComp'}); dirType = new CompileTypeMetadata({moduleUrl: 'package:some/module/a.js', name: 'SomeComp'});
@ -179,7 +179,8 @@ export function main() {
describe('normalizeExternalStylesheets', () => { describe('normalizeExternalStylesheets', () => {
beforeEach(() => { configureCompiler({providers: [{provide: XHR, useClass: SpyXHR}]}); }); beforeEach(
() => { TestBed.configureCompiler({providers: [{provide: XHR, useClass: SpyXHR}]}); });
it('should load an external stylesheet', it('should load an external stylesheet',
inject( inject(

View File

@ -27,7 +27,7 @@ export function main() {
expect(ngModule.selector).toEqual('cmp'); expect(ngModule.selector).toEqual('cmp');
}); });
it('should allow overriding the @NgModule', () => { it('should allow overriding the @Directive', () => {
dirResolver.setDirective( dirResolver.setDirective(
SomeComponent, new ComponentMetadata({selector: 'someOtherSelector'})); SomeComponent, new ComponentMetadata({selector: 'someOtherSelector'}));
var metadata = dirResolver.resolve(SomeComponent); var metadata = dirResolver.resolve(SomeComponent);

View File

@ -0,0 +1,116 @@
/**
* @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 {expect} from '@angular/platform-browser/testing/matchers';
import {MetadataOverrider} from '../testing/metadata_overrider';
interface SomeMetadataType {
plainProp?: string;
getterProp?: string;
arrayProp?: any[];
}
class SomeMetadata implements SomeMetadataType {
plainProp: string;
private _getterProp: string;
get getterProp(): string { return this._getterProp; }
arrayProp: any[];
constructor(options: SomeMetadataType) {
this.plainProp = options.plainProp;
this._getterProp = options.getterProp;
this.arrayProp = options.arrayProp;
}
}
export function main() {
describe('metadata overrider', () => {
let overrider: MetadataOverrider;
beforeEach(() => { overrider = new MetadataOverrider(); });
it('should return a new instance with the same values', () => {
const oldInstance = new SomeMetadata({plainProp: 'somePlainProp', getterProp: 'someInput'});
const newInstance = overrider.overrideMetadata(SomeMetadata, oldInstance, {});
expect(newInstance).not.toBe(oldInstance);
expect(newInstance).toBeAnInstanceOf(SomeMetadata);
expect(newInstance).toEqual(oldInstance);
});
it('should set individual properties and keep others', () => {
const oldInstance =
new SomeMetadata({plainProp: 'somePlainProp', getterProp: 'someGetterProp'});
const newInstance =
overrider.overrideMetadata(SomeMetadata, oldInstance, {set: {plainProp: 'newPlainProp'}});
expect(newInstance)
.toEqual(new SomeMetadata({plainProp: 'newPlainProp', getterProp: 'someGetterProp'}));
});
describe('add properties', () => {
it('should replace non array values', () => {
const oldInstance =
new SomeMetadata({plainProp: 'somePlainProp', getterProp: 'someGetterProp'});
const newInstance = overrider.overrideMetadata(
SomeMetadata, oldInstance, {add: {plainProp: 'newPlainProp'}});
expect(newInstance)
.toEqual(new SomeMetadata({plainProp: 'newPlainProp', getterProp: 'someGetterProp'}));
});
it('should add to array values', () => {
const oldInstance = new SomeMetadata({arrayProp: ['a']});
const newInstance =
overrider.overrideMetadata(SomeMetadata, oldInstance, {add: {arrayProp: ['b']}});
expect(newInstance).toEqual(new SomeMetadata({arrayProp: ['a', 'b']}));
});
});
describe('remove', () => {
it('should set values to undefined if their value matches', () => {
const oldInstance =
new SomeMetadata({plainProp: 'somePlainProp', getterProp: 'someGetterProp'});
const newInstance = overrider.overrideMetadata(
SomeMetadata, oldInstance, {remove: {plainProp: 'somePlainProp'}});
expect(newInstance)
.toEqual(new SomeMetadata({plainProp: undefined, getterProp: 'someGetterProp'}));
});
it('should leave values if their value does not match', () => {
const oldInstance =
new SomeMetadata({plainProp: 'somePlainProp', getterProp: 'someGetterProp'});
const newInstance = overrider.overrideMetadata(
SomeMetadata, oldInstance, {remove: {plainProp: 'newPlainProp'}});
expect(newInstance)
.toEqual(new SomeMetadata({plainProp: 'somePlainProp', getterProp: 'someGetterProp'}));
});
it('should remove a value from an array', () => {
const oldInstance =
new SomeMetadata({arrayProp: ['a', 'b', 'c'], getterProp: 'someGetterProp'});
const newInstance = overrider.overrideMetadata(
SomeMetadata, oldInstance, {remove: {arrayProp: ['a', 'c']}});
expect(newInstance)
.toEqual(new SomeMetadata({arrayProp: ['b'], getterProp: 'someGetterProp'}));
});
it('should support types as values', () => {
class Class1 {}
class Class2 {}
class Class3 {}
const instance1 = new SomeMetadata({arrayProp: [Class1, Class2, Class3]});
const instance2 =
overrider.overrideMetadata(SomeMetadata, instance1, {remove: {arrayProp: [Class1]}});
expect(instance2).toEqual(new SomeMetadata({arrayProp: [Class2, Class3]}));
const instance3 =
overrider.overrideMetadata(SomeMetadata, instance2, {remove: {arrayProp: [Class3]}});
expect(instance3).toEqual(new SomeMetadata({arrayProp: [Class2]}));
});
});
});
}

View File

@ -9,7 +9,7 @@
import {CompilerConfig} from '@angular/compiler/src/config'; import {CompilerConfig} from '@angular/compiler/src/config';
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, Component, Directive, DoCheck, Injectable, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewEncapsulation} from '@angular/core'; import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, Component, Directive, DoCheck, Injectable, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewEncapsulation} from '@angular/core';
import {LIFECYCLE_HOOKS_VALUES} from '@angular/core/src/metadata/lifecycle_hooks'; import {LIFECYCLE_HOOKS_VALUES} from '@angular/core/src/metadata/lifecycle_hooks';
import {configureCompiler} from '@angular/core/testing'; import {TestBed} from '@angular/core/testing';
import {afterEach, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal'; import {afterEach, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
import {CompileNgModuleMetadata} from '../src/compile_metadata'; import {CompileNgModuleMetadata} from '../src/compile_metadata';
@ -21,7 +21,7 @@ import {TEST_COMPILER_PROVIDERS} from './test_bindings';
export function main() { export function main() {
describe('CompileMetadataResolver', () => { describe('CompileMetadataResolver', () => {
beforeEach(() => { configureCompiler({providers: TEST_COMPILER_PROVIDERS}); }); beforeEach(() => { TestBed.configureCompiler({providers: TEST_COMPILER_PROVIDERS}); });
describe('getDirectiveMetadata', () => { describe('getDirectiveMetadata', () => {
it('should read metadata', it('should read metadata',

View File

@ -10,7 +10,7 @@ import {beforeEach, ddescribe, xdescribe, describe, iit, inject, beforeEachProvi
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
import {Injectable, Component, Input, ViewMetadata, Compiler, ComponentFactory, Injector, NgModule, NgModuleFactory} from '@angular/core'; import {Injectable, Component, Input, ViewMetadata, Compiler, ComponentFactory, Injector, NgModule, NgModuleFactory} from '@angular/core';
import {ConcreteType, stringify} from '../src/facade/lang'; import {ConcreteType, stringify} from '../src/facade/lang';
import {fakeAsync, tick, TestComponentBuilder, ComponentFixture, configureCompiler} from '@angular/core/testing'; import {fakeAsync, tick, TestComponentBuilder, ComponentFixture, TestBed} from '@angular/core/testing';
import {XHR, DirectiveResolver} from '@angular/compiler'; import {XHR, DirectiveResolver} from '@angular/compiler';
import {MockDirectiveResolver} from '@angular/compiler/testing'; import {MockDirectiveResolver} from '@angular/compiler/testing';
@ -36,7 +36,8 @@ export function main() {
let dirResolver: MockDirectiveResolver; let dirResolver: MockDirectiveResolver;
let injector: Injector; let injector: Injector;
beforeEach(() => { configureCompiler({providers: [{provide: XHR, useClass: SpyXHR}]}); }); beforeEach(
() => { TestBed.configureCompiler({providers: [{provide: XHR, useClass: SpyXHR}]}); });
beforeEach(inject( beforeEach(inject(
[Compiler, TestComponentBuilder, XHR, DirectiveResolver, Injector], [Compiler, TestComponentBuilder, XHR, DirectiveResolver, Injector],

View File

@ -14,7 +14,7 @@ import {TEMPLATE_TRANSFORMS, TemplateParser, splitClasses} from '@angular/compil
import {MockSchemaRegistry} from '@angular/compiler/testing'; import {MockSchemaRegistry} from '@angular/compiler/testing';
import {SchemaMetadata, SecurityContext} from '@angular/core'; import {SchemaMetadata, SecurityContext} from '@angular/core';
import {Console} from '@angular/core/src/console'; import {Console} from '@angular/core/src/console';
import {configureCompiler} from '@angular/core/testing'; import {TestBed} from '@angular/core/testing';
import {afterEach, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal'; import {afterEach, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal';
import {Identifiers, identifierToken} from '../src/identifiers'; import {Identifiers, identifierToken} from '../src/identifiers';
@ -40,7 +40,7 @@ export function main() {
function commonBeforeEach() { function commonBeforeEach() {
beforeEach(() => { beforeEach(() => {
console = new ArrayConsole(); console = new ArrayConsole();
configureCompiler({providers: [{provide: Console, useValue: console}]}); TestBed.configureCompiler({providers: [{provide: Console, useValue: console}]});
}); });
beforeEach(inject([TemplateParser], (parser: TemplateParser) => { beforeEach(inject([TemplateParser], (parser: TemplateParser) => {
var component = CompileDirectiveMetadata.create({ var component = CompileDirectiveMetadata.create({
@ -66,10 +66,10 @@ export function main() {
} }
describe('TemplateParser template transform', () => { describe('TemplateParser template transform', () => {
beforeEach(() => { configureCompiler({providers: TEST_COMPILER_PROVIDERS}); }); beforeEach(() => { TestBed.configureCompiler({providers: TEST_COMPILER_PROVIDERS}); });
beforeEach(() => { beforeEach(() => {
configureCompiler({ TestBed.configureCompiler({
providers: providers:
[{provide: TEMPLATE_TRANSFORMS, useValue: new FooAstTransformer(), multi: true}] [{provide: TEMPLATE_TRANSFORMS, useValue: new FooAstTransformer(), multi: true}]
}); });
@ -84,7 +84,7 @@ export function main() {
describe('multiple', () => { describe('multiple', () => {
beforeEach(() => { beforeEach(() => {
configureCompiler({ TestBed.configureCompiler({
providers: providers:
[{provide: TEMPLATE_TRANSFORMS, useValue: new BarAstTransformer(), multi: true}] [{provide: TEMPLATE_TRANSFORMS, useValue: new BarAstTransformer(), multi: true}]
}); });
@ -101,7 +101,7 @@ export function main() {
// Semi-integration test to make sure TemplateParser properly sets the security context. // Semi-integration test to make sure TemplateParser properly sets the security context.
// Uses the actual DomElementSchemaRegistry. // Uses the actual DomElementSchemaRegistry.
beforeEach(() => { beforeEach(() => {
configureCompiler({ TestBed.configureCompiler({
providers: [ providers: [
TEST_COMPILER_PROVIDERS, TEST_COMPILER_PROVIDERS,
{provide: ElementSchemaRegistry, useClass: DomElementSchemaRegistry} {provide: ElementSchemaRegistry, useClass: DomElementSchemaRegistry}
@ -138,7 +138,7 @@ export function main() {
describe('TemplateParser', () => { describe('TemplateParser', () => {
beforeEach(() => { beforeEach(() => {
configureCompiler({providers: [TEST_COMPILER_PROVIDERS, MOCK_SCHEMA_REGISTRY]}); TestBed.configureCompiler({providers: [TEST_COMPILER_PROVIDERS, MOCK_SCHEMA_REGISTRY]});
}); });
commonBeforeEach(); commonBeforeEach();

View File

@ -327,27 +327,6 @@ export function main() {
expect(componentFixture.nativeElement).toHaveText('Mock'); expect(componentFixture.nativeElement).toHaveText('Mock');
})); }));
it('should create components synchronously with a custom module',
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
@Pipe({name: 'somePipe'})
class SomePipe {
transform(value: any) { return `transformed ${value}`; }
}
@NgModule({declarations: [SomePipe]})
class SomeModule {
}
@Component({selector: 'comp', template: `{{'hello' | somePipe}}`})
class SomeComponent {
}
let componentFixture = tcb.createSync(SomeComponent, SomeModule);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('transformed hello');
}));
describe('ComponentFixture', () => { describe('ComponentFixture', () => {
it('should auto detect changes if autoDetectChanges is called', it('should auto detect changes if autoDetectChanges is called',
inject( inject(

View File

@ -10,12 +10,86 @@ export * from './testing/schema_registry_mock';
export * from './testing/test_component_builder'; export * from './testing/test_component_builder';
export * from './testing/directive_resolver_mock'; export * from './testing/directive_resolver_mock';
export * from './testing/ng_module_resolver_mock'; export * from './testing/ng_module_resolver_mock';
export * from './testing/pipe_resolver_mock';
import {createPlatformFactory, CompilerOptions, PlatformRef} from '@angular/core'; import {ConcreteType, Type} from './src/facade/lang';
import {platformCoreDynamic, DirectiveResolver, NgModuleResolver} from './index'; import {createPlatformFactory, ModuleWithComponentFactories, Injectable, CompilerOptions, PlatformRef, CompilerFactory, ComponentFactory, NgModuleFactory, Injector, NgModuleMetadata, NgModuleMetadataType, ComponentMetadata, ComponentMetadataType, DirectiveMetadata, DirectiveMetadataType, PipeMetadata, PipeMetadataType} from '@angular/core';
import {MetadataOverride} from '@angular/core/testing';
import {TestingCompilerFactory, TestingCompiler} from './core_private_testing';
import {platformCoreDynamic, RuntimeCompiler, DirectiveResolver, NgModuleResolver, PipeResolver} from './index';
import {MockDirectiveResolver} from './testing/directive_resolver_mock'; import {MockDirectiveResolver} from './testing/directive_resolver_mock';
import {MockNgModuleResolver} from './testing/ng_module_resolver_mock'; import {MockNgModuleResolver} from './testing/ng_module_resolver_mock';
import {MockPipeResolver} from './testing/pipe_resolver_mock';
import {MetadataOverrider} from './testing/metadata_overrider';
@Injectable()
export class TestingCompilerFactoryImpl implements TestingCompilerFactory {
constructor(private _compilerFactory: CompilerFactory) {}
createTestingCompiler(options: CompilerOptions[]): TestingCompiler {
const compiler = <RuntimeCompiler>this._compilerFactory.createCompiler(options);
return new TestingCompilerImpl(
compiler, compiler.injector.get(MockDirectiveResolver),
compiler.injector.get(MockPipeResolver), compiler.injector.get(MockNgModuleResolver));
}
}
export class TestingCompilerImpl implements TestingCompiler {
private _overrider = new MetadataOverrider();
constructor(
private _compiler: RuntimeCompiler, private _directiveResolver: MockDirectiveResolver,
private _pipeResolver: MockPipeResolver, private _moduleResolver: MockNgModuleResolver) {}
get injector(): Injector { return this._compiler.injector; }
compileComponentAsync<T>(component: ConcreteType<T>, ngModule: Type = null):
Promise<ComponentFactory<T>> {
return this._compiler.compileComponentAsync(component, <any>ngModule);
}
compileComponentSync<T>(component: ConcreteType<T>, ngModule: Type = null): ComponentFactory<T> {
return this._compiler.compileComponentSync(component, <any>ngModule);
}
compileModuleSync<T>(moduleType: ConcreteType<T>): NgModuleFactory<T> {
return this._compiler.compileModuleSync(moduleType);
}
compileModuleAsync<T>(moduleType: ConcreteType<T>): Promise<NgModuleFactory<T>> {
return this._compiler.compileModuleAsync(moduleType);
}
compileModuleAndAllComponentsSync<T>(moduleType: ConcreteType<T>):
ModuleWithComponentFactories<T> {
return this._compiler.compileModuleAndAllComponentsSync(moduleType);
}
compileModuleAndAllComponentsAsync<T>(moduleType: ConcreteType<T>):
Promise<ModuleWithComponentFactories<T>> {
return this._compiler.compileModuleAndAllComponentsAsync(moduleType);
}
overrideModule(ngModule: ConcreteType<any>, override: MetadataOverride<NgModuleMetadataType>):
void {
const oldMetadata = this._moduleResolver.resolve(ngModule, false);
this._moduleResolver.setNgModule(
ngModule, this._overrider.overrideMetadata(NgModuleMetadata, oldMetadata, override));
}
overrideDirective(
directive: ConcreteType<any>, override: MetadataOverride<DirectiveMetadataType>): void {
const oldMetadata = this._directiveResolver.resolve(directive, false);
this._directiveResolver.setDirective(
directive, this._overrider.overrideMetadata(DirectiveMetadata, oldMetadata, override));
}
overrideComponent(
component: ConcreteType<any>, override: MetadataOverride<ComponentMetadataType>): void {
const oldMetadata = this._directiveResolver.resolve(component, false);
this._directiveResolver.setDirective(
component, this._overrider.overrideMetadata(ComponentMetadata, oldMetadata, override));
}
overridePipe(pipe: ConcreteType<any>, override: MetadataOverride<PipeMetadataType>): void {
const oldMetadata = this._pipeResolver.resolve(pipe, false);
this._pipeResolver.setPipe(
pipe, this._overrider.overrideMetadata(PipeMetadata, oldMetadata, override));
}
clearCache(): void { this._compiler.clearCache(); }
clearCacheFor(type: Type) { this._compiler.clearCacheFor(type); }
}
/** /**
* Platform for dynamic tests * Platform for dynamic tests
@ -23,13 +97,17 @@ import {MockNgModuleResolver} from './testing/ng_module_resolver_mock';
* @experimental * @experimental
*/ */
export const platformCoreDynamicTesting = export const platformCoreDynamicTesting =
createPlatformFactory(platformCoreDynamic, 'coreDynamicTesting', [{ createPlatformFactory(platformCoreDynamic, 'coreDynamicTesting', [
provide: CompilerOptions, {
useValue: { provide: CompilerOptions,
providers: [ useValue: {
{provide: DirectiveResolver, useClass: MockDirectiveResolver}, providers: [
{provide: NgModuleResolver, useClass: MockNgModuleResolver} MockPipeResolver, {provide: PipeResolver, useExisting: MockPipeResolver},
] MockDirectiveResolver, {provide: DirectiveResolver, useExisting: MockDirectiveResolver},
}, MockNgModuleResolver, {provide: NgModuleResolver, useExisting: MockNgModuleResolver}
multi: true ]
}]); },
multi: true
},
{provide: TestingCompilerFactory, useClass: TestingCompilerFactoryImpl}
]);

View File

@ -55,7 +55,8 @@ export class MockDirectiveResolver extends DirectiveResolver {
if (metadata instanceof ComponentMetadata) { if (metadata instanceof ComponentMetadata) {
let viewProviders = metadata.viewProviders; let viewProviders = metadata.viewProviders;
if (isPresent(viewProviderOverrides)) { if (isPresent(viewProviderOverrides)) {
const originalViewProviders: any[] = isPresent(metadata.viewProviders) ? metadata.viewProviders : []; const originalViewProviders: any[] =
isPresent(metadata.viewProviders) ? metadata.viewProviders : [];
viewProviders = originalViewProviders.concat(viewProviderOverrides); viewProviders = originalViewProviders.concat(viewProviderOverrides);
} }

View File

@ -0,0 +1,131 @@
/**
* @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 {MetadataOverride} from '@angular/core/testing';
import {BaseException} from '../src/facade/exceptions';
import {ConcreteType, stringify} from '../src/facade/lang';
type StringMap = {
[key: string]: any
};
let _nextReferenceId = 0;
export class MetadataOverrider {
private _references = new Map<any, string>();
/**
* Creates a new instance for the given metadata class
* based on an old instance and overrides.
*/
overrideMetadata<C extends T, T>(
metadataClass: {new (options: T): C;}, oldMetadata: C, override: MetadataOverride<T>): C {
const props: StringMap = {};
if (oldMetadata) {
_valueProps(oldMetadata).forEach((prop) => props[prop] = (<any>oldMetadata)[prop]);
}
if (override.set) {
if (override.remove || override.add) {
throw new BaseException(
`Cannot set and add/remove ${stringify(metadataClass)} at the same time!`);
}
setMetadata(props, override.set);
}
if (override.remove) {
removeMetadata(props, override.remove, this._references);
}
if (override.add) {
addMetadata(props, override.add);
}
return new metadataClass(<any>props);
}
}
function removeMetadata(metadata: StringMap, remove: any, references: Map<any, string>) {
const removeObjects = new Set<string>();
for (let prop in remove) {
const removeValue = remove[prop];
if (removeValue instanceof Array) {
removeValue.forEach(
(value: any) => { removeObjects.add(_propHashKey(prop, value, references)); });
} else {
removeObjects.add(_propHashKey(prop, removeValue, references));
}
}
for (let prop in metadata) {
const propValue = metadata[prop];
if (propValue instanceof Array) {
metadata[prop] = propValue.filter(
(value: any) => { return !removeObjects.has(_propHashKey(prop, value, references)); });
} else {
if (removeObjects.has(_propHashKey(prop, propValue, references))) {
metadata[prop] = undefined;
}
}
}
}
function addMetadata(metadata: StringMap, add: any) {
for (let prop in add) {
const addValue = add[prop];
const propValue = metadata[prop];
if (propValue != null && propValue instanceof Array) {
metadata[prop] = propValue.concat(addValue);
} else {
metadata[prop] = addValue;
}
}
}
function setMetadata(metadata: StringMap, set: any) {
for (let prop in set) {
metadata[prop] = set[prop];
}
}
function _propHashKey(propName: any, propValue: any, references: Map<any, string>): string {
const replacer = (key: any, value: any) => {
if (typeof value === 'function') {
value = _serializeReference(value, references);
}
return value;
};
return `${propName}:${JSON.stringify(propValue, replacer)}`;
}
function _serializeReference(ref: any, references: Map<any, string>): string {
let id = references.get(ref);
if (!id) {
id = `${stringify(ref)}${_nextReferenceId++}`;
references.set(ref, id);
}
return id;
}
function _valueProps(obj: any): string[] {
const props: string[] = [];
// regular public props
Object.getOwnPropertyNames(obj).forEach((prop) => {
if (!prop.startsWith('_')) {
props.push(prop);
}
});
// getters
const proto = Object.getPrototypeOf(obj);
Object.getOwnPropertyNames(proto).forEach((protoProp) => {
var desc = Object.getOwnPropertyDescriptor(proto, protoProp);
if (!protoProp.startsWith('_') && desc && 'get' in desc) {
props.push(protoProp);
}
});
return props;
}

View File

@ -19,7 +19,7 @@ export class MockPipeResolver extends PipeResolver {
private get _compiler(): Compiler { return this._injector.get(Compiler); } private get _compiler(): Compiler { return this._injector.get(Compiler); }
private _clearCacheFor(component: Type) { this._compiler.clearCacheFor(component); } private _clearCacheFor(pipe: Type) { this._compiler.clearCacheFor(pipe); }
/** /**
* Overrides the {@link PipeMetadata} for a pipe. * Overrides the {@link PipeMetadata} for a pipe.

View File

@ -16,7 +16,10 @@ import {ConcreteType, IS_DART, Type, isPresent} from '../src/facade/lang';
/** /**
* A TestComponentBuilder that allows overriding based on the compiler. * A TestComponentBuilder that allows overriding based on the compiler.
*/ *
* @deprecated Use `TestBed.configureTestModule` / `TestBed.override...` / `TestBed.createComponent`
* instead.
*/
@Injectable() @Injectable()
export class OverridingTestComponentBuilder extends TestComponentBuilder { export class OverridingTestComponentBuilder extends TestComponentBuilder {
/** @internal */ /** @internal */
@ -87,16 +90,14 @@ export class OverridingTestComponentBuilder extends TestComponentBuilder {
return clone; return clone;
} }
createAsync<T>(rootComponentType: ConcreteType<T>, ngModule: ConcreteType<any> = null): createAsync<T>(rootComponentType: ConcreteType<T>): Promise<ComponentFixture<T>> {
Promise<ComponentFixture<T>> {
this._applyMetadataOverrides(); this._applyMetadataOverrides();
return super.createAsync(rootComponentType, ngModule); return super.createAsync(rootComponentType);
} }
createSync<T>(rootComponentType: ConcreteType<T>, ngModule: ConcreteType<any> = null): createSync<T>(rootComponentType: ConcreteType<T>): ComponentFixture<T> {
ComponentFixture<T> {
this._applyMetadataOverrides(); this._applyMetadataOverrides();
return super.createSync(rootComponentType, ngModule); return super.createSync(rootComponentType);
} }
private _applyMetadataOverrides() { private _applyMetadataOverrides() {

View File

@ -0,0 +1,21 @@
/**
* @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 * as test_compiler from './testing/test_compiler';
export declare namespace __core_private_testing_types__ {
export type TestingCompiler = test_compiler.TestingCompiler;
export var TestingCompiler: typeof test_compiler.TestingCompiler;
export type TestingCompilerFactory = test_compiler.TestingCompilerFactory;
export var TestingCompilerFactory: typeof test_compiler.TestingCompilerFactory;
}
export var __core_private_testing__ = {
TestingCompiler: test_compiler.TestingCompiler,
TestingCompilerFactory: test_compiler.TestingCompilerFactory
};

View File

@ -22,10 +22,6 @@ import {NgZone} from './zone/ng_zone';
let __unused: Type; // avoid unused import when Type union types are erased let __unused: Type; // avoid unused import when Type union types are erased
export function _componentFactoryResolverFactory() {
return ComponentFactoryResolver.NULL;
}
export function _iterableDiffersFactory() { export function _iterableDiffersFactory() {
return defaultIterableDiffers; return defaultIterableDiffers;
} }
@ -72,7 +68,6 @@ export const APPLICATION_COMMON_PROVIDERS: Array<Type|{[k: string]: any}|any[]>
{provide: ApplicationRef, useExisting: ApplicationRef_}, {provide: ApplicationRef, useExisting: ApplicationRef_},
Compiler, Compiler,
{provide: ComponentResolver, useExisting: Compiler}, {provide: ComponentResolver, useExisting: Compiler},
{provide: ComponentFactoryResolver, useFactory: _componentFactoryResolverFactory},
APP_ID_RANDOM_PROVIDER, APP_ID_RANDOM_PROVIDER,
ViewUtils, ViewUtils,
{provide: IterableDiffers, useFactory: _iterableDiffersFactory}, {provide: IterableDiffers, useFactory: _iterableDiffersFactory},

View File

@ -7,7 +7,7 @@
*/ */
// Public API for compiler // Public API for compiler
export {Compiler, CompilerFactory, CompilerOptions, ComponentStillLoadingError} from './linker/compiler'; export {Compiler, CompilerFactory, CompilerOptions, ComponentStillLoadingError, ModuleWithComponentFactories} from './linker/compiler';
export {ComponentFactory, ComponentRef} from './linker/component_factory'; export {ComponentFactory, ComponentRef} from './linker/component_factory';
export {ComponentFactoryResolver, NoComponentFactoryError} from './linker/component_factory_resolver'; export {ComponentFactoryResolver, NoComponentFactoryError} from './linker/component_factory_resolver';
export {ComponentResolver} from './linker/component_resolver'; export {ComponentResolver} from './linker/component_resolver';

View File

@ -7,10 +7,9 @@
*/ */
import {Injector, OpaqueToken} from '../di'; import {Injector, OpaqueToken} from '../di';
import {BaseException} from '../facade/exceptions'; import {BaseException, unimplemented} from '../facade/exceptions';
import {ConcreteType, Type, stringify} from '../facade/lang'; import {ConcreteType, Type, stringify} from '../facade/lang';
import {ViewEncapsulation} from '../metadata'; import {NgModuleMetadata, ViewEncapsulation} from '../metadata';
import {NgModuleMetadata} from '../metadata/ng_module';
import {ComponentFactory} from './component_factory'; import {ComponentFactory} from './component_factory';
import {ComponentResolver} from './component_resolver'; import {ComponentResolver} from './component_resolver';
@ -28,6 +27,22 @@ export class ComponentStillLoadingError extends BaseException {
} }
} }
/**
* Combination of NgModuleFactory and ComponentFactorys.
*
* @experimental
*/
export class ModuleWithComponentFactories<T> {
constructor(
public ngModuleFactory: NgModuleFactory<T>,
public componentFactories: ComponentFactory<any>[]) {}
}
function _throwError() {
throw new BaseException(`Runtime compiler is not loaded`);
}
/** /**
* Low-level service for running the angular compiler duirng runtime * Low-level service for running the angular compiler duirng runtime
* to create {@link ComponentFactory}s, which * to create {@link ComponentFactory}s, which
@ -39,42 +54,48 @@ export class ComponentStillLoadingError extends BaseException {
* @stable * @stable
*/ */
export class Compiler { export class Compiler {
/**
* Returns the injector with which the compiler has been created.
*/
get _injector(): Injector {
throw new BaseException(`Runtime compiler is not loaded. Tried to read the injector.`);
}
/** /**
* Loads the template and styles of a component and returns the associated `ComponentFactory`. * Loads the template and styles of a component and returns the associated `ComponentFactory`.
*/ */
compileComponentAsync<T>(component: ConcreteType<T>, ngModule: Type = null): compileComponentAsync<T>(component: ConcreteType<T>, ngModule: Type = null):
Promise<ComponentFactory<T>> { Promise<ComponentFactory<T>> {
throw new BaseException( throw _throwError();
`Runtime compiler is not loaded. Tried to compile ${stringify(component)}`);
} }
/** /**
* Compiles the given component. All templates have to be either inline or compiled via * Compiles the given component. All templates have to be either inline or compiled via
* `compileComponentAsync` before. Otherwise throws a {@link ComponentStillLoadingError}. * `compileComponentAsync` before. Otherwise throws a {@link ComponentStillLoadingError}.
*/ */
compileComponentSync<T>(component: ConcreteType<T>, ngModule: Type = null): ComponentFactory<T> { compileComponentSync<T>(component: ConcreteType<T>, ngModule: Type = null): ComponentFactory<T> {
throw new BaseException( throw _throwError();
`Runtime compiler is not loaded. Tried to compile ${stringify(component)}`);
} }
/** /**
* Compiles the given NgModule. All templates of the components listed in `entryComponents` * Compiles the given NgModule and all of its components. All templates of the components listed
* have to be either inline or compiled before via `compileComponentAsync` / * in `entryComponents`
* `compileModuleAsync`. Otherwise throws a {@link ComponentStillLoadingError}. * have to be inlined. Otherwise throws a {@link ComponentStillLoadingError}.
*/ */
compileModuleSync<T>(moduleType: ConcreteType<T>): NgModuleFactory<T> { compileModuleSync<T>(moduleType: ConcreteType<T>): NgModuleFactory<T> { throw _throwError(); }
throw new BaseException(
`Runtime compiler is not loaded. Tried to compile ${stringify(moduleType)}`); /**
* Compiles the given NgModule and all of its components
*/
compileModuleAsync<T>(moduleType: ConcreteType<T>): Promise<NgModuleFactory<T>> {
throw _throwError();
} }
compileModuleAsync<T>(moduleType: ConcreteType<T>): Promise<NgModuleFactory<T>> { /**
throw new BaseException( * Same as {@link compileModuleSync} put also creates ComponentFactories for all components.
`Runtime compiler is not loaded. Tried to compile ${stringify(moduleType)}`); */
compileModuleAndAllComponentsSync<T>(moduleType: ConcreteType<T>):
ModuleWithComponentFactories<T> {
throw _throwError();
}
/**
* Same as {@link compileModuleAsync} put also creates ComponentFactories for all components.
*/
compileModuleAndAllComponentsAsync<T>(moduleType: ConcreteType<T>):
Promise<ModuleWithComponentFactories<T>> {
throw _throwError();
} }
/** /**

View File

@ -20,7 +20,7 @@ import {AnimationPlayer} from '../../src/animation/animation_player';
import {AnimationStyles} from '../../src/animation/animation_styles'; import {AnimationStyles} from '../../src/animation/animation_styles';
import {AUTO_STYLE, AnimationEntryMetadata, animate, group, keyframes, sequence, state, style, transition, trigger} from '../../src/animation/metadata'; import {AUTO_STYLE, AnimationEntryMetadata, animate, group, keyframes, sequence, state, style, transition, trigger} from '../../src/animation/metadata';
import {isArray, isPresent} from '../../src/facade/lang'; import {isArray, isPresent} from '../../src/facade/lang';
import {configureCompiler, configureModule, fakeAsync, flushMicrotasks, tick} from '../../testing'; import {TestBed, fakeAsync, flushMicrotasks, tick} from '../../testing';
import {MockAnimationPlayer} from '../../testing/mock_animation_player'; import {MockAnimationPlayer} from '../../testing/mock_animation_player';
import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '../../testing/testing_internal'; import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '../../testing/testing_internal';
@ -32,8 +32,9 @@ export function main() {
function declareTests({useJit}: {useJit: boolean}) { function declareTests({useJit}: {useJit: boolean}) {
describe('animation tests', function() { describe('animation tests', function() {
beforeEachProviders(() => { beforeEachProviders(() => {
configureCompiler({useJit: useJit}); TestBed.configureCompiler({useJit: useJit});
configureModule({providers: [{provide: AnimationDriver, useClass: MockAnimationDriver}]}); TestBed.configureTestingModule(
{providers: [{provide: AnimationDriver, useClass: MockAnimationDriver}]});
}); });
var makeAnimationCmp = var makeAnimationCmp =

View File

@ -12,7 +12,7 @@ import {TEST_COMPILER_PROVIDERS} from '@angular/compiler/test/test_bindings';
import {MockSchemaRegistry} from '@angular/compiler/testing'; import {MockSchemaRegistry} from '@angular/compiler/testing';
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, DebugElement, Directive, DoCheck, Injectable, Input, OnChanges, OnDestroy, OnInit, Output, Pipe, PipeTransform, RenderComponentType, Renderer, RootRenderer, SimpleChange, SimpleChanges, TemplateRef, ViewContainerRef, ViewMetadata, WrappedValue, forwardRef} from '@angular/core'; import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, DebugElement, Directive, DoCheck, Injectable, Input, OnChanges, OnDestroy, OnInit, Output, Pipe, PipeTransform, RenderComponentType, Renderer, RootRenderer, SimpleChange, SimpleChanges, TemplateRef, ViewContainerRef, ViewMetadata, WrappedValue, forwardRef} from '@angular/core';
import {DebugDomRenderer} from '@angular/core/src/debug/debug_renderer'; import {DebugDomRenderer} from '@angular/core/src/debug/debug_renderer';
import {ComponentFixture, TestComponentBuilder, configureCompiler, configureModule, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing'; import {ComponentFixture, TestBed, TestComponentBuilder, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing';
import {afterEach, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal'; import {afterEach, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xit} from '@angular/core/testing/testing_internal';
import {By} from '@angular/platform-browser/src/dom/debug/by'; import {By} from '@angular/platform-browser/src/dom/debug/by';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
@ -78,8 +78,8 @@ export function main() {
if (!getDOM().supportsDOMEvents()) return; if (!getDOM().supportsDOMEvents()) return;
beforeEach(() => { beforeEach(() => {
configureCompiler({providers: TEST_COMPILER_PROVIDERS}); TestBed.configureCompiler({providers: TEST_COMPILER_PROVIDERS});
configureModule({ TestBed.configureTestingModule({
providers: providers:
[RenderLog, DirectiveLog, {provide: RootRenderer, useClass: LoggingRootRenderer}] [RenderLog, DirectiveLog, {provide: RootRenderer, useClass: LoggingRootRenderer}]
}); });

View File

@ -7,7 +7,7 @@
*/ */
import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, expect, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal'; import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, expect, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal';
import {TestComponentBuilder, configureModule, configureCompiler} from '@angular/core/testing'; import {TestComponentBuilder, TestBed} from '@angular/core/testing';
import {Component, ComponentFactoryResolver, NoComponentFactoryError, forwardRef, ANALYZE_FOR_ENTRY_COMPONENTS, ViewMetadata} from '@angular/core'; import {Component, ComponentFactoryResolver, NoComponentFactoryError, forwardRef, ANALYZE_FOR_ENTRY_COMPONENTS, ViewMetadata} from '@angular/core';
import {stringify} from '../../src/facade/lang'; import {stringify} from '../../src/facade/lang';
import {Console} from '../../src/console'; import {Console} from '../../src/console';
@ -29,8 +29,9 @@ function declareTests({useJit}: {useJit: boolean}) {
var console: DummyConsole; var console: DummyConsole;
beforeEach(() => { beforeEach(() => {
console = new DummyConsole(); console = new DummyConsole();
configureCompiler({useJit: useJit, providers: [{provide: Console, useValue: console}]}); TestBed.configureCompiler(
configureModule({declarations: [MainComp, ChildComp, NestedChildComp]}); {useJit: useJit, providers: [{provide: Console, useValue: console}]});
TestBed.configureTestingModule({declarations: [MainComp, ChildComp, NestedChildComp]});
}); });
it('should warn and auto declare if the component was not declared nor imported by the module', it('should warn and auto declare if the component was not declared nor imported by the module',

View File

@ -8,7 +8,7 @@
import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal'; import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
import {fakeAsync, tick, ComponentFixture, configureCompiler, configureModule, TestComponentBuilder} from '@angular/core/testing'; import {fakeAsync, tick, ComponentFixture, TestBed, TestComponentBuilder} from '@angular/core/testing';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {isPresent, stringify, isBlank,} from '../../src/facade/lang'; import {isPresent, stringify, isBlank,} from '../../src/facade/lang';
import {BaseException} from '../../src/facade/exceptions'; import {BaseException} from '../../src/facade/exceptions';
@ -48,8 +48,9 @@ function declareTests({useJit}: {useJit: boolean}) {
describe('integration tests', function() { describe('integration tests', function() {
beforeEach(() => { beforeEach(() => {
configureCompiler({useJit: useJit}); TestBed.configureCompiler({useJit: useJit});
configureModule({providers: [{provide: ANCHOR_ELEMENT, useValue: el('<div></div>')}]}); TestBed.configureTestingModule(
{providers: [{provide: ANCHOR_ELEMENT, useValue: el('<div></div>')}]});
}); });
describe('react to record changes', function() { describe('react to record changes', function() {

View File

@ -8,7 +8,7 @@
import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal'; import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
import {configureCompiler, TestComponentBuilder} from '@angular/core/testing'; import {TestBed, TestComponentBuilder} from '@angular/core/testing';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {Component, Directive, AfterContentInit, AfterViewInit, QueryList, ContentChildren, ViewChildren, Input} from '@angular/core'; import {Component, Directive, AfterContentInit, AfterViewInit, QueryList, ContentChildren, ViewChildren, Input} from '@angular/core';
import {NgIf} from '@angular/common'; import {NgIf} from '@angular/common';
@ -21,7 +21,7 @@ export function main() {
function declareTests({useJit}: {useJit: boolean}) { function declareTests({useJit}: {useJit: boolean}) {
describe('<ng-container>', function() { describe('<ng-container>', function() {
beforeEach(() => { configureCompiler({useJit: useJit}); }); beforeEach(() => { TestBed.configureCompiler({useJit: useJit}); });
it('should be rendered as comment with children as siblings', it('should be rendered as comment with children as siblings',
inject( inject(

View File

@ -11,7 +11,7 @@ import {CompilerConfig, NgModuleResolver} from '@angular/compiler';
import {MockNgModuleResolver} from '@angular/compiler/testing'; import {MockNgModuleResolver} from '@angular/compiler/testing';
import {ANALYZE_FOR_ENTRY_COMPONENTS, CUSTOM_ELEMENTS_SCHEMA, Compiler, Component, ComponentFactoryResolver, ComponentRef, ComponentResolver, DebugElement, Directive, Host, HostBinding, Inject, Injectable, Injector, Input, ModuleWithProviders, NgModule, NgModuleMetadata, NgModuleRef, OpaqueToken, Optional, Pipe, Provider, ReflectiveInjector, SelfMetadata, SkipSelf, SkipSelfMetadata, ViewMetadata, forwardRef, getDebugNode, provide} from '@angular/core'; import {ANALYZE_FOR_ENTRY_COMPONENTS, CUSTOM_ELEMENTS_SCHEMA, Compiler, Component, ComponentFactoryResolver, ComponentRef, ComponentResolver, DebugElement, Directive, Host, HostBinding, Inject, Injectable, Injector, Input, ModuleWithProviders, NgModule, NgModuleMetadata, NgModuleRef, OpaqueToken, Optional, Pipe, Provider, ReflectiveInjector, SelfMetadata, SkipSelf, SkipSelfMetadata, ViewMetadata, forwardRef, getDebugNode, provide} from '@angular/core';
import {Console} from '@angular/core/src/console'; import {Console} from '@angular/core/src/console';
import {ComponentFixture, configureCompiler} from '@angular/core/testing'; import {ComponentFixture, TestBed} from '@angular/core/testing';
import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal'; import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
@ -122,7 +122,8 @@ function declareTests({useJit}: {useJit: boolean}) {
beforeEach(() => { beforeEach(() => {
console = new DummyConsole(); console = new DummyConsole();
configureCompiler({useJit: useJit, providers: [{provide: Console, useValue: console}]}); TestBed.configureCompiler(
{useJit: useJit, providers: [{provide: Console, useValue: console}]});
}); });
beforeEach(inject([Compiler, Injector], (_compiler: Compiler, _injector: Injector) => { beforeEach(inject([Compiler, Injector], (_compiler: Compiler, _injector: Injector) => {

View File

@ -8,7 +8,7 @@
import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal'; import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
import {configureCompiler, configureModule, TestComponentBuilder} from '@angular/core/testing'; import {TestBed, TestComponentBuilder} from '@angular/core/testing';
import {Component, Pipe, PipeTransform, ViewMetadata, OpaqueToken, Injector, forwardRef} from '@angular/core'; import {Component, Pipe, PipeTransform, ViewMetadata, OpaqueToken, Injector, forwardRef} from '@angular/core';
import {NgIf, NgClass} from '@angular/common'; import {NgIf, NgClass} from '@angular/common';
@ -25,8 +25,8 @@ function declareTests({useJit}: {useJit: boolean}) {
describe('platform pipes', () => { describe('platform pipes', () => {
beforeEach(() => { beforeEach(() => {
configureCompiler({useJit: useJit}); TestBed.configureCompiler({useJit: useJit});
configureModule({declarations: [PlatformPipe]}); TestBed.configureTestingModule({declarations: [PlatformPipe]});
}); });
it('should overwrite them by custom pipes', it('should overwrite them by custom pipes',

View File

@ -7,7 +7,7 @@
*/ */
import {AsyncTestCompleter, ddescribe, describe, expect, inject, beforeEachProviders, beforeEach, afterEach, it,} from '@angular/core/testing/testing_internal'; import {AsyncTestCompleter, ddescribe, describe, expect, inject, beforeEachProviders, beforeEach, afterEach, it,} from '@angular/core/testing/testing_internal';
import {configureCompiler, TestComponentBuilder} from '@angular/core/testing'; import {TestBed, TestComponentBuilder} from '@angular/core/testing';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {Component} from '@angular/core/src/metadata'; import {Component} from '@angular/core/src/metadata';
import {DomSanitizationService} from '@angular/platform-browser/src/security/dom_sanitization_service'; import {DomSanitizationService} from '@angular/platform-browser/src/security/dom_sanitization_service';
@ -42,7 +42,7 @@ function itAsync(
function declareTests({useJit}: {useJit: boolean}) { function declareTests({useJit}: {useJit: boolean}) {
describe('security integration tests', function() { describe('security integration tests', function() {
beforeEach(() => { configureCompiler({useJit: useJit}); }); beforeEach(() => { TestBed.configureCompiler({useJit: useJit}); });
let originalLog: (msg: any) => any; let originalLog: (msg: any) => any;
beforeEach(() => { beforeEach(() => {

View File

@ -12,3 +12,6 @@ export * from './testing/fake_async';
export * from './testing/test_component_builder'; export * from './testing/test_component_builder';
export * from './testing/test_bed'; export * from './testing/test_bed';
export * from './testing/testing'; export * from './testing/testing';
export * from './testing/metadata_override';
export * from './private_export_testing';

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 * 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 {ListWrapper} from '../src/facade/collection';
import {BaseException} from '../src/facade/exceptions'; import {BaseException} from '../src/facade/exceptions';
import {ConcreteType, FunctionWrapper, isPresent, stringify} from '../src/facade/lang'; import {ConcreteType, FunctionWrapper, isPresent, stringify} from '../src/facade/lang';
import {AsyncTestCompleter} from './async_test_completer'; 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(); 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 * @experimental
*/ */
export class TestBed implements Injector { 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 _instantiated: boolean = false;
private _compiler: Compiler = null; private _compiler: TestingCompiler = null;
private _moduleRef: NgModuleRef<any> = null; private _moduleRef: NgModuleRef<any> = null;
private _ngModuleFactory: NgModuleFactory<any> = null; private _moduleWithComponentFactories: ModuleWithComponentFactories<any> = null;
private _compilerOptions: CompilerOptions[] = []; 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 _providers: Array<Type|Provider|any[]|any> = [];
private _declarations: Array<Type|any[]|any> = []; private _declarations: Array<Type|any[]|any> = [];
private _imports: Array<Type|any[]|any> = []; private _imports: Array<Type|any[]|any> = [];
private _entryComponents: Array<Type|any[]|any> = [];
private _schemas: Array<SchemaMetadata|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._compiler = null;
this._moduleOverrides = [];
this._componentOverrides = [];
this._directiveOverrides = [];
this._pipeOverrides = [];
this._moduleRef = null; this._moduleRef = null;
this._ngModuleFactory = null; this._moduleWithComponentFactories = null;
this._compilerOptions = []; this._compilerOptions = [];
this._providers = []; this._providers = [];
this._declarations = []; this._declarations = [];
this._imports = []; this._imports = [];
this._entryComponents = [];
this._schemas = []; this._schemas = [];
this._instantiated = false; this._instantiated = false;
} }
@ -51,22 +214,12 @@ export class TestBed implements Injector {
ngModule: Type = null; ngModule: Type = null;
configureCompiler(config: {providers?: any[], useJit?: boolean}) { configureCompiler(config: {providers?: any[], useJit?: boolean}) {
if (this._instantiated) { this._assertNotInstantiated('TestBed.configureCompiler', 'configure the compiler');
throw new BaseException('Cannot add configuration after test injector is instantiated');
}
this._compilerOptions.push(config); this._compilerOptions.push(config);
} }
configureModule(moduleDef: { configureTestingModule(moduleDef: TestModuleMetadata) {
providers?: any[], this._assertNotInstantiated('TestBed.configureTestingModule', 'configure the test module');
declarations?: any[],
imports?: any[],
entryComponents?: any[],
schemas?: Array<SchemaMetadata|any>
}) {
if (this._instantiated) {
throw new BaseException('Cannot add configuration after test injector is instantiated');
}
if (moduleDef.providers) { if (moduleDef.providers) {
this._providers = ListWrapper.concat(this._providers, moduleDef.providers); this._providers = ListWrapper.concat(this._providers, moduleDef.providers);
} }
@ -76,109 +229,141 @@ export class TestBed implements Injector {
if (moduleDef.imports) { if (moduleDef.imports) {
this._imports = ListWrapper.concat(this._imports, moduleDef.imports); this._imports = ListWrapper.concat(this._imports, moduleDef.imports);
} }
if (moduleDef.entryComponents) {
this._entryComponents = ListWrapper.concat(this._entryComponents, moduleDef.entryComponents);
}
if (moduleDef.schemas) { if (moduleDef.schemas) {
this._schemas = ListWrapper.concat(this._schemas, moduleDef.schemas); this._schemas = ListWrapper.concat(this._schemas, moduleDef.schemas);
} }
} }
createModuleFactory(): Promise<NgModuleFactory<any>> { compileComponents(): Promise<any> {
if (this._instantiated) { if (this._moduleWithComponentFactories || this._instantiated) {
throw new BaseException( return Promise.resolve(null);
'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);
} }
const moduleType = this._createCompilerAndModule(); const moduleType = this._createCompilerAndModule();
return this._compiler.compileModuleAndAllComponentsAsync(moduleType)
return this._compiler.compileModuleAsync(moduleType).then((ngModuleFactory) => { .then((moduleAndComponentFactories) => {
this._ngModuleFactory = ngModuleFactory; this._moduleWithComponentFactories = moduleAndComponentFactories;
return ngModuleFactory; });
});
} }
initTestModule() { private _initIfNeeded() {
if (this._instantiated) { if (this._instantiated) {
return; return;
} }
if (!this._moduleWithComponentFactories) {
if (this._ngModuleFactory) { try {
this._createFromModuleFactory(this._ngModuleFactory); let moduleType = this._createCompilerAndModule();
} else { this._moduleWithComponentFactories =
let moduleType = this._createCompilerAndModule(); this._compiler.compileModuleAndAllComponentsSync(moduleType);
this._createFromModuleFactory(this._compiler.compileModuleSync(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;
}
}
} }
} this._moduleRef =
this._moduleWithComponentFactories.ngModuleFactory.create(this.platform.injector);
/** this._instantiated = true;
* @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));
} }
private _createCompilerAndModule(): ConcreteType<any> { private _createCompilerAndModule(): ConcreteType<any> {
const providers = this._providers.concat([{provide: TestBed, useValue: this}]); const providers = this._providers.concat([{provide: TestBed, useValue: this}]);
const declarations = this._declarations; const declarations = this._declarations;
const imports = [this.ngModule, this._imports]; const imports = [this.ngModule, this._imports];
const entryComponents = this._entryComponents;
const schemas = this._schemas; const schemas = this._schemas;
@NgModule({ @NgModule(
providers: providers, {providers: providers, declarations: declarations, imports: imports, schemas: schemas})
declarations: declarations,
imports: imports,
entryComponents: entryComponents,
schemas: schemas
})
class DynamicTestModule { class DynamicTestModule {
} }
const compilerFactory: CompilerFactory = this.platform.injector.get(CompilerFactory); const compilerFactory: TestingCompilerFactory =
this.platform.injector.get(TestingCompilerFactory);
this._compiler = 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; return DynamicTestModule;
} }
private _createFromModuleFactory(ngModuleFactory: NgModuleFactory<any>): Injector { private _assertNotInstantiated(methodName: string, methodDescription: string) {
this._moduleRef = ngModuleFactory.create(this.platform.injector); if (this._instantiated) {
this._instantiated = true; throw new BaseException(
return this; `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) { get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND) {
if (!this._instantiated) { this._initIfNeeded();
throw new BaseException(
'Illegal state: The test bed\'s injector has not yet been created. Call initTestModule first!');
}
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.
let result = this._moduleRef.injector.get(token, UNDEFINED); 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 { execute(tokens: any[], fn: Function): any {
if (!this._instantiated) { this._initIfNeeded();
throw new BaseException(
'Illegal state: The test bed\'s injector has not yet been created. Call initTestModule first!');
}
var params = tokens.map(t => this.get(t)); var params = tokens.map(t => this.get(t));
return FunctionWrapper.apply(fn, params); 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; var _testBed: TestBed = null;
@ -211,7 +396,7 @@ export function getTestInjector() {
* Test modules and platforms for individual platforms are available from * Test modules and platforms for individual platforms are available from
* 'angular2/platform/testing/<platform_name>'. * 'angular2/platform/testing/<platform_name>'.
* *
* @deprecated Use initTestEnvironment instead * @deprecated Use TestBed.initTestEnvironment instead
*/ */
export function setBaseTestProviders( export function setBaseTestProviders(
platformProviders: Array<Type|Provider|any[]>, platformProviders: Array<Type|Provider|any[]>,
@ -220,65 +405,17 @@ export function setBaseTestProviders(
(<any>platformProviders[0])(applicationProviders); (<any>platformProviders[0])(applicationProviders);
} else { } else {
throw new Error( 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. * Reset the providers for the test injector.
* *
* @deprecated Use resetTestEnvironment instead. * @deprecated Use TestBed.resetTestEnvironment instead.
*/ */
export function resetBaseTestProviders() { export function resetBaseTestProviders() {
resetTestEnvironment(); TestBed.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();
} }
/** /**
@ -308,30 +445,17 @@ export function doAsyncEntryPointCompilation(): Promise<any> {
export function inject(tokens: any[], fn: Function): () => any { export function inject(tokens: any[], fn: Function): () => any {
let testBed = getTestBed(); let testBed = getTestBed();
if (tokens.indexOf(AsyncTestCompleter) >= 0) { if (tokens.indexOf(AsyncTestCompleter) >= 0) {
return () => { return () =>
// Return an async test method that returns a Promise if AsyncTestCompleter is one of the // Return an async test method that returns a Promise if AsyncTestCompleter is one of
// injected tokens. // the
return testBed._createInjectorAsync().then(() => { // injected tokens.
let completer: AsyncTestCompleter = testBed.get(AsyncTestCompleter); testBed.compileComponents().then(() => {
testBed.execute(tokens, fn); let completer: AsyncTestCompleter = testBed.get(AsyncTestCompleter);
return completer.promise; testBed.execute(tokens, fn);
}); return completer.promise;
}; });
} else { } else {
return () => { return () => testBed.execute(tokens, fn);
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);
};
} }
} }
@ -339,17 +463,12 @@ export function inject(tokens: any[], fn: Function): () => any {
* @experimental * @experimental
*/ */
export class InjectSetupWrapper { export class InjectSetupWrapper {
constructor(private _moduleDef: () => { constructor(private _moduleDef: () => TestModuleMetadata) {}
providers?: any[],
declarations?: any[],
imports?: any[],
entryComponents?: any[]
}) {}
private _addModule() { private _addModule() {
var moduleDef = this._moduleDef(); const moduleDef = this._moduleDef();
if (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) { export function withProviders(providers: () => any) {
return new InjectSetupWrapper(() => {{return {providers: providers()};}}); return new InjectSetupWrapper(() => { return {providers: providers()}; });
} }
/** /**
* @experimental * @experimental
*/ */
export function withModule(moduleDef: () => { export function withModule(moduleDef: TestModuleMetadata): InjectSetupWrapper;
providers?: any[], export function withModule(moduleDef: TestModuleMetadata, fn: Function): () => any;
declarations?: any[], export function withModule(moduleDef: TestModuleMetadata, fn: Function = null): (() => any)|
imports?: any[], InjectSetupWrapper {
entryComponents?: any[], if (fn) {
schemas?: Array<SchemaMetadata|any[]> return () => {
}) { const testBed = getTestBed();
return new InjectSetupWrapper(moduleDef); 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 {ComponentFixture} from './component_fixture';
import {tick} from './fake_async'; import {tick} from './fake_async';
import {ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, TestComponentRenderer} from './test_bed';
/**
* 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');
var _nextRootElementId = 0; var _nextRootElementId = 0;
/** /**
* Builds a ComponentFixture for use in component level tests. * Builds a ComponentFixture for use in component level tests.
* @stable *
* @deprecated Use `TestBed.configureTestModule` / `TestBed.override...` / `TestBed.createComponent`
* instead.
*/ */
@Injectable() @Injectable()
export class TestComponentBuilder { export class TestComponentBuilder {
@ -119,27 +102,25 @@ export class TestComponentBuilder {
/** /**
* Builds and returns a ComponentFixture. * Builds and returns a ComponentFixture.
*/ */
createAsync<T>(rootComponentType: ConcreteType<T>, ngModule: ConcreteType<any> = null): createAsync<T>(rootComponentType: ConcreteType<T>): Promise<ComponentFixture<T>> {
Promise<ComponentFixture<T>> {
let noNgZone = IS_DART || this._injector.get(ComponentFixtureNoNgZone, false); let noNgZone = IS_DART || this._injector.get(ComponentFixtureNoNgZone, false);
let ngZone: NgZone = noNgZone ? null : this._injector.get(NgZone, null); let ngZone: NgZone = noNgZone ? null : this._injector.get(NgZone, null);
let compiler: Compiler = this._injector.get(Compiler); let compiler: Compiler = this._injector.get(Compiler);
let initComponent = () => { let initComponent = () => {
let promise: Promise<ComponentFactory<any>> = let promise: Promise<ComponentFactory<any>> =
compiler.compileComponentAsync(rootComponentType, ngModule); compiler.compileComponentAsync(rootComponentType);
return promise.then(componentFactory => this.createFromFactory(ngZone, componentFactory)); return promise.then(componentFactory => this.createFromFactory(ngZone, componentFactory));
}; };
return ngZone == null ? initComponent() : ngZone.run(initComponent); return ngZone == null ? initComponent() : ngZone.run(initComponent);
} }
createFakeAsync<T>(rootComponentType: ConcreteType<T>, ngModule: ConcreteType<any> = null): createFakeAsync<T>(rootComponentType: ConcreteType<T>): ComponentFixture<T> {
ComponentFixture<T> {
let result: any /** TODO #9100 */; let result: any /** TODO #9100 */;
let error: any /** TODO #9100 */; let error: any /** TODO #9100 */;
PromiseWrapper.then( PromiseWrapper.then(
this.createAsync(rootComponentType, ngModule), (_result) => { result = _result; }, this.createAsync(rootComponentType), (_result) => { result = _result; },
(_error) => { error = _error; }); (_error) => { error = _error; });
tick(); tick();
if (isPresent(error)) { if (isPresent(error)) {
@ -148,15 +129,13 @@ export class TestComponentBuilder {
return result; return result;
} }
createSync<T>(rootComponentType: ConcreteType<T>, ngModule: ConcreteType<any> = null): createSync<T>(rootComponentType: ConcreteType<T>): ComponentFixture<T> {
ComponentFixture<T> {
let noNgZone = IS_DART || this._injector.get(ComponentFixtureNoNgZone, false); let noNgZone = IS_DART || this._injector.get(ComponentFixtureNoNgZone, false);
let ngZone: NgZone = noNgZone ? null : this._injector.get(NgZone, null); let ngZone: NgZone = noNgZone ? null : this._injector.get(NgZone, null);
let compiler: Compiler = this._injector.get(Compiler); let compiler: Compiler = this._injector.get(Compiler);
let initComponent = () => { let initComponent = () => {
return this.createFromFactory( return this.createFromFactory(ngZone, compiler.compileComponentSync(rootComponentType));
ngZone, compiler.compileComponentSync(rootComponentType, ngModule));
}; };
return ngZone == null ? initComponent() : ngZone.run(initComponent); return ngZone == null ? initComponent() : ngZone.run(initComponent);

View File

@ -13,75 +13,25 @@
*/ */
import {SchemaMetadata} from '../index'; import {SchemaMetadata} from '../index';
import {TestBed, getTestBed} from './test_bed';
import {TestBed, TestModuleMetadata, getTestBed} from './test_bed';
declare var global: any; declare var global: any;
var _global = <any>(typeof window === 'undefined' ? global : window); var _global = <any>(typeof window === 'undefined' ? global : window);
var testBed: TestBed = getTestBed();
// Reset the test providers before each test. // Reset the test providers before each test.
if (_global.beforeEach) { if (_global.beforeEach) {
_global.beforeEach(() => { testBed.reset(); }); _global.beforeEach(() => { TestBed.resetTestingModule(); });
} }
/** /**
* Allows overriding default providers of the test injector, * Allows overriding default providers of the test injector,
* which are defined in test_injector.js * which are defined in test_injector.js
* *
* @stable * @deprecated Use `TestBed.configureTestingModule instead.
*/ */
export function addProviders(providers: Array<any>): void { export function addProviders(providers: Array<any>): void {
if (!providers) return; if (!providers) return;
try { TestBed.configureTestingModule({providers: providers});
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.');
}
} }

View File

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

View File

@ -8,7 +8,7 @@
import {NgFor, NgIf} from '@angular/common'; import {NgFor, NgIf} from '@angular/common';
import {Component, Directive, EventEmitter, Input, Output, forwardRef} from '@angular/core'; import {Component, Directive, EventEmitter, Input, Output, forwardRef} from '@angular/core';
import {ComponentFixture, TestComponentBuilder, configureModule, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing'; import {ComponentFixture, TestBed, TestComponentBuilder, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing';
import {AsyncTestCompleter, afterEach, beforeEach, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal'; import {AsyncTestCompleter, afterEach, beforeEach, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
import {ControlValueAccessor, FormArray, FormControl, FormGroup, FormsModule, NG_ASYNC_VALIDATORS, NG_VALIDATORS, NgControl, ReactiveFormsModule, Validator, Validators} from '@angular/forms'; import {ControlValueAccessor, FormArray, FormControl, FormGroup, FormsModule, NG_ASYNC_VALIDATORS, NG_VALIDATORS, NgControl, ReactiveFormsModule, Validator, Validators} from '@angular/forms';
import {By} from '@angular/platform-browser/src/dom/debug/by'; import {By} from '@angular/platform-browser/src/dom/debug/by';
@ -22,7 +22,9 @@ import {PromiseWrapper} from '../src/facade/promise';
export function main() { export function main() {
describe('reactive forms integration tests', () => { describe('reactive forms integration tests', () => {
beforeEach(() => { configureModule({imports: [FormsModule, ReactiveFormsModule]}); }); beforeEach(() => {
TestBed.configureTestingModule({imports: [FormsModule, ReactiveFormsModule]});
});
it('should initialize DOM elements with the given form object', it('should initialize DOM elements with the given form object',
inject( inject(

View File

@ -8,19 +8,20 @@
import {NgFor, NgIf} from '@angular/common'; import {NgFor, NgIf} from '@angular/common';
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {ComponentFixture, TestComponentBuilder, configureModule, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing'; import {ComponentFixture, TestBed, TestComponentBuilder, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing';
import {AsyncTestCompleter, afterEach, beforeEach, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal'; import {AsyncTestCompleter, afterEach, beforeEach, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
import {FormsModule, NgForm} from '@angular/forms'; import {FormsModule, NgForm} from '@angular/forms';
import {By} from '@angular/platform-browser/src/dom/debug/by'; import {By} from '@angular/platform-browser/src/dom/debug/by';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {dispatchEvent} from '@angular/platform-browser/testing/browser_util'; import {dispatchEvent} from '@angular/platform-browser/testing/browser_util';
import {ObservableWrapper} from '../src/facade/async'; import {ObservableWrapper} from '../src/facade/async';
import {ListWrapper} from '../src/facade/collection'; import {ListWrapper} from '../src/facade/collection';
export function main() { export function main() {
describe('template-driven forms integration tests', () => { describe('template-driven forms integration tests', () => {
beforeEach(() => { configureModule({imports: [FormsModule]}); }); beforeEach(() => { TestBed.configureTestingModule({imports: [FormsModule]}); });
it('should support ngModel for single fields', it('should support ngModel for single fields',
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {

View File

@ -8,7 +8,7 @@
import {UrlResolver, XHR} from '@angular/compiler'; import {UrlResolver, XHR} from '@angular/compiler';
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {TestComponentBuilder, configureCompiler, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing'; import {TestBed, TestComponentBuilder, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing';
import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it, xit} from '@angular/core/testing/testing_internal'; import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it, xit} from '@angular/core/testing/testing_internal';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
@ -26,7 +26,7 @@ export function main() {
return new CachedXHR(); return new CachedXHR();
} }
beforeEach(() => { beforeEach(() => {
configureCompiler({ TestBed.configureCompiler({
providers: [ providers: [
{provide: UrlResolver, useClass: TestUrlResolver}, {provide: UrlResolver, useClass: TestUrlResolver},
{provide: XHR, useFactory: createCachedXHR} {provide: XHR, useFactory: createCachedXHR}

View File

@ -9,7 +9,7 @@
import {CompilerConfig, DirectiveResolver, NgModuleResolver, analyzeAppProvidersForDeprecatedConfiguration} from '@angular/compiler'; import {CompilerConfig, DirectiveResolver, NgModuleResolver, analyzeAppProvidersForDeprecatedConfiguration} from '@angular/compiler';
import {OverridingTestComponentBuilder, platformCoreDynamicTesting} from '@angular/compiler/testing'; import {OverridingTestComponentBuilder, platformCoreDynamicTesting} from '@angular/compiler/testing';
import {Compiler, CompilerFactory, CompilerOptions, NgModule, PlatformRef, Provider, ReflectiveInjector, Type, createPlatform, createPlatformFactory} from '@angular/core'; import {Compiler, CompilerFactory, CompilerOptions, NgModule, PlatformRef, Provider, ReflectiveInjector, Type, createPlatform, createPlatformFactory} from '@angular/core';
import {TestComponentBuilder, TestComponentRenderer, initTestEnvironment} from '@angular/core/testing'; import {TestBed, TestComponentBuilder, TestComponentRenderer} from '@angular/core/testing';
import {BrowserTestingModule, platformBrowserTesting} from '@angular/platform-browser/testing'; import {BrowserTestingModule, platformBrowserTesting} from '@angular/platform-browser/testing';
import {Console} from './core_private'; import {Console} from './core_private';
@ -62,7 +62,7 @@ export const TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS: Array<any /*Type | Provide
class DynamicTestModule { class DynamicTestModule {
} }
const testInjector = initTestEnvironment(DynamicTestModule, platformRef); const testInjector = TestBed.initTestEnvironment(DynamicTestModule, platformRef);
const console: Console = testInjector.get(Console); const console: Console = testInjector.get(Console);
deprecatedConfiguration.deprecationMessages.forEach((msg) => console.warn(msg)); deprecatedConfiguration.deprecationMessages.forEach((msg) => console.warn(msg));
}]; }];

View File

@ -8,8 +8,8 @@
import {NgIf} from '@angular/common'; import {NgIf} from '@angular/common';
import {CompilerConfig, XHR} from '@angular/compiler'; import {CompilerConfig, XHR} from '@angular/compiler';
import {CUSTOM_ELEMENTS_SCHEMA, Component, ComponentFactoryResolver, Directive, Injectable, Input, NgModule, Pipe, ViewMetadata, provide} from '@angular/core'; import {CUSTOM_ELEMENTS_SCHEMA, Component, ComponentFactoryResolver, ComponentMetadata, Directive, DirectiveMetadata, HostBinding, Injectable, Input, NgModule, NgModuleMetadata, Pipe, PipeMetadata, ViewMetadata, provide} from '@angular/core';
import {TestComponentBuilder, addProviders, async, configureCompiler, configureModule, doAsyncEntryPointCompilation, fakeAsync, inject, tick, withModule, withProviders} from '@angular/core/testing'; import {TestBed, TestComponentBuilder, addProviders, async, fakeAsync, inject, tick, withModule, withProviders} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
import {stringify} from '../../http/src/facade/lang'; import {stringify} from '../../http/src/facade/lang';
@ -229,26 +229,63 @@ export function main() {
}); });
describe('using the test injector with modules', () => { describe('using the test injector with modules', () => {
let moduleConfig: any; let moduleConfig = {
beforeEach(() => { providers: [FancyService],
moduleConfig = { imports: [SomeLibModule],
providers: [FancyService], declarations: [SomeDirective, SomePipe, CompUsingModuleDirectiveAndPipe],
imports: [SomeLibModule], };
declarations: [SomeDirective, SomePipe, CompUsingModuleDirectiveAndPipe],
entryComponents: [CompUsingModuleDirectiveAndPipe]
};
});
describe('setting up a module', () => { describe('setting up a module', () => {
beforeEach(() => configureModule(moduleConfig)); beforeEach(() => TestBed.configureTestingModule(moduleConfig));
it('should use set up providers', inject([FancyService], (service: FancyService) => { it('should use set up providers', inject([FancyService], (service: FancyService) => {
expect(service.value).toEqual('real value'); expect(service.value).toEqual('real value');
})); }));
it('should use set up directives and pipes', it('should be able to create any declared components', () => {
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { const compFixture = TestBed.createComponent(CompUsingModuleDirectiveAndPipe);
let compFixture = tcb.createSync(CompUsingModuleDirectiveAndPipe); expect(compFixture.componentInstance).toBeAnInstanceOf(CompUsingModuleDirectiveAndPipe);
});
it('should use set up directives and pipes', () => {
const compFixture = TestBed.createComponent(CompUsingModuleDirectiveAndPipe);
let el = compFixture.debugElement;
compFixture.detectChanges();
expect(el.children[0].properties['title']).toBe('transformed someValue');
});
it('should use set up imported modules',
inject([SomeLibModule], (libModule: SomeLibModule) => {
expect(libModule).toBeAnInstanceOf(SomeLibModule);
}));
describe('provided schemas', () => {
@Component({template: '<some-element [someUnknownProp]="true"></some-element>'})
class ComponentUsingInvalidProperty {
}
beforeEach(() => {
TestBed.configureTestingModule(
{schemas: [CUSTOM_ELEMENTS_SCHEMA], declarations: [ComponentUsingInvalidProperty]});
});
it('should not error on unknown bound properties on custom elements when using the CUSTOM_ELEMENTS_SCHEMA',
() => {
expect(TestBed.createComponent(ComponentUsingInvalidProperty).componentInstance)
.toBeAnInstanceOf(ComponentUsingInvalidProperty);
});
});
});
describe('per test modules', () => {
it('should use set up providers',
withModule(moduleConfig).inject([FancyService], (service: FancyService) => {
expect(service.value).toEqual('real value');
}));
it('should use set up directives and pipes', withModule(moduleConfig, () => {
let compFixture = TestBed.createComponent(CompUsingModuleDirectiveAndPipe);
let el = compFixture.debugElement; let el = compFixture.debugElement;
compFixture.detectChanges(); compFixture.detectChanges();
@ -256,83 +293,96 @@ export function main() {
})); }));
it('should use set up library modules', it('should use set up library modules',
inject([SomeLibModule], (libModule: SomeLibModule) => { withModule(moduleConfig).inject([SomeLibModule], (libModule: SomeLibModule) => {
expect(libModule).toBeAnInstanceOf(SomeLibModule); expect(libModule).toBeAnInstanceOf(SomeLibModule);
})); }));
it('should use set up entryComponents components',
inject([ComponentFactoryResolver], (resolver: ComponentFactoryResolver) => {
expect(resolver.resolveComponentFactory(CompUsingModuleDirectiveAndPipe).componentType)
.toBe(CompUsingModuleDirectiveAndPipe);
}));
it('should error on unknown bound properties on custom elements by default',
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
@Component({template: '<some-element [someUnknownProp]="true"></some-element>'})
class ComponentUsingInvalidProperty {
}
expect(() => tcb.createSync(ComponentUsingInvalidProperty))
.toThrowError(/Can't bind to 'someUnknownProp'/);
}));
describe('provided schemas', () => {
beforeEach(() => { configureModule({schemas: [CUSTOM_ELEMENTS_SCHEMA]}); });
it('should not error on unknown bound properties on custom elements when using the CUSTOM_ELEMENTS_SCHEMA',
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
@Component({template: '<some-element [someUnknownProp]="true"></some-element>'})
class ComponentUsingInvalidProperty {
}
tcb.createSync(ComponentUsingInvalidProperty);
expect(() => tcb.createSync(ComponentUsingInvalidProperty)).not.toThrow();
}));
});
}); });
describe('per test modules', () => { describe('components with template url', () => {
it('should use set up providers',
withModule(() => moduleConfig).inject([FancyService], (service: FancyService) => {
expect(service.value).toEqual('real value');
}));
it('should use set up directives and pipes',
withModule(() => moduleConfig)
.inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
let compFixture = tcb.createSync(CompUsingModuleDirectiveAndPipe);
let el = compFixture.debugElement;
compFixture.detectChanges();
expect(el.children[0].properties['title']).toBe('transformed someValue');
}));
it('should use set up library modules',
withModule(() => moduleConfig).inject([SomeLibModule], (libModule: SomeLibModule) => {
expect(libModule).toBeAnInstanceOf(SomeLibModule);
}));
it('should use set up entryComponents components',
withModule(() => moduleConfig)
.inject([ComponentFactoryResolver], (resolver: ComponentFactoryResolver) => {
expect(
resolver.resolveComponentFactory(CompUsingModuleDirectiveAndPipe).componentType)
.toBe(CompUsingModuleDirectiveAndPipe);
}));
});
describe('entryComponents components with template url', () => {
beforeEach(async(() => { beforeEach(async(() => {
configureModule( TestBed.configureTestingModule({declarations: [CompWithUrlTemplate]});
{declarations: [CompWithUrlTemplate], entryComponents: [CompWithUrlTemplate]}); TestBed.compileComponents();
doAsyncEntryPointCompilation();
})); }));
it('should allow to createSync components with templateUrl after explicit async compilation', it('should allow to createSync components with templateUrl after explicit async compilation',
inject([TestComponentBuilder], (builder: TestComponentBuilder) => { () => {
let fixture = builder.createSync(CompWithUrlTemplate); let fixture = TestBed.createComponent(CompWithUrlTemplate);
expect(fixture.nativeElement).toHaveText('from external template\n'); expect(fixture.nativeElement).toHaveText('from external template\n');
})); });
});
describe('overwrite metadata', () => {
@Pipe({name: 'undefined'})
class SomePipe {
transform(value: string): string { return `transformed ${value}`; }
}
@Directive({selector: '[undefined]'})
class SomeDirective {
someProp = 'hello';
}
@Component({selector: 'comp', template: 'someText'})
class SomeComponent {
}
@Component({selector: 'othercomp', template: 'someOtherText'})
class SomeOtherComponent {
}
@NgModule({declarations: [SomeComponent, SomeDirective, SomePipe]})
class SomeModule {
}
beforeEach(() => { TestBed.configureTestingModule({imports: [SomeModule]}); });
describe('module', () => {
beforeEach(() => {
TestBed.overrideModule(SomeModule, {set: {declarations: [SomeOtherComponent]}});
});
it('should work', () => {
expect(TestBed.createComponent(SomeOtherComponent).componentInstance)
.toBeAnInstanceOf(SomeOtherComponent);
});
});
describe('component', () => {
beforeEach(() => {
TestBed.overrideComponent(SomeComponent, {set: {selector: 'comp', template: 'newText'}});
});
it('should work', () => {
expect(TestBed.createComponent(SomeComponent).nativeElement).toHaveText('newText');
});
});
describe('directive', () => {
beforeEach(() => {
TestBed
.overrideComponent(
SomeComponent, {set: {selector: 'comp', template: `<div someDir></div>`}})
.overrideDirective(
SomeDirective, {set: {selector: '[someDir]', host: {'[title]': 'someProp'}}});
});
it('should work', () => {
const compFixture = TestBed.createComponent(SomeComponent);
compFixture.detectChanges();
expect(compFixture.debugElement.children[0].properties['title']).toEqual('hello');
});
});
describe('pipe', () => {
beforeEach(() => {
TestBed
.overrideComponent(
SomeComponent, {set: {selector: 'comp', template: `{{'hello' | somePipe}}`}})
.overridePipe(SomePipe, {set: {name: 'somePipe'}});
});
it('should work', () => {
const compFixture = TestBed.createComponent(SomeComponent);
compFixture.detectChanges();
expect(compFixture.nativeElement).toHaveText('transformed hello');
});
});
}); });
describe('setting up the compiler', () => { describe('setting up the compiler', () => {
@ -340,7 +390,7 @@ export function main() {
describe('providers', () => { describe('providers', () => {
beforeEach(() => { beforeEach(() => {
let xhrGet = jasmine.createSpy('xhrGet').and.returnValue(Promise.resolve('Hello world!')); let xhrGet = jasmine.createSpy('xhrGet').and.returnValue(Promise.resolve('Hello world!'));
configureCompiler({providers: [{provide: XHR, useValue: {get: xhrGet}}]}); TestBed.configureCompiler({providers: [{provide: XHR, useValue: {get: xhrGet}}]});
}); });
it('should use set up providers', it('should use set up providers',
@ -351,14 +401,14 @@ export function main() {
}); });
describe('useJit true', () => { describe('useJit true', () => {
beforeEach(() => { configureCompiler({useJit: true}); }); beforeEach(() => { TestBed.configureCompiler({useJit: true}); });
it('should set the value into CompilerConfig', it('should set the value into CompilerConfig',
inject([CompilerConfig], (config: CompilerConfig) => { inject([CompilerConfig], (config: CompilerConfig) => {
expect(config.useJit).toBe(true); expect(config.useJit).toBe(true);
})); }));
}); });
describe('useJit false', () => { describe('useJit false', () => {
beforeEach(() => { configureCompiler({useJit: false}); }); beforeEach(() => { TestBed.configureCompiler({useJit: false}); });
it('should set the value into CompilerConfig', it('should set the value into CompilerConfig',
inject([CompilerConfig], (config: CompilerConfig) => { inject([CompilerConfig], (config: CompilerConfig) => {
expect(config.useJit).toBe(false); expect(config.useJit).toBe(false);
@ -451,49 +501,55 @@ export function main() {
beforeEach(() => addProviders([{provide: FancyService, useValue: new FancyService()}])); beforeEach(() => addProviders([{provide: FancyService, useValue: new FancyService()}]));
}) })
.toThrowError( .toThrowError(
'addProviders can\'t be called after the injector has been already created for this test. ' + `Cannot configure the test module when the test module has already been instantiated. ` +
'This is most likely because you\'ve already used the injector to inject a beforeEach or the ' + `Make sure you are not using \`inject\` before \`TestBed.configureTestingModule\`.`);
'current `it` function.');
restoreJasmineBeforeEach(); restoreJasmineBeforeEach();
}); });
}); });
}); });
describe('entryComponents', () => { describe('components', () => {
let xhrGet: jasmine.Spy; let xhrGet: jasmine.Spy;
beforeEach(() => { beforeEach(() => {
xhrGet = jasmine.createSpy('xhrGet').and.returnValue(Promise.resolve('Hello world!')); xhrGet = jasmine.createSpy('xhrGet').and.returnValue(Promise.resolve('Hello world!'));
configureCompiler({providers: [{provide: XHR, useValue: {get: xhrGet}}]}); TestBed.configureCompiler({providers: [{provide: XHR, useValue: {get: xhrGet}}]});
}); });
it('should report an error for entryComponents components with templateUrl which never call doAsyncEntryComponents', it('should report an error for declared components with templateUrl which never call TestBed.compileComponents',
() => { () => {
var itPromise = patchJasmineIt(); var itPromise = patchJasmineIt();
expect( expect(
() => () =>
it('should fail', it('should fail', withModule(
withModule(() => { {declarations: [CompWithUrlTemplate]},
return { () => { TestBed.createComponent(CompWithUrlTemplate); })))
declarations: [CompWithUrlTemplate],
entryComponents: [CompWithUrlTemplate]
};
})
.inject(
[ComponentFactoryResolver],
(resolver: ComponentFactoryResolver) => {
expect(resolver.resolveComponentFactory(CompWithUrlTemplate)
.componentType)
.toBe(CompWithUrlTemplate);
})))
.toThrowError( .toThrowError(
`This test module uses the entryComponents ${stringify(CompWithUrlTemplate)} which is using a "templateUrl", but they were never compiled. ` + `This test module uses the component ${stringify(CompWithUrlTemplate)} which is using a "templateUrl", but they were never compiled. ` +
`Please call "doAsyncEntryPointCompilation" before "inject".`); `Please call "TestBed.compileComponents" before your test.`);
restoreJasmineIt(); restoreJasmineIt();
}); });
}); });
it('should error on unknown bound properties on custom elements by default', () => {
@Component({template: '<some-element [someUnknownProp]="true"></some-element>'})
class ComponentUsingInvalidProperty {
}
var itPromise = patchJasmineIt();
expect(
() =>
it('should fail',
withModule(
{declarations: [ComponentUsingInvalidProperty]},
() => { TestBed.createComponent(ComponentUsingInvalidProperty); })))
.toThrowError(/Can't bind to 'someUnknownProp'/);
restoreJasmineIt();
});
}); });
describe('test component builder', function() { describe('test component builder', function() {

View File

@ -8,7 +8,7 @@
import {AsyncTestCompleter, inject, ddescribe, describe, it, iit, beforeEach, beforeEachProviders,} from '@angular/core/testing/testing_internal'; import {AsyncTestCompleter, inject, ddescribe, describe, it, iit, beforeEach, beforeEachProviders,} from '@angular/core/testing/testing_internal';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
import {TestBed, TestComponentBuilder, configureModule} from '@angular/core/testing'; import {TestBed, TestComponentBuilder} from '@angular/core/testing';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {Injector, ViewMetadata, Component, Injectable, ComponentRef, ReflectiveInjector, getPlatform} from '@angular/core'; import {Injector, ViewMetadata, Component, Injectable, ComponentRef, ReflectiveInjector, getPlatform} from '@angular/core';
import {NgIf} from '@angular/common'; import {NgIf} from '@angular/common';
@ -67,19 +67,18 @@ export function main() {
var testUiInjector = new TestBed(); var testUiInjector = new TestBed();
testUiInjector.platform = platformBrowserDynamicTesting(); testUiInjector.platform = platformBrowserDynamicTesting();
testUiInjector.ngModule = BrowserTestingModule; testUiInjector.ngModule = BrowserTestingModule;
testUiInjector.configureModule({ testUiInjector.configureTestingModule({
providers: [ providers: [
Serializer, {provide: RenderStore, useValue: uiRenderStore}, Serializer, {provide: RenderStore, useValue: uiRenderStore},
{provide: DomRootRenderer, useClass: DomRootRenderer_}, {provide: DomRootRenderer, useClass: DomRootRenderer_},
{provide: RootRenderer, useExisting: DomRootRenderer} {provide: RootRenderer, useExisting: DomRootRenderer}
] ]
}); });
testUiInjector.initTestModule();
var uiSerializer = testUiInjector.get(Serializer); var uiSerializer = testUiInjector.get(Serializer);
var domRootRenderer = testUiInjector.get(DomRootRenderer); var domRootRenderer = testUiInjector.get(DomRootRenderer);
workerRenderStore = new RenderStore(); workerRenderStore = new RenderStore();
configureModule({ TestBed.configureTestingModule({
providers: [ providers: [
Serializer, {provide: RenderStore, useValue: workerRenderStore}, { Serializer, {provide: RenderStore, useValue: workerRenderStore}, {
provide: RootRenderer, provide: RootRenderer,

View File

@ -9,7 +9,7 @@
import {analyzeAppProvidersForDeprecatedConfiguration} from '@angular/compiler'; import {analyzeAppProvidersForDeprecatedConfiguration} from '@angular/compiler';
import {platformCoreDynamicTesting} from '@angular/compiler/testing'; import {platformCoreDynamicTesting} from '@angular/compiler/testing';
import {CompilerFactory, CompilerOptions, NgModule, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, assertPlatform, createPlatform, createPlatformFactory, getPlatform} from '@angular/core'; import {CompilerFactory, CompilerOptions, NgModule, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, assertPlatform, createPlatform, createPlatformFactory, getPlatform} from '@angular/core';
import {initTestEnvironment} from '@angular/core/testing'; import {TestBed} from '@angular/core/testing';
import {BrowserDynamicTestingModule, TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing'; import {BrowserDynamicTestingModule, TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing';
import {Console} from '../core_private'; import {Console} from '../core_private';
@ -63,7 +63,7 @@ export const TEST_SERVER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]
class DynamicTestModule { class DynamicTestModule {
} }
const testInjector = initTestEnvironment(DynamicTestModule, platformRef); const testInjector = TestBed.initTestEnvironment(DynamicTestModule, platformRef);
const console: Console = testInjector.get(Console); const console: Console = testInjector.get(Console);
deprecatedConfiguration.deprecationMessages.forEach((msg) => console.warn(msg)); deprecatedConfiguration.deprecationMessages.forEach((msg) => console.warn(msg));
}]; }];

View File

@ -72,7 +72,7 @@ Promise.all([
var testing = providers[0]; var testing = providers[0];
var testingBrowser = providers[1]; var testingBrowser = providers[1];
testing.initTestEnvironment( testing.TestBed.initTestEnvironment(
testingBrowser.BrowserDynamicTestingModule, testingBrowser.BrowserDynamicTestingModule,
testingBrowser.platformBrowserDynamicTesting()); testingBrowser.platformBrowserDynamicTesting());

View File

@ -10,7 +10,7 @@ import 'rxjs/add/operator/map';
import {Location} from '@angular/common'; import {Location} from '@angular/common';
import {Component, NgModule, NgModuleFactoryLoader} from '@angular/core'; import {Component, NgModule, NgModuleFactoryLoader} from '@angular/core';
import {ComponentFixture, TestComponentBuilder, addProviders, configureModule, fakeAsync, inject, tick} from '@angular/core/testing'; import {ComponentFixture, TestBed, TestComponentBuilder, addProviders, fakeAsync, inject, tick} from '@angular/core/testing';
import {expect} from '@angular/platform-browser/testing/matchers'; import {expect} from '@angular/platform-browser/testing/matchers';
import {Observable} from 'rxjs/Observable'; import {Observable} from 'rxjs/Observable';
import {of } from 'rxjs/observable/of'; import {of } from 'rxjs/observable/of';
@ -20,7 +20,7 @@ import {RouterTestingModule, SpyNgModuleFactoryLoader} from '../testing';
describe('Integration', () => { describe('Integration', () => {
beforeEach(() => { beforeEach(() => {
configureModule({ TestBed.configureTestingModule({
imports: [RouterTestingModule], imports: [RouterTestingModule],
providers: [provideRoutes( providers: [provideRoutes(
[{path: '', component: BlankCmp}, {path: 'simple', component: SimpleCmp}])], [{path: '', component: BlankCmp}, {path: 'simple', component: SimpleCmp}])],

View File

@ -75,7 +75,7 @@ System.import('@angular/core/testing')
.then(function(coreTesting){ .then(function(coreTesting){
return System.import('@angular/platform-browser-dynamic/testing') return System.import('@angular/platform-browser-dynamic/testing')
.then(function(browserTesting) { .then(function(browserTesting) {
coreTesting.initTestEnvironment( coreTesting.TestBed.initTestEnvironment(
browserTesting.BrowserDynamicTestingModule, browserTesting.BrowserDynamicTestingModule,
browserTesting.platformBrowserDynamicTesting()); browserTesting.platformBrowserDynamicTesting());
}); });

View File

@ -1,5 +1,5 @@
var testingPlatformServer = require('../../all/@angular/platform-server/testing/server.js'); var testingPlatformServer = require('../../all/@angular/platform-server/testing/server.js');
var testing = require('../../all/@angular/core/testing'); var testing = require('../../all/@angular/core/testing');
testing.initTestEnvironment( testing.TestBed.initTestEnvironment(
testingPlatformServer.ServerTestingModule, testingPlatformServer.serverTestingPlatform()); testingPlatformServer.ServerTestingModule, testingPlatformServer.serverTestingPlatform());