feat(tests): manage asynchronous tests using zones

Instead of using injectAsync and returning a promise, use the `async` function
to wrap tests. This will run the test inside a zone which does not complete
the test until all asynchronous tasks have been completed.

`async` may be used with the `inject` function, or separately.

BREAKING CHANGE:

`injectAsync` is now deprecated. Instead, use the `async` function
to wrap any asynchronous tests.

Before:
```
it('should wait for returned promises', injectAsync([FancyService], (service) => {
  return service.getAsyncValue().then((value) => { expect(value).toEqual('async value'); });
}));

it('should wait for returned promises', injectAsync([], () => {
  return somePromise.then(() => { expect(true).toEqual(true); });
}));
```

After:
```
it('should wait for returned promises', async(inject([FancyService], (service) => {
  service.getAsyncValue().then((value) => { expect(value).toEqual('async value'); });
})));

// Note that if there is no injection, we no longer need `inject` OR `injectAsync`.
it('should wait for returned promises', async(() => {
  somePromise.then() => { expect(true).toEqual(true); });
}));
```

Closes #7735
This commit is contained in:
Julie Ralph
2016-03-23 10:59:38 -07:00
committed by Robert Messerle
parent ecb9bb96f0
commit 8490921fb3
11 changed files with 289 additions and 254 deletions

View File

@ -130,6 +130,7 @@ export class InjectSetupWrapper {
return new FunctionWithParamTokens(tokens, fn, false, this._providers);
}
/** @Deprecated {use async(withProviders().inject())} */
injectAsync(tokens: any[], fn: Function): FunctionWithParamTokens {
return new FunctionWithParamTokens(tokens, fn, true, this._providers);
}
@ -140,6 +141,8 @@ export function withProviders(providers: () => any) {
}
/**
* @Deprecated {use async(inject())}
*
* Allows injecting dependencies in `beforeEach()` and `it()`. The test must return
* a promise which will resolve when all asynchronous activity is complete.
*
@ -161,6 +164,32 @@ export function injectAsync(tokens: any[], fn: Function): FunctionWithParamToken
return new FunctionWithParamTokens(tokens, fn, true);
}
/**
* 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
* to wrap an {@link inject} call.
*
* Example:
*
* ```
* it('...', async(inject([AClass], (object) => {
* object.doSomething.then(() => {
* expect(...);
* })
* });
* ```
*/
export function async(fn: Function | FunctionWithParamTokens): FunctionWithParamTokens {
if (fn instanceof FunctionWithParamTokens) {
fn.isAsync = true;
return fn;
} else if (fn instanceof Function) {
return new FunctionWithParamTokens([], fn, true);
} else {
throw new BaseException('argument to async must be a function or inject(<Function>)');
}
}
function emptyArray(): Array<any> {
return [];
}