Skip to content

Commit

Permalink
Move promise-handling code to t.throwsAsync and t.notThrowsAsync
Browse files Browse the repository at this point in the history
References #1794.
  • Loading branch information
novemberborn committed Jul 27, 2018
1 parent e0f914a commit 7babf6b
Show file tree
Hide file tree
Showing 9 changed files with 581 additions and 362 deletions.
17 changes: 0 additions & 17 deletions docs/recipes/flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,3 @@ test('an actual test', t => {
```

Note that, despite the type cast above, when executing `t.context` is an empty object unless it's assigned.

## Using `t.throws()` and `t.notThrows()`

The `t.throws()` and `t.noThrows()` assertions can be called with a function that returns an observable or a promise. You may have to explicitly type functions:

```ts
import test from 'ava';

test('just throws', async t => {
const expected = new Error();
const err = t.throws((): void => { throw expected; });
t.is(err, expected);

const err2 = await t.throws((): Promise<*> => Promise.reject(expected));
t.is(err2, expected);
});
```
4 changes: 2 additions & 2 deletions docs/recipes/when-to-use-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ test('rejects with foo', t => {
```

Here, the use of `t.plan()` seeks to ensure that the code inside the `catch` block is executed.
Instead, you should take advantage of `t.throws` and `async`/`await`, as this leads to flatter code that is easier to reason about:
Instead, you should take advantage of `t.throwsAsync` and `async`/`await`, as this leads to flatter code that is easier to reason about:

```js
test('rejects with foo', async t => {
const reason = await t.throws(shouldRejectWithFoo());
const reason = await t.throwsAsync(shouldRejectWithFoo());
t.is(reason.message, 'Hello');
t.is(reason.foo, 'bar');
});
Expand Down
88 changes: 36 additions & 52 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ export interface Assertions {
/** Assert that the function does not throw. */
notThrows: NotThrowsAssertion;

/** Assert that the async function does not throw, or that the promise does not reject. Must be awaited. */
notThrowsAsync: NotThrowsAsyncAssertion;

/** Count a passing assertion. */
pass: PassAssertion;

Expand All @@ -80,6 +83,12 @@ export interface Assertions {
*/
throws: ThrowsAssertion;

/**
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error), or the promise rejects
* with one. If so, returns a promise for the error value, which must be awaited.
*/
throwsAsync: ThrowsAsyncAssertion;

/** Assert that `actual` is strictly true. */
true: TrueAssertion;

Expand Down Expand Up @@ -159,13 +168,15 @@ export interface NotRegexAssertion {

export interface NotThrowsAssertion {
/** Assert that the function does not throw. */
(fn: () => never, message?: string): void;
(fn: () => any, message?: string): void;

/** Assert that the function returns a promise that does not reject. You must await the result. */
(fn: () => PromiseLike<any>, message?: string): Promise<void>;
/** Skip this assertion. */
skip(fn: () => any, message?: string): void;
}

/** Assert that the function does not throw. */
(fn: () => any, message?: string): void;
export interface NotThrowsAsyncAssertion {
/** Assert that the async function does not throw. You must await the result. */
(fn: () => PromiseLike<any>, message?: string): Promise<void>;

/** Assert that the promise does not reject. You must await the result. */
(promise: PromiseLike<any>, message?: string): Promise<void>;
Expand Down Expand Up @@ -216,94 +227,67 @@ export interface ThrowsAssertion {
/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
*/
(fn: () => never, expectations?: null, message?: string): any;
(fn: () => any, expectations?: null, message?: string): any;

/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must be an instance of the given constructor.
*/
(fn: () => never, constructor: Constructor, message?: string): any;
(fn: () => any, constructor: Constructor, message?: string): any;

/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must have a message that matches the regular expression.
*/
(fn: () => never, regex: RegExp, message?: string): any;
(fn: () => any, regex: RegExp, message?: string): any;

/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must have a message equal to `errorMessage`.
*/
(fn: () => never, errorMessage: string, message?: string): any;
(fn: () => any, errorMessage: string, message?: string): any;

/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must satisfy all expectations.
*/
(fn: () => never, expectations: ThrowsExpectation, message?: string): any;
(fn: () => any, expectations: ThrowsExpectation, message?: string): any;

/** Skip this assertion. */
skip(fn: () => any, expectations?: any, message?: string): void;
}

export interface ThrowsAsyncAssertion {
/**
* Assert that the function returns a promise that rejects with [an error](https://www.npmjs.com/package/is-error).
* If so, returns the rejection reason. You must await the result.
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
* value. You must await the result.
*/
(fn: () => PromiseLike<any>, expectations?: null, message?: string): Promise<any>;

/**
* Assert that the function returns a promise that rejects with [an error](https://www.npmjs.com/package/is-error).
* If so, returns the rejection reason. You must await the result. The error must be an instance of the given
* constructor.
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
* value. You must await the result. The error must be an instance of the given constructor.
*/
(fn: () => PromiseLike<any>, constructor: Constructor, message?: string): Promise<any>;

/**
* Assert that the function returns a promise that rejects with [an error](https://www.npmjs.com/package/is-error).
* If so, returns the rejection reason. You must await the result. The error must have a message that matches the
* regular expression.
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
* value. You must await the result. The error must have a message that matches the regular expression.
*/
(fn: () => PromiseLike<any>, regex: RegExp, message?: string): Promise<any>;

/**
* Assert that the function returns a promise that rejects with [an error](https://www.npmjs.com/package/is-error).
* If so, returns the rejection reason. You must await the result. The error must have a message equal to
* `errorMessage`.
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
* value. You must await the result. The error must have a message equal to `errorMessage`.
*/
(fn: () => PromiseLike<any>, errorMessage: string, message?: string): Promise<any>;

/**
* Assert that the function returns a promise that rejects with [an error](https://www.npmjs.com/package/is-error).
* If so, returns the rejection reason. You must await the result. The error must satisfy all expectations.
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
* value. You must await the result. The error must satisfy all expectations.
*/
(fn: () => PromiseLike<any>, expectations: ThrowsExpectation, message?: string): Promise<any>;

/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
*/
(fn: () => any, expectations?: null, message?: string): any;

/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must be an instance of the given constructor.
*/
(fn: () => any, constructor: Constructor, message?: string): any;

/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must have a message that matches the regular expression.
*/
(fn: () => any, regex: RegExp, message?: string): any;

/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must have a message equal to `errorMessage`.
*/
(fn: () => any, errorMessage: string, message?: string): any;

/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must satisfy all expectations.
*/
(fn: () => any, expectations: ThrowsExpectation, message?: string): any;

/**
* Assert that the promise rejects with [an error](https://www.npmjs.com/package/is-error). If so, returns the
* rejection reason. You must await the result.
Expand Down
86 changes: 51 additions & 35 deletions index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ export interface Assertions {
/** Assert that the function does not throw. */
notThrows: NotThrowsAssertion;

/** Assert that the async function does not throw, or that the promise does not reject. Must be awaited. */
notThrowsAsync: NotThrowsAsyncAssertion;

/** Count a passing assertion. */
pass: PassAssertion;

Expand All @@ -93,6 +96,12 @@ export interface Assertions {
*/
throws: ThrowsAssertion;

/**
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error), or the promise rejects
* with one. If so, returns a promise for the error value, which must be awaited.
*/
throwsAsync: ThrowsAsyncAssertion;

/** Assert that `actual` is strictly true. */
true: TrueAssertion;

Expand Down Expand Up @@ -171,12 +180,17 @@ export interface NotRegexAssertion {
}

export interface NotThrowsAssertion {
/** Assert that the function returns a promise that does not reject. You must await the result. */
(fn: () => PromiseLike<any>, message?: string): Promise<void>;

/** Assert that the function does not throw. */
(fn: () => any, message?: string): void;

/** Skip this assertion. */
skip(fn: () => any, message?: string): void;
}

export interface NotThrowsAsyncAssertion {
/** Assert that the async function does not throw. You must await the result. */
(fn: () => PromiseLike<any>, message?: string): Promise<void>;

/** Assert that the promise does not reject. You must await the result. */
(promise: PromiseLike<any>, message?: string): Promise<void>;

Expand Down Expand Up @@ -224,66 +238,68 @@ export interface SnapshotAssertion {

export interface ThrowsAssertion {
/**
* Assert that the function returns a promise that rejects with [an error](https://www.npmjs.com/package/is-error).
* If so, returns the rejection reason. You must await the result.
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
*/
(fn: () => PromiseLike<any>, expectations?: null, message?: string): Promise<any>;
(fn: () => any, expectations?: null, message?: string): any;

/**
* Assert that the function returns a promise that rejects with [an error](https://www.npmjs.com/package/is-error).
* If so, returns the rejection reason. You must await the result. The error must be an instance of the given
* constructor.
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must be an instance of the given constructor.
*/
(fn: () => PromiseLike<any>, constructor: Constructor, message?: string): Promise<any>;
(fn: () => any, constructor: Constructor, message?: string): any;

/**
* Assert that the function returns a promise that rejects with [an error](https://www.npmjs.com/package/is-error).
* If so, returns the rejection reason. You must await the result. The error must have a message that matches the
* regular expression.
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must have a message that matches the regular expression.
*/
(fn: () => PromiseLike<any>, regex: RegExp, message?: string): Promise<any>;
(fn: () => any, regex: RegExp, message?: string): any;

/**
* Assert that the function returns a promise that rejects with [an error](https://www.npmjs.com/package/is-error).
* If so, returns the rejection reason. You must await the result. The error must have a message equal to
* `errorMessage`.
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must have a message equal to `errorMessage`.
*/
(fn: () => PromiseLike<any>, errorMessage: string, message?: string): Promise<any>;
(fn: () => any, errorMessage: string, message?: string): any;

/**
* Assert that the function returns a promise that rejects with [an error](https://www.npmjs.com/package/is-error).
* If so, returns the rejection reason. You must await the result. The error must satisfy all expectations.
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must satisfy all expectations.
*/
(fn: () => PromiseLike<any>, expectations: ThrowsExpectation, message?: string): Promise<any>;
(fn: () => any, expectations: ThrowsExpectation, message?: string): any;

/** Skip this assertion. */
skip(fn: () => any, expectations?: any, message?: string): void;
}

export interface ThrowsAsyncAssertion {
/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
* value. You must await the result.
*/
(fn: () => any, expectations?: null, message?: string): any;
(fn: () => PromiseLike<any>, expectations?: null, message?: string): Promise<any>;

/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must be an instance of the given constructor.
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
* value. You must await the result. The error must be an instance of the given constructor.
*/
(fn: () => any, constructor: Constructor, message?: string): any;
(fn: () => PromiseLike<any>, constructor: Constructor, message?: string): Promise<any>;

/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must have a message that matches the regular expression.
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
* value. You must await the result. The error must have a message that matches the regular expression.
*/
(fn: () => any, regex: RegExp, message?: string): any;
(fn: () => PromiseLike<any>, regex: RegExp, message?: string): Promise<any>;

/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must have a message equal to `errorMessage`.
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
* value. You must await the result. The error must have a message equal to `errorMessage`.
*/
(fn: () => any, errorMessage: string, message?: string): any;
(fn: () => PromiseLike<any>, errorMessage: string, message?: string): Promise<any>;

/**
* Assert that the function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error value.
* The error must satisfy all expectations.
* Assert that the async function throws [an error](https://www.npmjs.com/package/is-error). If so, returns the error
* value. You must await the result. The error must satisfy all expectations.
*/
(fn: () => any, expectations: ThrowsExpectation, message?: string): any;
(fn: () => PromiseLike<any>, expectations: ThrowsExpectation, message?: string): Promise<any>;

/**
* Assert that the promise rejects with [an error](https://www.npmjs.com/package/is-error). If so, returns the
Expand Down
Loading

0 comments on commit 7babf6b

Please sign in to comment.