doc: improve assert docs
This improves the error example output by reflecting the current state. It also makes sure the examples are up to date in general. `assert.throws` clarified the `ERR_AMBIGUOUS_ARGUMENT` error. PR-URL: https://github.com/nodejs/node/pull/20313 Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
This commit is contained in:
parent
8a0fb137d8
commit
655430179f
@ -102,31 +102,25 @@ It can be accessed using:
|
||||
const assert = require('assert').strict;
|
||||
```
|
||||
|
||||
Example error diff (the `expected`, `actual`, and `Lines skipped` will be on a
|
||||
single row):
|
||||
Example error diff:
|
||||
|
||||
```js
|
||||
const assert = require('assert').strict;
|
||||
|
||||
assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]);
|
||||
```
|
||||
|
||||
```diff
|
||||
AssertionError [ERR_ASSERTION]: Input A expected to deepStrictEqual input B:
|
||||
+ expected
|
||||
- actual
|
||||
... Lines skipped
|
||||
|
||||
[
|
||||
[
|
||||
...
|
||||
2,
|
||||
- 3
|
||||
+ '3'
|
||||
],
|
||||
...
|
||||
5
|
||||
]
|
||||
// AssertionError: Input A expected to strictly deep-equal input B:
|
||||
// + expected - actual ... Lines skipped
|
||||
//
|
||||
// [
|
||||
// [
|
||||
// ...
|
||||
// 2,
|
||||
// - 3
|
||||
// + '3'
|
||||
// ],
|
||||
// ...
|
||||
// 5
|
||||
// ]
|
||||
```
|
||||
|
||||
To deactivate the colors, use the `NODE_DISABLE_COLORS` environment variable.
|
||||
@ -319,9 +313,14 @@ are recursively evaluated also by the following rules.
|
||||
```js
|
||||
const assert = require('assert').strict;
|
||||
|
||||
// This fails because 1 !== '1'.
|
||||
assert.deepStrictEqual({ a: 1 }, { a: '1' });
|
||||
// AssertionError: { a: 1 } deepStrictEqual { a: '1' }
|
||||
// because 1 !== '1' using SameValue comparison
|
||||
// AssertionError: Input A expected to strictly deep-equal input B:
|
||||
// + expected - actual
|
||||
// {
|
||||
// - a: 1
|
||||
// + a: '1'
|
||||
// }
|
||||
|
||||
// The following objects don't have own properties
|
||||
const date = new Date();
|
||||
@ -329,33 +328,52 @@ const object = {};
|
||||
const fakeDate = {};
|
||||
Object.setPrototypeOf(fakeDate, Date.prototype);
|
||||
|
||||
// Different [[Prototype]]:
|
||||
assert.deepStrictEqual(object, fakeDate);
|
||||
// AssertionError: {} deepStrictEqual Date {}
|
||||
// Different [[Prototype]]
|
||||
// AssertionError: Input A expected to strictly deep-equal input B:
|
||||
// + expected - actual
|
||||
// - {}
|
||||
// + Date {}
|
||||
|
||||
// Different type tags:
|
||||
assert.deepStrictEqual(date, fakeDate);
|
||||
// AssertionError: 2017-03-11T14:25:31.849Z deepStrictEqual Date {}
|
||||
// Different type tags
|
||||
// AssertionError: Input A expected to strictly deep-equal input B:
|
||||
// + expected - actual
|
||||
// - 2018-04-26T00:49:08.604Z
|
||||
// + Date {}
|
||||
|
||||
assert.deepStrictEqual(NaN, NaN);
|
||||
// OK, because of the SameValue comparison
|
||||
|
||||
// Different unwrapped numbers:
|
||||
assert.deepStrictEqual(new Number(1), new Number(2));
|
||||
// Fails because the wrapped number is unwrapped and compared as well.
|
||||
// AssertionError: Input A expected to strictly deep-equal input B:
|
||||
// + expected - actual
|
||||
// - [Number: 1]
|
||||
// + [Number: 2]
|
||||
|
||||
assert.deepStrictEqual(new String('foo'), Object('foo'));
|
||||
// OK because the object and the string are identical when unwrapped.
|
||||
|
||||
assert.deepStrictEqual(-0, -0);
|
||||
// OK
|
||||
|
||||
// Different zeros using the SameValue Comparison:
|
||||
assert.deepStrictEqual(0, -0);
|
||||
// AssertionError: 0 deepStrictEqual -0
|
||||
// AssertionError: Input A expected to strictly deep-equal input B:
|
||||
// + expected - actual
|
||||
// - 0
|
||||
// + -0
|
||||
|
||||
const symbol1 = Symbol();
|
||||
const symbol2 = Symbol();
|
||||
assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol1]: 1 });
|
||||
// OK, because it is the same symbol on both objects.
|
||||
assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol2]: 1 });
|
||||
// Fails because symbol1 !== symbol2!
|
||||
// AssertionError [ERR_ASSERTION]: Input objects not identical:
|
||||
// {
|
||||
// [Symbol()]: 1
|
||||
// }
|
||||
|
||||
const weakMap1 = new WeakMap();
|
||||
const weakMap2 = new WeakMap([[{}, {}]]);
|
||||
@ -364,8 +382,16 @@ weakMap3.unequal = true;
|
||||
|
||||
assert.deepStrictEqual(weakMap1, weakMap2);
|
||||
// OK, because it is impossible to compare the entries
|
||||
|
||||
// Fails because weakMap3 has a property that weakMap1 does not contain:
|
||||
assert.deepStrictEqual(weakMap1, weakMap3);
|
||||
// Fails because weakMap3 has a property that weakMap1 does not contain!
|
||||
// AssertionError: Input A expected to strictly deep-equal input B:
|
||||
// + expected - actual
|
||||
// WeakMap {
|
||||
// - [items unknown]
|
||||
// + [items unknown],
|
||||
// + unequal: true
|
||||
// }
|
||||
```
|
||||
|
||||
If the values are not equal, an `AssertionError` is thrown with a `message`
|
||||
@ -639,7 +665,9 @@ changes:
|
||||
* `value` {any}
|
||||
|
||||
Throws `value` if `value` is not `undefined` or `null`. This is useful when
|
||||
testing the `error` argument in callbacks.
|
||||
testing the `error` argument in callbacks. The stack trace contains all frames
|
||||
from the error passed to `ifError()` including the potential new frames for
|
||||
`ifError()` itself. See below for an example.
|
||||
|
||||
```js
|
||||
const assert = require('assert').strict;
|
||||
@ -652,6 +680,19 @@ assert.ifError('error');
|
||||
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 'error'
|
||||
assert.ifError(new Error());
|
||||
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: Error
|
||||
|
||||
// Create some random error frames.
|
||||
let err;
|
||||
(function errorFrame() {
|
||||
err = new Error('test error');
|
||||
})();
|
||||
|
||||
(function ifErrorFrame() {
|
||||
assert.ifError(err);
|
||||
})();
|
||||
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error
|
||||
// at ifErrorFrame
|
||||
// at errorFrame
|
||||
```
|
||||
|
||||
## assert.notDeepEqual(actual, expected[, message])
|
||||
@ -834,7 +875,7 @@ assert.notStrictEqual(1, 2);
|
||||
// OK
|
||||
|
||||
assert.notStrictEqual(1, 1);
|
||||
// AssertionError: 1 notStrictEqual 1
|
||||
// AssertionError [ERR_ASSERTION]: Identical input passed to notStrictEqual: 1
|
||||
|
||||
assert.notStrictEqual(1, '1');
|
||||
// OK
|
||||
@ -880,40 +921,34 @@ assert.ok(1);
|
||||
// OK
|
||||
|
||||
assert.ok();
|
||||
// throws:
|
||||
// "AssertionError: No value argument passed to `assert.ok`.
|
||||
// AssertionError: No value argument passed to `assert.ok()`
|
||||
|
||||
assert.ok(false, 'it\'s false');
|
||||
// throws "AssertionError: it's false"
|
||||
// AssertionError: it's false
|
||||
|
||||
// In the repl:
|
||||
assert.ok(typeof 123 === 'string');
|
||||
// throws:
|
||||
// "AssertionError: false == true
|
||||
// AssertionError: false == true
|
||||
|
||||
// In a file (e.g. test.js):
|
||||
assert.ok(typeof 123 === 'string');
|
||||
// throws:
|
||||
// "AssertionError: The expression evaluated to a falsy value:
|
||||
// AssertionError: The expression evaluated to a falsy value:
|
||||
//
|
||||
// assert.ok(typeof 123 === 'string')
|
||||
|
||||
assert.ok(false);
|
||||
// throws:
|
||||
// "AssertionError: The expression evaluated to a falsy value:
|
||||
// AssertionError: The expression evaluated to a falsy value:
|
||||
//
|
||||
// assert.ok(false)
|
||||
|
||||
assert.ok(0);
|
||||
// throws:
|
||||
// "AssertionError: The expression evaluated to a falsy value:
|
||||
// AssertionError: The expression evaluated to a falsy value:
|
||||
//
|
||||
// assert.ok(0)
|
||||
|
||||
// Using `assert()` works the same:
|
||||
assert(0);
|
||||
// throws:
|
||||
// "AssertionError: The expression evaluated to a falsy value:
|
||||
// AssertionError: The expression evaluated to a falsy value:
|
||||
//
|
||||
// assert(0)
|
||||
```
|
||||
@ -995,13 +1030,19 @@ determined by the [SameValue Comparison][].
|
||||
const assert = require('assert').strict;
|
||||
|
||||
assert.strictEqual(1, 2);
|
||||
// AssertionError: 1 strictEqual 2
|
||||
// AssertionError [ERR_ASSERTION]: Input A expected to strictly equal input B:
|
||||
// + expected - actual
|
||||
// - 1
|
||||
// + 2
|
||||
|
||||
assert.strictEqual(1, 1);
|
||||
// OK
|
||||
|
||||
assert.strictEqual(1, '1');
|
||||
// AssertionError: 1 strictEqual '1'
|
||||
// AssertionError [ERR_ASSERTION]: Input A expected to strictly equal input B:
|
||||
// + expected - actual
|
||||
// - 1
|
||||
// + '1'
|
||||
```
|
||||
|
||||
If the values are not strictly equal, an `AssertionError` is thrown with a
|
||||
@ -1035,6 +1076,34 @@ each property will be tested for including the non-enumerable `message` and
|
||||
If specified, `message` will be the message provided by the `AssertionError` if
|
||||
the block fails to throw.
|
||||
|
||||
Custom error object / error instance:
|
||||
|
||||
```js
|
||||
const err = new TypeError('Wrong value');
|
||||
err.code = 404;
|
||||
|
||||
assert.throws(
|
||||
() => {
|
||||
throw err;
|
||||
},
|
||||
{
|
||||
name: 'TypeError',
|
||||
message: 'Wrong value'
|
||||
// Note that only properties on the error object will be tested!
|
||||
}
|
||||
);
|
||||
|
||||
// Fails due to the different `message` and `name` properties:
|
||||
assert.throws(
|
||||
() => {
|
||||
const otherErr = new Error('Not found');
|
||||
otherErr.code = 404;
|
||||
throw otherErr;
|
||||
},
|
||||
err // This tests for `message`, `name` and `code`.
|
||||
);
|
||||
```
|
||||
|
||||
Validate instanceof using constructor:
|
||||
|
||||
```js
|
||||
@ -1076,39 +1145,12 @@ assert.throws(
|
||||
);
|
||||
```
|
||||
|
||||
Custom error object / error instance:
|
||||
|
||||
```js
|
||||
const err = new TypeError('Wrong value');
|
||||
err.code = 404;
|
||||
|
||||
assert.throws(
|
||||
() => {
|
||||
throw err;
|
||||
},
|
||||
{
|
||||
name: 'TypeError',
|
||||
message: 'Wrong value'
|
||||
// Note that only properties on the error object will be tested!
|
||||
}
|
||||
);
|
||||
|
||||
// Fails due to the different `message` and `name` properties:
|
||||
assert.throws(
|
||||
() => {
|
||||
const otherErr = new Error('Not found');
|
||||
otherErr.code = 404;
|
||||
throw otherErr;
|
||||
},
|
||||
err // This tests for `message`, `name` and `code`.
|
||||
);
|
||||
```
|
||||
|
||||
Note that `error` cannot be a string. If a string is provided as the second
|
||||
argument, then `error` is assumed to be omitted and the string will be used for
|
||||
`message` instead. This can lead to easy-to-miss mistakes. Please read the
|
||||
example below carefully if using a string as the second argument gets
|
||||
considered:
|
||||
`message` instead. This can lead to easy-to-miss mistakes. Using the same
|
||||
message as the thrown error message is going to result in an
|
||||
`ERR_AMBIGUOUS_ARGUMENT` error. Please read the example below carefully if using
|
||||
a string as the second argument gets considered:
|
||||
|
||||
<!-- eslint-disable no-restricted-syntax -->
|
||||
```js
|
||||
@ -1121,10 +1163,15 @@ function throwingSecond() {
|
||||
function notThrowing() {}
|
||||
|
||||
// The second argument is a string and the input function threw an Error.
|
||||
// In that case both cases do not throw as neither is going to try to
|
||||
// match for the error message thrown by the input function!
|
||||
// The first case will not throw as it does not match for the error message
|
||||
// thrown by the input function!
|
||||
assert.throws(throwingFirst, 'Second');
|
||||
// In the next example the message has no benefit over the message from the
|
||||
// error and since it is not clear if the user intended to actually match
|
||||
// against the error message, Node.js thrown an `ERR_AMBIGUOUS_ARGUMENT` error.
|
||||
assert.throws(throwingSecond, 'Second');
|
||||
// Throws an error:
|
||||
// TypeError [ERR_AMBIGUOUS_ARGUMENT]
|
||||
|
||||
// The string is only used (as message) in case the function does not throw:
|
||||
assert.throws(notThrowing, 'Second');
|
||||
@ -1134,7 +1181,7 @@ assert.throws(notThrowing, 'Second');
|
||||
assert.throws(throwingSecond, /Second$/);
|
||||
// Does not throw because the error messages match.
|
||||
assert.throws(throwingFirst, /Second$/);
|
||||
// Throws a error:
|
||||
// Throws an error:
|
||||
// Error: First
|
||||
// at throwingFirst (repl:2:9)
|
||||
```
|
||||
|
Loading…
x
Reference in New Issue
Block a user