refactor(testing): remove wrapping of Jasmine functions (#9564)
Instead, the async function now determines whether it should return a promise or instead call a done function parameter. Importing Jasmine functions from `@angular/core/testing` is no longer necessary and is now deprecated. Additionally, beforeEachProviders is also deprecated, as it is specific to the testing framework. Instead, use the new addProviders method directly. Before: ```js import {beforeEachProviders, it, describe, inject} from 'angular2/testing/core'; describe('my code', () => { beforeEachProviders(() => [MyService]); it('does stuff', inject([MyService], (service) => { // actual test }); }); ``` After: ```js import {addProviders, inject} from 'angular2/testing/core'; describe('my code', () => { beforeEach(() => { addProviders([MyService]); }); it('does stuff', inject([MyService], (service) => { // actual test }); }); ```
This commit is contained in:
parent
a33195dcf3
commit
40b907a657
|
@ -6,6 +6,10 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
declare var global: any;
|
||||
|
||||
var _global = <any>(typeof window === 'undefined' ? global : window);
|
||||
|
||||
/**
|
||||
* Wraps a test function in an asynchronous test zone. The test will automatically
|
||||
* complete when all asynchronous calls within this zone are done. Can be used
|
||||
|
@ -21,16 +25,36 @@
|
|||
* });
|
||||
* ```
|
||||
*/
|
||||
export function async(fn: Function): Function {
|
||||
export function async(fn: Function): (done: any) => any {
|
||||
// If we're running using the Jasmine test framework, adapt to call the 'done'
|
||||
// function when asynchronous activity is finished.
|
||||
if (_global.jasmine) {
|
||||
return (done: any) => {
|
||||
runInTestZone(fn, done, (err: string | Error) => {
|
||||
if (typeof err === 'string') {
|
||||
return done.fail(new Error(<string>err));
|
||||
} else {
|
||||
done.fail(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
// Otherwise, return a promise which will resolve when asynchronous activity
|
||||
// is finished. This will be correctly consumed by the Mocha framework with
|
||||
// it('...', async(myFn)); or can be used in a custom framework.
|
||||
return () => new Promise<void>((finishCallback, failCallback) => {
|
||||
var AsyncTestZoneSpec = (Zone as any /** TODO #9100 */)['AsyncTestZoneSpec'];
|
||||
if (AsyncTestZoneSpec === undefined) {
|
||||
throw new Error(
|
||||
'AsyncTestZoneSpec is needed for the async() test helper but could not be found. ' +
|
||||
'Please make sure that your environment includes zone.js/dist/async-test.js');
|
||||
}
|
||||
var testZoneSpec = new AsyncTestZoneSpec(finishCallback, failCallback, 'test');
|
||||
var testZone = Zone.current.fork(testZoneSpec);
|
||||
return testZone.run(fn);
|
||||
runInTestZone(fn, finishCallback, failCallback);
|
||||
});
|
||||
}
|
||||
|
||||
function runInTestZone(fn: Function, finishCallback: Function, failCallback: Function) {
|
||||
var AsyncTestZoneSpec = (Zone as any /** TODO #9100 */)['AsyncTestZoneSpec'];
|
||||
if (AsyncTestZoneSpec === undefined) {
|
||||
throw new Error(
|
||||
'AsyncTestZoneSpec is needed for the async() test helper but could not be found. ' +
|
||||
'Please make sure that your environment includes zone.js/dist/async-test.js');
|
||||
}
|
||||
var testZoneSpec = new AsyncTestZoneSpec(finishCallback, failCallback, 'test');
|
||||
var testZone = Zone.current.fork(testZoneSpec);
|
||||
return testZone.run(fn);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ let _FakeAsyncTestZoneSpecType = (Zone as any /** TODO #9100 */)['FakeAsyncTestZ
|
|||
* @param fn
|
||||
* @returns {Function} The function wrapped to be executed in the fakeAsync zone
|
||||
*/
|
||||
export function fakeAsync(fn: Function): Function {
|
||||
export function fakeAsync(fn: Function): (...args: any[]) => any {
|
||||
if (Zone.current.get('FakeAsyncTestZoneSpec') != null) {
|
||||
throw new BaseException('fakeAsync() calls can not be nested');
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ export function resetBaseTestProviders() {
|
|||
* becomes `it('...', @Inject (object: AClass, async: AsyncTestCompleter) => { ... });`
|
||||
*
|
||||
*/
|
||||
export function inject(tokens: any[], fn: Function): Function {
|
||||
export function inject(tokens: any[], fn: Function): () => any {
|
||||
let testInjector = getTestInjector();
|
||||
if (tokens.indexOf(AsyncTestCompleter) >= 0) {
|
||||
// Return an async test method that returns a Promise if AsyncTestCompleter is one of the
|
||||
|
@ -158,7 +158,7 @@ export class InjectSetupWrapper {
|
|||
}
|
||||
}
|
||||
|
||||
inject(tokens: any[], fn: Function): Function {
|
||||
inject(tokens: any[], fn: Function): () => any {
|
||||
return () => {
|
||||
this._addProviders();
|
||||
return inject_impl(tokens, fn)();
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Public Test Library for unit testing Angular2 Applications. Uses the
|
||||
* Jasmine framework.
|
||||
* Public Test Library for unit testing Angular2 Applications. Assumes that you are running
|
||||
* with Jasmine, Mocha, or a similar framework which exports a beforeEach function and
|
||||
* allows tests to be asynchronous by either returning a promise or using a 'done' parameter.
|
||||
*/
|
||||
import {isPromise, isString} from '../src/facade/lang';
|
||||
|
||||
import {TestInjector, getTestInjector} from './test_injector';
|
||||
|
||||
|
@ -18,188 +18,121 @@ declare var global: any;
|
|||
|
||||
var _global = <any>(typeof window === 'undefined' ? global : window);
|
||||
|
||||
/**
|
||||
* @deprecated you no longer need to import jasmine functions from @angular/core/testing. Simply use
|
||||
* the globals.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*/
|
||||
export var expect: Function = _global.expect;
|
||||
|
||||
/**
|
||||
* Run a function (with an optional asynchronous callback) after each test case.
|
||||
* @deprecated you no longer need to import jasmine functions from @angular/core/testing. Simply use
|
||||
* the globals.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='afterEach'}
|
||||
*/
|
||||
export var afterEach: Function = _global.afterEach;
|
||||
|
||||
/**
|
||||
* Group test cases together under a common description prefix.
|
||||
* @deprecated you no longer need to import jasmine functions from @angular/core/testing. Simply use
|
||||
* the globals.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='describeIt'}
|
||||
*/
|
||||
export var describe: Function = _global.describe;
|
||||
|
||||
/**
|
||||
* See {@link fdescribe}.
|
||||
*/
|
||||
export var ddescribe: Function = _global.fdescribe;
|
||||
|
||||
/**
|
||||
* Like {@link describe}, but instructs the test runner to only run
|
||||
* the test cases in this group. This is useful for debugging.
|
||||
* @deprecated you no longer need to import jasmine functions from @angular/core/testing. Simply use
|
||||
* the globals.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='fdescribe'}
|
||||
*/
|
||||
export var fdescribe: Function = _global.fdescribe;
|
||||
export var fdescribe = _global.fdescribe;
|
||||
|
||||
/**
|
||||
* Like {@link describe}, but instructs the test runner to exclude
|
||||
* this group of test cases from execution. This is useful for
|
||||
* debugging, or for excluding broken tests until they can be fixed.
|
||||
* @deprecated you no longer need to import jasmine functions from @angular/core/testing. Simply use
|
||||
* the globals.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*/
|
||||
export var ddescribe = _global.ddescribe;
|
||||
|
||||
/**
|
||||
* @deprecated you no longer need to import jasmine functions from @angular/core/testing. Simply use
|
||||
* the globals.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='xdescribe'}
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*/
|
||||
export var xdescribe: Function = _global.xdescribe;
|
||||
|
||||
var jsmBeforeEach = _global.beforeEach;
|
||||
var jsmIt = _global.it;
|
||||
var jsmIIt = _global.fit;
|
||||
var jsmXIt = _global.xit;
|
||||
/**
|
||||
* @deprecated you no longer need to import jasmine functions from @angular/core/testing. Simply use
|
||||
* the globals.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*/
|
||||
export var beforeEach = _global.beforeEach;
|
||||
|
||||
/**
|
||||
* @deprecated you no longer need to import jasmine functions from @angular/core/testing. Simply use
|
||||
* the globals.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*/
|
||||
export var it = _global.it;
|
||||
|
||||
/**
|
||||
* @deprecated you no longer need to import jasmine functions from @angular/core/testing. Simply use
|
||||
* the globals.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*/
|
||||
export var fit = _global.fit;
|
||||
|
||||
/**
|
||||
* @deprecated you no longer need to import jasmine functions from @angular/core/testing. Simply use
|
||||
* the globals.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*/
|
||||
export var iit = _global.fit;
|
||||
|
||||
/**
|
||||
* @deprecated you no longer need to import jasmine functions from @angular/core/testing. Simply use
|
||||
* the globals.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*/
|
||||
export var xit = _global.xit;
|
||||
|
||||
// TODO(juliemr): override the globals and make them throw with a useful message.
|
||||
|
||||
var testInjector: TestInjector = getTestInjector();
|
||||
|
||||
// Reset the test providers before each test.
|
||||
jsmBeforeEach(() => { testInjector.reset(); });
|
||||
if (_global.beforeEach) {
|
||||
beforeEach(() => { testInjector.reset(); });
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows overriding default providers of the test injector,
|
||||
* which are defined in test_injector.js.
|
||||
*
|
||||
* The given function must return a list of DI providers.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='beforeEachProviders'}
|
||||
* which are defined in test_injector.js
|
||||
*/
|
||||
export function addProviders(providers: Array<any>): void {
|
||||
if (!providers) return;
|
||||
try {
|
||||
testInjector.addProviders(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.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use beforeEach(() => addProviders())
|
||||
*/
|
||||
export function beforeEachProviders(fn: () => Array<any>): void {
|
||||
jsmBeforeEach(() => {
|
||||
var providers = fn();
|
||||
if (!providers) return;
|
||||
try {
|
||||
testInjector.addProviders(providers);
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
'beforeEachProviders was called after the injector had ' +
|
||||
'been used in a beforeEach or it block. This invalidates the ' +
|
||||
'test injector');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function _wrapTestFn(fn: Function) {
|
||||
// Wraps a test or beforeEach function to handle synchronous and asynchronous execution.
|
||||
return (done: any) => {
|
||||
if (fn.length === 0) {
|
||||
let retVal = fn();
|
||||
if (isPromise(retVal)) {
|
||||
// Asynchronous test function - wait for completion.
|
||||
(<Promise<any>>retVal).then(done, (err) => {
|
||||
if (isString(err)) {
|
||||
return done.fail(new Error(err));
|
||||
}
|
||||
return done.fail(err);
|
||||
});
|
||||
} else {
|
||||
// Synchronous test function - complete immediately.
|
||||
done();
|
||||
}
|
||||
} else {
|
||||
// Asynchronous test function that takes "done" as parameter.
|
||||
fn(done);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function _it(jsmFn: Function, name: string, testFn: Function, testTimeOut: number): void {
|
||||
jsmFn(name, _wrapTestFn(testFn), testTimeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around Jasmine beforeEach function.
|
||||
*
|
||||
* beforeEach may be used with the `inject` function to fetch dependencies.
|
||||
*
|
||||
* See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='beforeEach'}
|
||||
*/
|
||||
export function beforeEach(fn: Function): void {
|
||||
jsmBeforeEach(_wrapTestFn(fn));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a single test case with the given test name and execution function.
|
||||
*
|
||||
* The test function can be either a synchronous function, the result of {@link async},
|
||||
* or an injected function created via {@link inject}.
|
||||
*
|
||||
* Wrapper around Jasmine it function. See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='describeIt'}
|
||||
*/
|
||||
export function it(name: string, fn: Function, timeOut: number = null): void {
|
||||
return _it(jsmIt, name, fn, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link it}, but instructs the test runner to exclude this test
|
||||
* entirely. Useful for debugging or for excluding broken tests until
|
||||
* they can be fixed.
|
||||
*
|
||||
* Wrapper around Jasmine xit function. See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='xit'}
|
||||
*/
|
||||
export function xit(name: string, fn: Function, timeOut: number = null): void {
|
||||
return _it(jsmXIt, name, fn, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link fit}.
|
||||
*/
|
||||
export function iit(name: string, fn: Function, timeOut: number = null): void {
|
||||
return _it(jsmIIt, name, fn, timeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link it}, but instructs the test runner to only run this test.
|
||||
* Useful for debugging.
|
||||
*
|
||||
* Wrapper around Jasmine fit function. See http://jasmine.github.io/ for more details.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {@example testing/ts/testing.ts region='fit'}
|
||||
*/
|
||||
export function fit(name: string, fn: Function, timeOut: number = null): void {
|
||||
return _it(jsmIIt, name, fn, timeOut);
|
||||
beforeEach(() => { addProviders(fn()); });
|
||||
}
|
||||
|
|
|
@ -6,10 +6,9 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing';
|
||||
|
||||
import {fakeAsync, async, withProviders, tick,} from '@angular/core/testing';
|
||||
import {addProviders, inject, fakeAsync, async, withProviders, tick,} from '@angular/core/testing';
|
||||
import {TestComponentBuilder} from '@angular/compiler/testing';
|
||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||
import {Injectable, provide, Component, ViewMetadata} from '@angular/core';
|
||||
import {NgIf} from '@angular/common';
|
||||
import {PromiseWrapper} from '../../http/src/facade/promise';
|
||||
|
@ -127,7 +126,7 @@ export function main() {
|
|||
|
||||
describe('using the test injector with the inject helper', () => {
|
||||
describe('setting up Providers', () => {
|
||||
beforeEachProviders(() => [{provide: FancyService, useValue: new FancyService()}]);
|
||||
beforeEach(() => addProviders([{provide: FancyService, useValue: new FancyService()}]));
|
||||
|
||||
it('should use set up providers', inject([FancyService], (service: any /** TODO #9100 */) => {
|
||||
expect(service.value).toEqual('real value');
|
||||
|
@ -273,23 +272,24 @@ export function main() {
|
|||
restoreJasmineIt();
|
||||
});
|
||||
|
||||
describe('using beforeEachProviders', () => {
|
||||
beforeEachProviders(() => [{provide: FancyService, useValue: new FancyService()}]);
|
||||
describe('using addProviders', () => {
|
||||
beforeEach(() => addProviders([{provide: FancyService, useValue: new FancyService()}]));
|
||||
|
||||
beforeEach(inject([FancyService], (service: any /** TODO #9100 */) => {
|
||||
expect(service.value).toEqual('real value');
|
||||
}));
|
||||
|
||||
describe('nested beforeEachProviders', () => {
|
||||
describe('nested addProviders', () => {
|
||||
|
||||
it('should fail when the injector has already been used', () => {
|
||||
patchJasmineBeforeEach();
|
||||
expect(() => {
|
||||
beforeEachProviders(() => [{provide: FancyService, useValue: new FancyService()}]);
|
||||
beforeEach(() => addProviders([{provide: FancyService, useValue: new FancyService()}]));
|
||||
})
|
||||
.toThrowError(
|
||||
'beforeEachProviders was called after the injector had been used ' +
|
||||
'in a beforeEach or it block. This invalidates the test injector');
|
||||
'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.');
|
||||
restoreJasmineBeforeEach();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
export declare function addProviders(providers: Array<any>): void;
|
||||
|
||||
export declare var afterEach: Function;
|
||||
|
||||
export declare function async(fn: Function): Function;
|
||||
export declare function async(fn: Function): (done: any) => any;
|
||||
|
||||
export declare function beforeEach(fn: Function): void;
|
||||
export declare var beforeEach: any;
|
||||
|
||||
export declare function beforeEachProviders(fn: () => Array<any>): void;
|
||||
|
||||
|
@ -27,7 +29,7 @@ export declare var ComponentFixtureAutoDetect: OpaqueToken;
|
|||
|
||||
export declare var ComponentFixtureNoNgZone: OpaqueToken;
|
||||
|
||||
export declare var ddescribe: Function;
|
||||
export declare var ddescribe: any;
|
||||
|
||||
export declare var describe: Function;
|
||||
|
||||
|
@ -35,26 +37,26 @@ export declare function discardPeriodicTasks(): void;
|
|||
|
||||
export declare var expect: Function;
|
||||
|
||||
export declare function fakeAsync(fn: Function): Function;
|
||||
export declare function fakeAsync(fn: Function): (...args: any[]) => any;
|
||||
|
||||
export declare var fdescribe: Function;
|
||||
export declare var fdescribe: any;
|
||||
|
||||
export declare function fit(name: string, fn: Function, timeOut?: number): void;
|
||||
export declare var fit: any;
|
||||
|
||||
export declare function flushMicrotasks(): void;
|
||||
|
||||
export declare function getTestInjector(): TestInjector;
|
||||
|
||||
export declare function iit(name: string, fn: Function, timeOut?: number): void;
|
||||
export declare var iit: any;
|
||||
|
||||
export declare function inject(tokens: any[], fn: Function): Function;
|
||||
export declare function inject(tokens: any[], fn: Function): () => any;
|
||||
|
||||
export declare class InjectSetupWrapper {
|
||||
constructor(_providers: () => any);
|
||||
inject(tokens: any[], fn: Function): Function;
|
||||
inject(tokens: any[], fn: Function): () => any;
|
||||
}
|
||||
|
||||
export declare function it(name: string, fn: Function, timeOut?: number): void;
|
||||
export declare var it: any;
|
||||
|
||||
export declare function resetBaseTestProviders(): void;
|
||||
|
||||
|
@ -95,4 +97,4 @@ export declare function withProviders(providers: () => any): InjectSetupWrapper;
|
|||
|
||||
export declare var xdescribe: Function;
|
||||
|
||||
export declare function xit(name: string, fn: Function, timeOut?: number): void;
|
||||
export declare var xit: any;
|
||||
|
|
Loading…
Reference in New Issue