Skip to content

Commit

Permalink
assert: support custom errors
Browse files Browse the repository at this point in the history
  • Loading branch information
geek committed Sep 11, 2017
1 parent 61e9ba1 commit f135786
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 18 deletions.
59 changes: 41 additions & 18 deletions doc/api/assert.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ assert.deepEqual(obj1, obj4);

If the values are not equal, an `AssertionError` is thrown with a `message`
property set equal to the value of the `message` parameter. If the `message`
parameter is undefined, a default error message is assigned.
parameter is undefined, a default error message is assigned. If the `message`
parameter is an instance of an `Error` then it will be thrown instead of the
`AssertionError`.

## assert.deepStrictEqual(actual, expected[, message])
<!-- YAML
Expand Down Expand Up @@ -174,7 +176,9 @@ assert.deepStrictEqual(NaN, NaN);

If the values are not equal, an `AssertionError` is thrown with a `message`
property set equal to the value of the `message` parameter. If the `message`
parameter is undefined, a default error message is assigned.
parameter is undefined, a default error message is assigned. If the `message`
parameter is an instance of an `Error` then it will be thrown instead of the
`AssertionError`.

## assert.doesNotThrow(block[, error][, message])
<!-- YAML
Expand Down Expand Up @@ -268,7 +272,9 @@ assert.equal({ a: { b: 1 } }, { a: { b: 1 } });

If the values are not equal, an `AssertionError` is thrown with a `message`
property set equal to the value of the `message` parameter. If the `message`
parameter is undefined, a default error message is assigned.
parameter is undefined, a default error message is assigned. If the `message`
parameter is an instance of an `Error` then it will be thrown instead of the
`AssertionError`.

## assert.fail([message])
## assert.fail(actual, expected[, message[, operator[, stackStartFunction]]])
Expand All @@ -282,13 +288,15 @@ added: v0.1.21
* `stackStartFunction` {function} (default: `assert.fail`)

Throws an `AssertionError`. If `message` is falsy, the error message is set as
the values of `actual` and `expected` separated by the provided `operator`.
If just the two `actual` and `expected` arguments are provided, `operator` will
default to `'!='`. If `message` is provided only it will be used as the error
message, the other arguments will be stored as properties on the thrown object.
If `stackStartFunction` is provided, all stack frames above that function will
be removed from stacktrace (see [`Error.captureStackTrace`]). If no arguments
are given, the default message `Failed` will be used.
the values of `actual` and `expected` separated by the provided `operator`. If
the `message` parameter is an instance of an `Error` then it will be thrown
instead of the `AssertionError`. If just the two `actual` and `expected`
arguments are provided, `operator` will default to `'!='`. If `message` is
provided only it will be used as the error message, the other arguments will be
stored as properties on the thrown object. If `stackStartFunction` is provided,
all stack frames above that function will be removed from stacktrace (see
[`Error.captureStackTrace`]). If no arguments are given, the default message
`Failed` will be used.

```js
const assert = require('assert');
Expand All @@ -301,6 +309,9 @@ assert.fail(1, 2, 'fail');

assert.fail(1, 2, 'whoops', '>');
// AssertionError [ERR_ASSERTION]: whoops

assert.fail(1, 2, new TypeError('need array'));
// TypeError: need array
```

*Note*: Is the last two cases `actual`, `expected`, and `operator` have no
Expand Down Expand Up @@ -412,7 +423,9 @@ assert.notDeepEqual(obj1, obj4);

If the values are deeply equal, an `AssertionError` is thrown with a `message`
property set equal to the value of the `message` parameter. If the `message`
parameter is undefined, a default error message is assigned.
parameter is undefined, a default error message is assigned. If the `message`
parameter is an instance of an `Error` then it will be thrown instead of the
`AssertionError`.

