Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 17 additions & 10 deletions docs/api/assert/rejects.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ version_added: "2.5.0"
---

`rejects( promise, message = "" )`<br>
`rejects( promise, expectedMatcher, message = "" )`
`rejects( promise, expectedMatcher, message = "" )`<br>
`rejectionValue = await rejects( promise, message = "" )`

Test if the provided promise rejects, and optionally compare the rejection value.

Expand All @@ -34,6 +35,10 @@ The `expectedMatcher` argument can be:

Note: in order to avoid confusion between the `message` and the `expectedMatcher`, the `expectedMatcher` **can not** be a string.

`assert.rejects()` returns a promise which is resolved with the rejection value from the provided
promise. This can be used instead of `expectedMatcher` to assert other facts about the expected
failure.

## See also

* Use [`assert.throws()`](./throws.md) for synchronous errors.
Expand Down Expand Up @@ -62,7 +67,7 @@ QUnit.test('example', async function (assert) {
### Example: Matcher argument

```js
QUnit.test('rejects example', function (assert) {
QUnit.test('rejects example', async function (assert) {
// simple check
assert.rejects(Promise.reject('some error'));

Expand Down Expand Up @@ -113,6 +118,13 @@ QUnit.test('rejects example', function (assert) {
return err.toString() === 'some error';
}
);

// custom validation using return value
const err = await assert.rejects(
Promise.reject(new CustomError('some error'))
);
assert.true(err instanceof CustomError);
assert.strictEqual(err.toString(), 'some error');
});
```

Expand Down Expand Up @@ -181,17 +193,12 @@ QUnit.test('BAD example', function (assert) {
});
```

If you want to perform additional assertions after a failure, consider performing these directly in your test function, after `assert.rejects()`:
If you want to perform additional assertions after a failure, consider performing these directly in your test function, after `await assert.rejects()`:

```js
QUnit.test('example', async function (assert) {
const p = feedMe();
await assert.rejects(p, RangeError);

try {
await p;
} catch (e) {
assert.deepEqual(e.somedata, { foo: 'bar' });
}
const e = await assert.rejects(p, RangeError);
assert.deepEqual(e.somedata, { foo: 'bar' });
});
```
14 changes: 13 additions & 1 deletion docs/api/assert/throws.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ version_added: "1.0.0"
---

`throws( blockFn, message = "" )`<br>
`throws( blockFn, expectedMatcher, message = "" )`
`throws( blockFn, expectedMatcher, message = "" )`<br>
`thrownValue = throws( blockFn, message = "" )`

Test if a callback throws an exception, and optionally compare the thrown error.

Expand All @@ -31,6 +32,10 @@ The `expectedMatcher` argument can be:
* A RegExp that matches (or partially matches) the string representation.
* A callback with your own custom validation, that returns `true` or `false`.

`assert.throws()` returns the value which was thrown from the provided
function. This can be used instead of `expectedMatcher` to assert other facts about the expected
failure.

<p class="note" markdown="1">If you need to comply with classic ES3 syntax, such as in early versions of Closure Compiler, you can use `assert.raises()`, which is an alias for `assert.throws()`. It has the same signature and behaviour.</p>

## Changelog
Expand Down Expand Up @@ -110,5 +115,12 @@ QUnit.test('throws example', function (assert) {
return err.toString() === 'some error';
}
);

// custom validation using return value
const err = assert.throws(function () {
throw new CustomError('some error');
});
assert.true(err instanceof CustomError);
assert.strictEqual(err.toString(), 'some error');
});
```
4 changes: 4 additions & 0 deletions src/core/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,8 @@ class Assert {
expected,
message
});

return actual;
}

rejects (promise, expected, message) {
Expand Down Expand Up @@ -355,6 +357,8 @@ class Assert {
message
});
done();

return actual;
}
);
}
Expand Down
60 changes: 43 additions & 17 deletions test/main/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,20 @@ function buildMockPromise (settledValue, shouldFulfill) {

var thenable = {
then: function (fulfilledCallback, rejectedCallback) {
var resolve = function () {};
defer(function () {
return shouldFulfill
resolve(shouldFulfill
? fulfilledCallback.call(thenable, settledValue)
: rejectedCallback.call(thenable, settledValue);
: rejectedCallback.call(thenable, settledValue));
});

// returning another thenable for easy confirmation of return value
return buildMockPromise('final promise', true);
// (very incomplete implementation, this is enough for the one test that needs it)
return {
then: function (fulfilledCallback) {
resolve = fulfilledCallback;
}
};
}
};
return thenable;
Expand Down Expand Up @@ -567,6 +573,18 @@ QUnit.test('throws', function (assert) {
/^Error: Invalid expected value type \(array\) provided to assert\.throws\.$/,
'throws errors when provided an array'
);

// return value tests
var returnValue = assert.throws(
function () {
throw 'my error';
}
);
assert.strictEqual(
returnValue,
'my error',
'throws returns the error value'
);
});

QUnit.test('raises', function (assert) {
Expand All @@ -582,16 +600,6 @@ QUnit.test('rejects', function (assert) {
return this.message;
};

var rejectsReturnValue = assert.rejects(
buildMockPromise('my error')
);

assert.equal(
typeof rejectsReturnValue.then,
'function',
'rejects returns a thennable'
);

assert.rejects(
buildMockPromise('my error'),
"simple string rejection, no 'expected' value given"
Expand Down Expand Up @@ -743,12 +751,30 @@ QUnit.test('rejects', function (assert) {
'rejects errors when provided a string'
);

// should return a thenable
// return value tests
var done = assert.async();
var returnValue = assert.rejects(
buildMockPromise(undefined)
buildMockPromise('my error')
);
assert.strictEqual(typeof returnValue, 'object');
assert.strictEqual(typeof returnValue.then, 'function');
assert.strictEqual(
typeof returnValue.then,
'function',
'rejects returns a thenable'
);
returnValue.then(function (error) {
assert.strictEqual(
error,
'my error',
'returned thenable resolves with the rejection value'
);
done();
}, function () {
assert.ok(
false,
'returned thenable does not reject'
);
done();
});
});

if (typeof window !== 'undefined') {
Expand Down
Loading