fix(testing): add an explicit doAsyncPrecompilation step (#10015)
This removes the magic from the `inject` test helper that would inspect the current zone and would only work with our `async` test helper. Now, `inject` is always synchronous, and if you are using a module that requires async precompilation, you're required to call `doAsyncPrecompilation` in your tests. This is part of the breaking changes introduced with the swap to each test having an AppModule. Closes #9975 Closes #9593 BREAKING CHANGE: `TestInjector` is now renamed to `TestBed` Before: ```js import {TestInjector, getTestInjector} from '@angular/core/testing'; ``` After: ```js import {TestBed, getTestBed} from '@angular/core/testing'; ```
This commit is contained in:
		
							parent
							
								
									450f61d384
								
							
						
					
					
						commit
						b43f95435b
					
				| @ -7,7 +7,7 @@ | |||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| import {beforeEach, ddescribe, xdescribe, describe, expect, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal'; | import {beforeEach, ddescribe, xdescribe, describe, expect, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal'; | ||||||
| import {TestComponentBuilder, ComponentFixtureAutoDetect, ComponentFixtureNoNgZone} from '@angular/core/testing'; | import {TestComponentBuilder, ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, withProviders} from '@angular/core/testing'; | ||||||
| import {AsyncTestCompleter} from '@angular/core/testing/testing_internal'; | import {AsyncTestCompleter} from '@angular/core/testing/testing_internal'; | ||||||
| import {Injectable, Component, Input, ViewMetadata} from '@angular/core'; | import {Injectable, Component, Input, ViewMetadata} from '@angular/core'; | ||||||
| import {NgIf} from '@angular/common'; | import {NgIf} from '@angular/common'; | ||||||
| @ -15,7 +15,6 @@ import {TimerWrapper} from '../src/facade/async'; | |||||||
| import {IS_DART} from '../src/facade/lang'; | import {IS_DART} from '../src/facade/lang'; | ||||||
| import {PromiseWrapper} from '../src/facade/promise'; | import {PromiseWrapper} from '../src/facade/promise'; | ||||||
| import {dispatchEvent} from '@angular/platform-browser/testing/browser_util'; | import {dispatchEvent} from '@angular/platform-browser/testing/browser_util'; | ||||||
| import {withProviders} from '@angular/core/testing/test_injector'; |  | ||||||
| 
 | 
 | ||||||
| @Component( | @Component( | ||||||
|     {selector: 'child-comp', template: `<span>Original {{childBinding}}</span>`, directives: []}) |     {selector: 'child-comp', template: `<span>Original {{childBinding}}</span>`, directives: []}) | ||||||
|  | |||||||
| @ -7,12 +7,13 @@ | |||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| import {AnimationEntryMetadata, Compiler, ComponentFactory, Inject, Injectable, Injector, NgZone, ViewMetadata} from '@angular/core'; | import {AnimationEntryMetadata, Compiler, ComponentFactory, Inject, Injectable, Injector, NgZone, ViewMetadata} from '@angular/core'; | ||||||
| import {ComponentFixture, ComponentFixtureNoNgZone, TestComponentBuilder, TestInjector} from '@angular/core/testing'; | import {ComponentFixture, ComponentFixtureNoNgZone, TestBed, TestComponentBuilder} from '@angular/core/testing'; | ||||||
| 
 | 
 | ||||||
| import {DirectiveResolver, ViewResolver} from '../index'; | import {DirectiveResolver, ViewResolver} from '../index'; | ||||||
| import {MapWrapper} from '../src/facade/collection'; | import {MapWrapper} from '../src/facade/collection'; | ||||||
| import {ConcreteType, IS_DART, Type, isPresent} from '../src/facade/lang'; | 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. | ||||||
|  */ |  */ | ||||||
| @ -31,7 +32,7 @@ export class OverridingTestComponentBuilder extends TestComponentBuilder { | |||||||
|   /** @internal */ |   /** @internal */ | ||||||
|   _viewOverrides = new Map<Type, ViewMetadata>(); |   _viewOverrides = new Map<Type, ViewMetadata>(); | ||||||
| 
 | 
 | ||||||
|   constructor(@Inject(TestInjector) injector: Injector) { super(injector); } |   constructor(@Inject(TestBed) injector: Injector) { super(injector); } | ||||||
| 
 | 
 | ||||||
|   /** @internal */ |   /** @internal */ | ||||||
|   _clone(): OverridingTestComponentBuilder { |   _clone(): OverridingTestComponentBuilder { | ||||||
|  | |||||||
| @ -10,5 +10,5 @@ export * from './testing/async'; | |||||||
| export * from './testing/component_fixture'; | export * from './testing/component_fixture'; | ||||||
| export * from './testing/fake_async'; | export * from './testing/fake_async'; | ||||||
| export * from './testing/test_component_builder'; | export * from './testing/test_component_builder'; | ||||||
| export * from './testing/test_injector'; | export * from './testing/test_bed'; | ||||||
| export * from './testing/testing'; | export * from './testing/testing'; | ||||||
|  | |||||||
| @ -18,11 +18,12 @@ const UNDEFINED = new Object(); | |||||||
| /** | /** | ||||||
|  * @experimental |  * @experimental | ||||||
|  */ |  */ | ||||||
| export class TestInjector implements Injector { | export class TestBed implements Injector { | ||||||
|   private _instantiated: boolean = false; |   private _instantiated: boolean = false; | ||||||
| 
 | 
 | ||||||
|   private _compiler: Compiler = null; |   private _compiler: Compiler = null; | ||||||
|   private _moduleRef: AppModuleRef<any> = null; |   private _moduleRef: AppModuleRef<any> = null; | ||||||
|  |   private _appModuleFactory: AppModuleFactory<any> = null; | ||||||
| 
 | 
 | ||||||
|   private _compilerProviders: Array<Type|Provider|any[]|any> = []; |   private _compilerProviders: Array<Type|Provider|any[]|any> = []; | ||||||
|   private _compilerUseJit: boolean = true; |   private _compilerUseJit: boolean = true; | ||||||
| @ -36,6 +37,7 @@ export class TestInjector implements Injector { | |||||||
|   reset() { |   reset() { | ||||||
|     this._compiler = null; |     this._compiler = null; | ||||||
|     this._moduleRef = null; |     this._moduleRef = null; | ||||||
|  |     this._appModuleFactory = null; | ||||||
|     this._compilerProviders = []; |     this._compilerProviders = []; | ||||||
|     this._compilerUseJit = true; |     this._compilerUseJit = true; | ||||||
|     this._providers = []; |     this._providers = []; | ||||||
| @ -89,16 +91,43 @@ export class TestInjector implements Injector { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   createInjectorSync(): Injector { |   createAppModuleFactory(): Promise<AppModuleFactory<any>> { | ||||||
|     if (this._instantiated) { |     if (this._instantiated) { | ||||||
|       return this; |       throw new BaseException( | ||||||
|  |           'Cannot run precompilation when the test AppModule has already been instantiated. ' + | ||||||
|  |           'Make sure you are not using `inject` before `doAsyncPrecompilation`.'); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     if (this._appModuleFactory) { | ||||||
|  |       return Promise.resolve(this._appModuleFactory); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     let moduleMeta = this._createCompilerAndModuleMeta(); |     let moduleMeta = this._createCompilerAndModuleMeta(); | ||||||
|     return this._createFromModuleFactory( | 
 | ||||||
|         this._compiler.compileAppModuleSync(_NoopModule, moduleMeta)); |     return this._compiler.compileAppModuleAsync(_NoopModule, moduleMeta) | ||||||
|  |         .then((appModuleFactory) => { | ||||||
|  |           this._appModuleFactory = appModuleFactory; | ||||||
|  |           return appModuleFactory; | ||||||
|  |         }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   createInjectorAsync(): Promise<Injector> { |   initTestAppModule() { | ||||||
|  |     if (this._instantiated) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (this._appModuleFactory) { | ||||||
|  |       this._createFromModuleFactory(this._appModuleFactory); | ||||||
|  |     } else { | ||||||
|  |       let moduleMeta = this._createCompilerAndModuleMeta(); | ||||||
|  |       this._createFromModuleFactory(this._compiler.compileAppModuleSync(_NoopModule, moduleMeta)); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** | ||||||
|  |    * @internal | ||||||
|  |    */ | ||||||
|  |   _createInjectorAsync(): Promise<Injector> { | ||||||
|     if (this._instantiated) { |     if (this._instantiated) { | ||||||
|       return Promise.resolve(this); |       return Promise.resolve(this); | ||||||
|     } |     } | ||||||
| @ -115,7 +144,7 @@ export class TestInjector implements Injector { | |||||||
|       deprecatedAppProviders: this._providers |       deprecatedAppProviders: this._providers | ||||||
|     }); |     }); | ||||||
|     const moduleMeta = new AppModuleMetadata({ |     const moduleMeta = new AppModuleMetadata({ | ||||||
|       providers: this._providers.concat([{provide: TestInjector, useValue: this}]), |       providers: this._providers.concat([{provide: TestBed, useValue: this}]), | ||||||
|       modules: this._modules.concat([this.appModule]), |       modules: this._modules.concat([this.appModule]), | ||||||
|       directives: this._directives, |       directives: this._directives, | ||||||
|       pipes: this._pipes, |       pipes: this._pipes, | ||||||
| @ -134,9 +163,9 @@ export class TestInjector implements Injector { | |||||||
|   get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND) { |   get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND) { | ||||||
|     if (!this._instantiated) { |     if (!this._instantiated) { | ||||||
|       throw new BaseException( |       throw new BaseException( | ||||||
|           'Illegal state: The TestInjector has not yet been created. Call createInjectorSync/Async first!'); |           'Illegal state: The test bed\'s injector has not yet been created. Call initTestAppModule first!'); | ||||||
|     } |     } | ||||||
|     if (token === TestInjector) { |     if (token === TestBed) { | ||||||
|       return this; |       return this; | ||||||
|     } |     } | ||||||
|     // Tests can inject things from the app module and from the compiler,
 |     // Tests can inject things from the app module and from the compiler,
 | ||||||
| @ -148,23 +177,30 @@ export class TestInjector implements Injector { | |||||||
|   execute(tokens: any[], fn: Function): any { |   execute(tokens: any[], fn: Function): any { | ||||||
|     if (!this._instantiated) { |     if (!this._instantiated) { | ||||||
|       throw new BaseException( |       throw new BaseException( | ||||||
|           'Illegal state: The TestInjector has not yet been created. Call createInjectorSync/Async first!'); |           'Illegal state: The test bed\'s injector has not yet been created. Call initTestAppModule 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); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var _testInjector: TestInjector = null; | var _testBed: TestBed = null; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * @experimental |  * @experimental | ||||||
|  */ |  */ | ||||||
| export function getTestInjector() { | export function getTestBed() { | ||||||
|   if (_testInjector == null) { |   if (_testBed == null) { | ||||||
|     _testInjector = new TestInjector(); |     _testBed = new TestBed(); | ||||||
|   } |   } | ||||||
|   return _testInjector; |   return _testBed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * @deprecated use getTestBed instead. | ||||||
|  |  */ | ||||||
|  | export function getTestInjector() { | ||||||
|  |   return getTestBed(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -208,12 +244,12 @@ export function setBaseTestProviders( | |||||||
|  * @experimental |  * @experimental | ||||||
|  */ |  */ | ||||||
| export function initTestEnvironment(appModule: Type, platform: PlatformRef) { | export function initTestEnvironment(appModule: Type, platform: PlatformRef) { | ||||||
|   var testInjector = getTestInjector(); |   var testBed = getTestBed(); | ||||||
|   if (testInjector.platform || testInjector.appModule) { |   if (testBed.platform || testBed.appModule) { | ||||||
|     throw new BaseException('Cannot set base providers because it has already been called'); |     throw new BaseException('Cannot set base providers because it has already been called'); | ||||||
|   } |   } | ||||||
|   testInjector.platform = platform; |   testBed.platform = platform; | ||||||
|   testInjector.appModule = appModule; |   testBed.appModule = appModule; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -231,10 +267,22 @@ export function resetBaseTestProviders() { | |||||||
|  * @experimental |  * @experimental | ||||||
|  */ |  */ | ||||||
| export function resetTestEnvironment() { | export function resetTestEnvironment() { | ||||||
|   var testInjector = getTestInjector(); |   var testBed = getTestBed(); | ||||||
|   testInjector.platform = null; |   testBed.platform = null; | ||||||
|   testInjector.appModule = null; |   testBed.appModule = null; | ||||||
|   testInjector.reset(); |   testBed.reset(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Run asynchronous precompilation for the test's AppModule. It is necessary to call this function | ||||||
|  |  * if your test is using an AppModule which has precompiled components that require an asynchronous | ||||||
|  |  * call, such as an XHR. Should be called once before the test case. | ||||||
|  |  * | ||||||
|  |  * @experimental | ||||||
|  |  */ | ||||||
|  | export function doAsyncPrecompilation(): Promise<any> { | ||||||
|  |   let testBed = getTestBed(); | ||||||
|  |   return testBed.createAppModuleFactory(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -262,39 +310,31 @@ export function resetTestEnvironment() { | |||||||
|  * @stable |  * @stable | ||||||
|  */ |  */ | ||||||
| export function inject(tokens: any[], fn: Function): () => any { | export function inject(tokens: any[], fn: Function): () => any { | ||||||
|   let testInjector = getTestInjector(); |   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 the
 | ||||||
|       // injected tokens.
 |       // injected tokens.
 | ||||||
|       return testInjector.createInjectorAsync().then(() => { |       return testBed._createInjectorAsync().then(() => { | ||||||
|         let completer: AsyncTestCompleter = testInjector.get(AsyncTestCompleter); |         let completer: AsyncTestCompleter = testBed.get(AsyncTestCompleter); | ||||||
|         testInjector.execute(tokens, fn); |         testBed.execute(tokens, fn); | ||||||
|         return completer.promise; |         return completer.promise; | ||||||
|       }); |       }); | ||||||
|     }; |     }; | ||||||
|   } else { |   } else { | ||||||
|     return () => { |     return () => { | ||||||
|       // Return a asynchronous test method with the injected tokens.
 |       try { | ||||||
|       // TODO(tbosch): Right now, we can only detect the AsyncTestZoneSpec via its name.
 |         testBed.initTestAppModule(); | ||||||
|       // (see https://github.com/angular/zone.js/issues/370)
 |       } catch (e) { | ||||||
|       if (Zone.current.name.toLowerCase().indexOf('asynctestzone') >= 0) { |         if (e instanceof ComponentStillLoadingError) { | ||||||
|         return testInjector.createInjectorAsync().then(() => testInjector.execute(tokens, fn)); |           throw new Error( | ||||||
|       } else { |               `This test module precompiles the component ${stringify(e.compType)} which is using a "templateUrl", but precompilation was never done. ` + | ||||||
|         // Return a synchronous test method with the injected tokens.
 |               `Please call "doAsyncPrecompilation" before "inject".`); | ||||||
|         try { |         } else { | ||||||
|           testInjector.createInjectorSync(); |           throw e; | ||||||
|         } catch (e) { |  | ||||||
|           if (e instanceof ComponentStillLoadingError) { |  | ||||||
|             throw new Error( |  | ||||||
|                 `This test module precompiles the component ${stringify(e.compType)} which is using a "templateUrl", but the test is synchronous. ` + |  | ||||||
|                 `Please use the "async(...)" or "fakeAsync(...)" helper functions to make the test asynchronous.`); |  | ||||||
|           } else { |  | ||||||
|             throw e; |  | ||||||
|           } |  | ||||||
|         } |         } | ||||||
|         return testInjector.execute(tokens, fn); |  | ||||||
|       } |       } | ||||||
|  |       return testBed.execute(tokens, fn); | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @ -314,14 +354,14 @@ export class InjectSetupWrapper { | |||||||
|   private _addModule() { |   private _addModule() { | ||||||
|     var moduleDef = this._moduleDef(); |     var moduleDef = this._moduleDef(); | ||||||
|     if (moduleDef) { |     if (moduleDef) { | ||||||
|       getTestInjector().configureModule(moduleDef); |       getTestBed().configureModule(moduleDef); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   inject(tokens: any[], fn: Function): () => any { |   inject(tokens: any[], fn: Function): () => any { | ||||||
|     return () => { |     return () => { | ||||||
|       this._addModule(); |       this._addModule(); | ||||||
|       return inject_impl(tokens, fn)(); |       return inject(tokens, fn)(); | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @ -346,9 +386,4 @@ export function withModule(moduleDef: () => { | |||||||
|   return new InjectSetupWrapper(moduleDef); |   return new InjectSetupWrapper(moduleDef); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| // This is to ensure inject(Async) within InjectSetupWrapper doesn't call itself
 |  | ||||||
| // when transpiled to Dart.
 |  | ||||||
| var inject_impl = inject; |  | ||||||
| 
 |  | ||||||
| class _NoopModule {} | class _NoopModule {} | ||||||
| @ -12,17 +12,17 @@ | |||||||
|  * allows tests to be asynchronous by either returning a promise or using a 'done' parameter. |  * allows tests to be asynchronous by either returning a promise or using a 'done' parameter. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| import {TestInjector, getTestInjector} from './test_injector'; | import {TestBed, 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 testInjector: TestInjector = getTestInjector(); | 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(() => { testInjector.reset(); }); |   _global.beforeEach(() => { testBed.reset(); }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -34,7 +34,7 @@ if (_global.beforeEach) { | |||||||
| export function addProviders(providers: Array<any>): void { | export function addProviders(providers: Array<any>): void { | ||||||
|   if (!providers) return; |   if (!providers) return; | ||||||
|   try { |   try { | ||||||
|     testInjector.configureModule({providers: providers}); |     testBed.configureModule({providers: providers}); | ||||||
|   } catch (e) { |   } catch (e) { | ||||||
|     throw new Error( |     throw new Error( | ||||||
|         'addProviders can\'t be called after the injector has been already created for this test. ' + |         'addProviders can\'t be called after the injector has been already created for this test. ' + | ||||||
| @ -58,7 +58,7 @@ export function configureModule(moduleDef: { | |||||||
| }): void { | }): void { | ||||||
|   if (!moduleDef) return; |   if (!moduleDef) return; | ||||||
|   try { |   try { | ||||||
|     testInjector.configureModule(moduleDef); |     testBed.configureModule(moduleDef); | ||||||
|   } catch (e) { |   } catch (e) { | ||||||
|     throw new Error( |     throw new Error( | ||||||
|         'configureModule can\'t be called after the injector has been already created for this test. ' + |         'configureModule can\'t be called after the injector has been already created for this test. ' + | ||||||
| @ -76,7 +76,7 @@ export function configureModule(moduleDef: { | |||||||
| export function configureCompiler(config: {providers?: any[], useJit?: boolean}): void { | export function configureCompiler(config: {providers?: any[], useJit?: boolean}): void { | ||||||
|   if (!config) return; |   if (!config) return; | ||||||
|   try { |   try { | ||||||
|     testInjector.configureCompiler(config); |     testBed.configureCompiler(config); | ||||||
|   } catch (e) { |   } catch (e) { | ||||||
|     throw new Error( |     throw new Error( | ||||||
|         'configureCompiler can\'t be called after the injector has been already created for this test. ' + |         'configureCompiler can\'t be called after the injector has been already created for this test. ' + | ||||||
|  | |||||||
| @ -11,11 +11,11 @@ import {StringMapWrapper} from '../src/facade/collection'; | |||||||
| import {Math, global, isFunction, isPromise} from '../src/facade/lang'; | import {Math, global, isFunction, isPromise} from '../src/facade/lang'; | ||||||
| 
 | 
 | ||||||
| import {AsyncTestCompleter} from './async_test_completer'; | import {AsyncTestCompleter} from './async_test_completer'; | ||||||
| import {getTestInjector, inject} from './test_injector'; | import {getTestBed, inject} from './test_bed'; | ||||||
| 
 | 
 | ||||||
| export {AsyncTestCompleter} from './async_test_completer'; | export {AsyncTestCompleter} from './async_test_completer'; | ||||||
| export {MockAnimationPlayer} from './mock_animation_player'; | export {MockAnimationPlayer} from './mock_animation_player'; | ||||||
| export {inject} from './test_injector'; | export {inject} from './test_bed'; | ||||||
| export * from './logger'; | export * from './logger'; | ||||||
| export * from './ng_zone_mock'; | export * from './ng_zone_mock'; | ||||||
| export * from './mock_application_ref'; | export * from './mock_application_ref'; | ||||||
| @ -40,7 +40,7 @@ var inIt = false; | |||||||
| jasmine.DEFAULT_TIMEOUT_INTERVAL = 3000; | jasmine.DEFAULT_TIMEOUT_INTERVAL = 3000; | ||||||
| var globalTimeOut = jasmine.DEFAULT_TIMEOUT_INTERVAL; | var globalTimeOut = jasmine.DEFAULT_TIMEOUT_INTERVAL; | ||||||
| 
 | 
 | ||||||
| var testInjector = getTestInjector(); | var testBed = getTestBed(); | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Mechanism to run `beforeEach()` functions of Angular tests. |  * Mechanism to run `beforeEach()` functions of Angular tests. | ||||||
| @ -61,7 +61,7 @@ class BeforeEachRunner { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Reset the test providers before each test
 | // Reset the test providers before each test
 | ||||||
| jsmBeforeEach(() => { testInjector.reset(); }); | jsmBeforeEach(() => { testBed.reset(); }); | ||||||
| 
 | 
 | ||||||
| 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; | ||||||
|     testInjector.configureModule({providers: providers}); |     testBed.configureModule({providers: providers}); | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -138,7 +138,7 @@ function _it(jsmFn: Function, name: string, testFn: Function, testTimeOut: numbe | |||||||
|         return new AsyncTestCompleter(); |         return new AsyncTestCompleter(); | ||||||
|       } |       } | ||||||
|     }; |     }; | ||||||
|     testInjector.configureModule({providers: [completerProvider]}); |     testBed.configureModule({providers: [completerProvider]}); | ||||||
|     runner.run(); |     runner.run(); | ||||||
| 
 | 
 | ||||||
|     inIt = true; |     inIt = true; | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ | |||||||
| import {NgIf} from '@angular/common'; | import {NgIf} from '@angular/common'; | ||||||
| import {CompilerConfig, XHR} from '@angular/compiler'; | import {CompilerConfig, XHR} from '@angular/compiler'; | ||||||
| import {AppModule, Component, ComponentFactoryResolver, Directive, Injectable, Input, Pipe, ViewMetadata, provide} from '@angular/core'; | import {AppModule, Component, ComponentFactoryResolver, Directive, Injectable, Input, Pipe, ViewMetadata, provide} from '@angular/core'; | ||||||
| import {TestComponentBuilder, addProviders, async, configureCompiler, configureModule, fakeAsync, inject, tick, withModule, withProviders} from '@angular/core/testing'; | import {TestComponentBuilder, addProviders, async, configureCompiler, configureModule, doAsyncPrecompilation, 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'; | ||||||
| @ -115,7 +115,10 @@ class CompUsingModuleDirectiveAndPipe { | |||||||
| class SomeNestedModule { | class SomeNestedModule { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Component({selector: 'comp', templateUrl: 'someTemplate.html'}) | @Component({ | ||||||
|  |   selector: 'comp', | ||||||
|  |   templateUrl: '/base/modules/@angular/platform-browser/test/static_assets/test.html' | ||||||
|  | }) | ||||||
| class CompWithUrlTemplate { | class CompWithUrlTemplate { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -296,27 +299,16 @@ export function main() { | |||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     describe('precompile components with template url', () => { |     describe('precompile components with template url', () => { | ||||||
|       let xhrGet: jasmine.Spy; |       beforeEach(async(() => { | ||||||
|       beforeEach(() => { |         configureModule({precompile: [CompWithUrlTemplate]}); | ||||||
|         xhrGet = jasmine.createSpy('xhrGet').and.returnValue(Promise.resolve('Hello world!')); |         doAsyncPrecompilation(); | ||||||
|         configureCompiler({providers: [{provide: XHR, useValue: {get: xhrGet}}]}); |       })); | ||||||
|       }); |  | ||||||
| 
 | 
 | ||||||
|       it('should allow to precompile components with templateUrl using the async helper', |       it('should allow to createSync components with templateUrl after async precompilation', | ||||||
|          async(withModule(() => { |          inject([TestComponentBuilder], (builder: TestComponentBuilder) => { | ||||||
|                  return {precompile: [CompWithUrlTemplate]}; |            let fixture = builder.createSync(CompWithUrlTemplate); | ||||||
|                }).inject([ComponentFactoryResolver], (resolver: ComponentFactoryResolver) => { |            expect(fixture.nativeElement).toHaveText('from external template\n'); | ||||||
|            expect(resolver.resolveComponentFactory(CompWithUrlTemplate).componentType) |          })); | ||||||
|                .toBe(CompWithUrlTemplate); |  | ||||||
|          }))); |  | ||||||
| 
 |  | ||||||
|       it('should allow to precompile components with templateUrl using the fakeAsync helper', |  | ||||||
|          fakeAsync(withModule(() => { |  | ||||||
|                      return {precompile: [CompWithUrlTemplate]}; |  | ||||||
|                    }).inject([ComponentFactoryResolver], (resolver: ComponentFactoryResolver) => { |  | ||||||
|            expect(resolver.resolveComponentFactory(CompWithUrlTemplate).componentType) |  | ||||||
|                .toBe(CompWithUrlTemplate); |  | ||||||
|          }))); |  | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     describe('setting up the compiler', () => { |     describe('setting up the compiler', () => { | ||||||
| @ -450,26 +442,27 @@ export function main() { | |||||||
|         configureCompiler({providers: [{provide: XHR, useValue: {get: xhrGet}}]}); |         configureCompiler({providers: [{provide: XHR, useValue: {get: xhrGet}}]}); | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
|       it('should report an error for precompile components with templateUrl and sync tests', () => { |       it('should report an error for precompile components with templateUrl which never call doAsyncPrecompile', | ||||||
|         var itPromise = patchJasmineIt(); |          () => { | ||||||
|  |            var itPromise = patchJasmineIt(); | ||||||
| 
 | 
 | ||||||
|         expect( |            expect( | ||||||
|             () => it( |                () => | ||||||
|                 'should fail', |                    it('should fail', | ||||||
|                 withModule(() => { return {precompile: [CompWithUrlTemplate]}; }) |                       withModule(() => { return {precompile: [CompWithUrlTemplate]}; }) | ||||||
|                     .inject( |                           .inject( | ||||||
|                         [ComponentFactoryResolver], |                               [ComponentFactoryResolver], | ||||||
|                         (resolver: ComponentFactoryResolver) => { |                               (resolver: ComponentFactoryResolver) => { | ||||||
|                           expect( |                                 expect(resolver.resolveComponentFactory(CompWithUrlTemplate) | ||||||
|                               resolver.resolveComponentFactory(CompWithUrlTemplate).componentType) |                                            .componentType) | ||||||
|                               .toBe(CompWithUrlTemplate); |                                     .toBe(CompWithUrlTemplate); | ||||||
|                         }))) |                               }))) | ||||||
|             .toThrowError( |                .toThrowError( | ||||||
|                 `This test module precompiles the component ${stringify(CompWithUrlTemplate)} which is using a "templateUrl", but the test is synchronous. ` + |                    `This test module precompiles the component ${stringify(CompWithUrlTemplate)} which is using a "templateUrl", but precompilation was never done. ` + | ||||||
|                 'Please use the "async(...)" or "fakeAsync(...)" helper functions to make the test asynchronous.'); |                    'Please call "doAsyncPrecompilation" before "inject".'); | ||||||
| 
 | 
 | ||||||
|         restoreJasmineIt(); |            restoreJasmineIt(); | ||||||
|       }); |          }); | ||||||
| 
 | 
 | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ | |||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| import {NgZone, provide} from '@angular/core'; | import {NgZone, provide} from '@angular/core'; | ||||||
| import {withProviders} from '@angular/core/testing/test_injector'; | import {withProviders} from '@angular/core/testing/test_bed'; | ||||||
| import {MockNgZone, beforeEach, beforeEachProviders, describe, expect, inject, it} from '@angular/core/testing/testing_internal'; | import {MockNgZone, beforeEach, beforeEachProviders, describe, expect, inject, it} from '@angular/core/testing/testing_internal'; | ||||||
| import {AsyncTestCompleter} from '@angular/core/testing/testing_internal'; | import {AsyncTestCompleter} from '@angular/core/testing/testing_internal'; | ||||||
| import {MessageBus} from '@angular/platform-browser/src/web_workers/shared/message_bus'; | import {MessageBus} from '@angular/platform-browser/src/web_workers/shared/message_bus'; | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ | |||||||
| 
 | 
 | ||||||
| import {inject, ddescribe, describe, it, iit, expect, beforeEach, beforeEachProviders,} from '@angular/core/testing/testing_internal'; | import {inject, ddescribe, describe, it, iit, expect, beforeEach, beforeEachProviders,} from '@angular/core/testing/testing_internal'; | ||||||
| import {AsyncTestCompleter} from '@angular/core/testing/testing_internal'; | import {AsyncTestCompleter} from '@angular/core/testing/testing_internal'; | ||||||
| import {TestInjector, TestComponentBuilder, configureModule} from '@angular/core/testing'; | import {TestBed, TestComponentBuilder, configureModule} 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 {provide, Injector, ViewMetadata, Component, Injectable, ComponentRef, ReflectiveInjector, getPlatform} from '@angular/core'; | import {provide, Injector, ViewMetadata, Component, Injectable, ComponentRef, ReflectiveInjector, getPlatform} from '@angular/core'; | ||||||
| import {NgIf} from '@angular/common'; | import {NgIf} from '@angular/common'; | ||||||
| @ -67,7 +67,7 @@ export function main() { | |||||||
| 
 | 
 | ||||||
|         beforeEach(() => { |         beforeEach(() => { | ||||||
|           uiRenderStore = new RenderStore(); |           uiRenderStore = new RenderStore(); | ||||||
|           var testUiInjector = new TestInjector(); |           var testUiInjector = new TestBed(); | ||||||
|           testUiInjector.platform = browserDynamicTestPlatform(); |           testUiInjector.platform = browserDynamicTestPlatform(); | ||||||
|           testUiInjector.appModule = BrowserTestModule; |           testUiInjector.appModule = BrowserTestModule; | ||||||
|           testUiInjector.configureModule({ |           testUiInjector.configureModule({ | ||||||
| @ -77,9 +77,9 @@ export function main() { | |||||||
|               {provide: RootRenderer, useExisting: DomRootRenderer} |               {provide: RootRenderer, useExisting: DomRootRenderer} | ||||||
|             ] |             ] | ||||||
|           }); |           }); | ||||||
|           uiInjector = testUiInjector.createInjectorSync(); |           testUiInjector.initTestAppModule(); | ||||||
|           var uiSerializer = uiInjector.get(Serializer); |           var uiSerializer = testUiInjector.get(Serializer); | ||||||
|           var domRootRenderer = uiInjector.get(DomRootRenderer); |           var domRootRenderer = testUiInjector.get(DomRootRenderer); | ||||||
|           workerRenderStore = new RenderStore(); |           workerRenderStore = new RenderStore(); | ||||||
| 
 | 
 | ||||||
|           configureModule({ |           configureModule({ | ||||||
|  | |||||||
							
								
								
									
										52
									
								
								tools/public_api_guard/core/testing.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								tools/public_api_guard/core/testing.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -46,6 +46,9 @@ export declare function configureModule(moduleDef: { | |||||||
| /** @experimental */ | /** @experimental */ | ||||||
| export declare function discardPeriodicTasks(): void; | export declare function discardPeriodicTasks(): void; | ||||||
| 
 | 
 | ||||||
|  | /** @experimental */ | ||||||
|  | export declare function doAsyncPrecompilation(): Promise<any>; | ||||||
|  | 
 | ||||||
| /** @experimental */ | /** @experimental */ | ||||||
| export declare function fakeAsync(fn: Function): (...args: any[]) => any; | export declare function fakeAsync(fn: Function): (...args: any[]) => any; | ||||||
| 
 | 
 | ||||||
| @ -53,7 +56,10 @@ export declare function fakeAsync(fn: Function): (...args: any[]) => any; | |||||||
| export declare function flushMicrotasks(): void; | export declare function flushMicrotasks(): void; | ||||||
| 
 | 
 | ||||||
| /** @experimental */ | /** @experimental */ | ||||||
| export declare function getTestInjector(): TestInjector; | export declare function getTestBed(): TestBed; | ||||||
|  | 
 | ||||||
|  | /** @deprecated */ | ||||||
|  | export declare function getTestInjector(): TestBed; | ||||||
| 
 | 
 | ||||||
| /** @experimental */ | /** @experimental */ | ||||||
| export declare function initTestEnvironment(appModule: Type, platform: PlatformRef): void; | export declare function initTestEnvironment(appModule: Type, platform: PlatformRef): void; | ||||||
| @ -82,6 +88,28 @@ export declare function resetTestEnvironment(): void; | |||||||
| /** @deprecated */ | /** @deprecated */ | ||||||
| export declare function setBaseTestProviders(platformProviders: Array<Type | Provider | any[]>, applicationProviders: Array<Type | Provider | any[]>): void; | export declare function setBaseTestProviders(platformProviders: Array<Type | Provider | any[]>, applicationProviders: Array<Type | Provider | any[]>): void; | ||||||
| 
 | 
 | ||||||
|  | /** @experimental */ | ||||||
|  | export declare class TestBed implements Injector { | ||||||
|  |     appModule: Type; | ||||||
|  |     platform: PlatformRef; | ||||||
|  |     configureCompiler(config: { | ||||||
|  |         providers?: any[]; | ||||||
|  |         useJit?: boolean; | ||||||
|  |     }): void; | ||||||
|  |     configureModule(moduleDef: { | ||||||
|  |         providers?: any[]; | ||||||
|  |         directives?: any[]; | ||||||
|  |         pipes?: any[]; | ||||||
|  |         precompile?: any[]; | ||||||
|  |         modules?: any[]; | ||||||
|  |     }): void; | ||||||
|  |     createAppModuleFactory(): Promise<AppModuleFactory<any>>; | ||||||
|  |     execute(tokens: any[], fn: Function): any; | ||||||
|  |     get(token: any, notFoundValue?: any): any; | ||||||
|  |     initTestAppModule(): void; | ||||||
|  |     reset(): void; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /** @stable */ | /** @stable */ | ||||||
| export declare class TestComponentBuilder { | export declare class TestComponentBuilder { | ||||||
|     protected _injector: Injector; |     protected _injector: Injector; | ||||||
| @ -103,28 +131,6 @@ export declare class TestComponentRenderer { | |||||||
|     insertRootElement(rootElementId: string): void; |     insertRootElement(rootElementId: string): void; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** @experimental */ |  | ||||||
| export declare class TestInjector implements Injector { |  | ||||||
|     appModule: Type; |  | ||||||
|     platform: PlatformRef; |  | ||||||
|     configureCompiler(config: { |  | ||||||
|         providers?: any[]; |  | ||||||
|         useJit?: boolean; |  | ||||||
|     }): void; |  | ||||||
|     configureModule(moduleDef: { |  | ||||||
|         providers?: any[]; |  | ||||||
|         directives?: any[]; |  | ||||||
|         pipes?: any[]; |  | ||||||
|         precompile?: any[]; |  | ||||||
|         modules?: any[]; |  | ||||||
|     }): void; |  | ||||||
|     createInjectorAsync(): Promise<Injector>; |  | ||||||
|     createInjectorSync(): Injector; |  | ||||||
|     execute(tokens: any[], fn: Function): any; |  | ||||||
|     get(token: any, notFoundValue?: any): any; |  | ||||||
|     reset(): void; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** @experimental */ | /** @experimental */ | ||||||
| export declare function tick(millis?: number): void; | export declare function tick(millis?: number): void; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user