Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(testing): remove wrapping of Jasmine functions #9564

Merged
merged 1 commit into from Jun 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 34 additions & 10 deletions modules/@angular/core/testing/async.ts
Expand Up @@ -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
Expand All @@ -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);
}
2 changes: 1 addition & 1 deletion modules/@angular/core/testing/fake_async.ts
Expand Up @@ -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');
}
Expand Down
4 changes: 2 additions & 2 deletions modules/@angular/core/testing/test_injector.ts
Expand Up @@ -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
Expand All @@ -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)();
Expand Down
201 changes: 67 additions & 134 deletions modules/@angular/core/testing/testing.ts
Expand Up @@ -7,199 +7,132 @@
*/

/**
* 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';

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}.
* @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: Function = _global.fdescribe;
export var fdescribe = _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 ddescribe = _global.ddescribe;

/**
* 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.
*
* ## Example:
*
* {@example testing/ts/testing.ts region='xdescribe'}
*/
export var xdescribe: Function = _global.xdescribe;

var jsmBeforeEach = _global.beforeEach;
var jsmIt = _global.it;
var jsmIIt = _global.fit;
var jsmXIt = _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(); });

/**
* Allows overriding default providers of the test injector,
* which are defined in test_injector.js.
* @deprecated you no longer need to import jasmine functions from @angular/core/testing. Simply use
* the globals.
*
* The given function must return a list of DI providers.
*
* ## Example:
*
* {@example testing/ts/testing.ts region='beforeEachProviders'}
* See http://jasmine.github.io/ for more details.
*/
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);
}
export var beforeEach = _global.beforeEach;

/**
* Wrapper around Jasmine beforeEach function.
*
* beforeEach may be used with the `inject` function to fetch dependencies.
* @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='beforeEach'}
*/
export function beforeEach(fn: Function): void {
jsmBeforeEach(_wrapTestFn(fn));
}
export var it = _global.it;

/**
* 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}.
* @deprecated you no longer need to import jasmine functions from @angular/core/testing. Simply use
* the globals.
*
* Wrapper around Jasmine it function. See http://jasmine.github.io/ for more details.
*
* ## Example:
*
* {@example testing/ts/testing.ts region='describeIt'}
* See http://jasmine.github.io/ for more details.
*/
export function it(name: string, fn: Function, timeOut: number = null): void {
return _it(jsmIt, name, fn, timeOut);
}
export var fit = _global.fit;

/**
* 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.
* @deprecated you no longer need to import jasmine functions from @angular/core/testing. Simply use
* the globals.
*
* Wrapper around Jasmine xit function. See http://jasmine.github.io/ for more details.
*
* ## Example:
* 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.
*
* {@example testing/ts/testing.ts region='xit'}
* See http://jasmine.github.io/ for more details.
*/
export function xit(name: string, fn: Function, timeOut: number = null): void {
return _it(jsmXIt, name, fn, timeOut);
export var xit = _global.xit;


var testInjector: TestInjector = getTestInjector();

// Reset the test providers before each test.
if (_global.beforeEach) {
beforeEach(() => { testInjector.reset(); });
}

/**
* See {@link fit}.
* Allows overriding default providers of the test injector,
* which are defined in test_injector.js
*/
export function iit(name: string, fn: Function, timeOut: number = null): void {
return _it(jsmIIt, name, fn, timeOut);
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.');
}
}

/**
* 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'}
* @deprecated Use beforeEach(() => addProviders())
*/
export function fit(name: string, fn: Function, timeOut: number = null): void {
return _it(jsmIIt, name, fn, timeOut);
export function beforeEachProviders(fn: () => Array<any>): void {
beforeEach(() => { addProviders(fn()); });
}