## assert.notDeepStrictEqual(actual, expected[, message])
<!-- YAML
Expand Down Expand Up @@ -453,9 +466,11 @@ assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
// OK
```

If the values are deeply and strictly equal, an `AssertionError` is thrown
with a `message` property set equal to the value of the `message` parameter. If
the `message` parameter is undefined, a default error message is assigned.
If the values are deeply and strictly equal, an `AssertionError` is thrown with
a `message` property set equal to the value of the `message` parameter. If the
`message` parameter is undefined, a default error message is assigned. If the
`message` parameter is an instance of an `Error` then it will be thrown instead
of the `AssertionError`.

## assert.notEqual(actual, expected[, message])
<!-- YAML
Expand Down Expand Up @@ -483,7 +498,9 @@ assert.notEqual(1, '1');

If the values are equal, an `AssertionError` is thrown with a `message`
property set equal to the value of the `message` parameter. If the `message`
parameter is undefined, a default error message is assigned.
parameter is undefined, a default error message is assigned. If the `message`
parameter is an instance of an `Error` then it will be thrown instead of the
`AssertionError`.

## assert.notStrictEqual(actual, expected[, message])
<!-- YAML
Expand Down Expand Up @@ -511,7 +528,9 @@ assert.notStrictEqual(1, '1');

If the values are strictly equal, an `AssertionError` is thrown with a
`message` property set equal to the value of the `message` parameter. If the
`message` parameter is undefined, a default error message is assigned.
`message` parameter is undefined, a default error message is assigned. If the
`message` parameter is an instance of an `Error` then it will be thrown instead
of the `AssertionError`.

## assert.ok(value[, message])
<!-- YAML
Expand All @@ -525,7 +544,9 @@ Tests if `value` is truthy. It is equivalent to

If `value` is not truthy, an `AssertionError` is thrown with a `message`
property set equal to the value of the `message` parameter. If the `message`
parameter is `undefined`, a default error message is assigned.
parameter is `undefined`, a default error message is assigned. If the `message`
parameter is an instance of an `Error` then it will be thrown instead of the
`AssertionError`.

```js
const assert = require('assert');
Expand Down Expand Up @@ -568,7 +589,9 @@ assert.strictEqual(1, '1');

If the values are not strictly equal, an `AssertionError` is thrown with a
`message` property set equal to the value of the `message` parameter. If the
`message` parameter is undefined, a default error message is assigned.
`message` parameter is undefined, a default error message is assigned. If the
`message` parameter is an instance of an `Error` then it will be thrown instead
of the `AssertionError`.

## assert.throws(block[, error][, message])
<!-- YAML
Expand Down
2 changes: 2 additions & 0 deletions lib/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ const assert = module.exports = ok;
// display purposes.

function innerFail(actual, expected, message, operator, stackStartFunction) {
if (message instanceof Error) throw message;

throw new errors.AssertionError({
message,
actual,
Expand Down
22 changes: 22 additions & 0 deletions test/parallel/test-assert-fail.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ common.expectsError(() => {
expected: undefined
});

// One arg = Error
common.expectsError(() => {
assert.fail(new TypeError('custom message'));
}, {
type: TypeError,
message: 'custom message',
operator: undefined,
actual: undefined,
expected: undefined
});

// Two args only, operator defaults to '!='
common.expectsError(() => {
assert.fail('first', 'second');
Expand All @@ -52,6 +63,17 @@ common.expectsError(() => {
expected: 'ignored'
});

// Three args with custom Error
common.expectsError(() => {
assert.fail(typeof 1, 'object', new TypeError('another custom message'));
}, {
type: TypeError,
message: 'another custom message',
operator: undefined,
actual: 'number',
expected: 'object'
});

// No third arg (but a fourth arg)
common.expectsError(() => {
assert.fail('first', 'second', undefined, 'operator');
Expand Down
28 changes: 28 additions & 0 deletions test/parallel/test-assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,34 @@ try {
'Message incorrectly marked as generated');
}

{
let threw = false;
const rangeError = new RangeError('my range');

// verify custom errors
try {
assert.strictEqual(1, 2, rangeError);
} catch (e) {
assert.strictEqual(e, rangeError);
threw = true;
assert.ok(e instanceof RangeError, 'Incorrect error type thrown');
}
assert.ok(threw);
threw = false;

// verify AssertionError is the result from doesNotThrow with custom Error
try {
assert.doesNotThrow(() => {
throw new TypeError('wrong type');
}, TypeError, rangeError);
} catch (e) {
threw = true;
assert.ok(e.message.includes(rangeError.message));
assert.ok(e instanceof assert.AssertionError);
}
assert.ok(threw);
}

{
// Verify that throws() and doesNotThrow() throw on non-function block
function typeName(value) {
Expand Down

0 comments on commit f135786

Please sign in to comment.