Skip to content

Commit 90026c3

Browse files
BridgeARMylesBorins
authored andcommitted
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: #20313 Reviewed-By: Vse Mozhet Byt <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]>
1 parent 7293c58 commit 90026c3

File tree

1 file changed

+128
-81
lines changed

1 file changed

+128
-81
lines changed

doc/api/assert.md

+128-81
Original file line numberDiff line numberDiff line change
@@ -102,31 +102,25 @@ It can be accessed using:
102102
const assert = require('assert').strict;
103103
```
104104

105-
Example error diff (the `expected`, `actual`, and `Lines skipped` will be on a
106-
single row):
105+
Example error diff:
107106

108107
```js
109108
const assert = require('assert').strict;
110109

111110
assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]);
112-
```
113-
114-
```diff
115-
AssertionError [ERR_ASSERTION]: Input A expected to deepStrictEqual input B:
116-
+ expected
117-
- actual
118-
... Lines skipped
119-
120-
[
121-
[
122-
...
123-
2,
124-
- 3
125-
+ '3'
126-
],
127-
...
128-
5
129-
]
111+
// AssertionError: Input A expected to strictly deep-equal input B:
112+
// + expected - actual ... Lines skipped
113+
//
114+
// [
115+
// [
116+
// ...
117+
// 2,
118+
// - 3
119+
// + '3'
120+
// ],
121+
// ...
122+
// 5
123+
// ]
130124
```
131125

132126
To deactivate the colors, use the `NODE_DISABLE_COLORS` environment variable.
@@ -319,43 +313,67 @@ are recursively evaluated also by the following rules.
319313
```js
320314
const assert = require('assert').strict;
321315

316+
// This fails because 1 !== '1'.
322317
assert.deepStrictEqual({ a: 1 }, { a: '1' });
323-
// AssertionError: { a: 1 } deepStrictEqual { a: '1' }
324-
// because 1 !== '1' using SameValue comparison
318+
// AssertionError: Input A expected to strictly deep-equal input B:
319+
// + expected - actual
320+
// {
321+
// - a: 1
322+
// + a: '1'
323+
// }
325324

326325
// The following objects don't have own properties
327326
const date = new Date();
328327
const object = {};
329328
const fakeDate = {};
330329
Object.setPrototypeOf(fakeDate, Date.prototype);
331330

331+
// Different [[Prototype]]:
332332
assert.deepStrictEqual(object, fakeDate);
333-
// AssertionError: {} deepStrictEqual Date {}
334-
// Different [[Prototype]]
333+
// AssertionError: Input A expected to strictly deep-equal input B:
334+
// + expected - actual
335+
// - {}
336+
// + Date {}
335337

338+
// Different type tags:
336339
assert.deepStrictEqual(date, fakeDate);
337-
// AssertionError: 2017-03-11T14:25:31.849Z deepStrictEqual Date {}
338-
// Different type tags
340+
// AssertionError: Input A expected to strictly deep-equal input B:
341+
// + expected - actual
342+
// - 2018-04-26T00:49:08.604Z
343+
// + Date {}
339344

340345
assert.deepStrictEqual(NaN, NaN);
341346
// OK, because of the SameValue comparison
342347

348+
// Different unwrapped numbers:
343349
assert.deepStrictEqual(new Number(1), new Number(2));
344-
// Fails because the wrapped number is unwrapped and compared as well.
350+
// AssertionError: Input A expected to strictly deep-equal input B:
351+
// + expected - actual
352+
// - [Number: 1]
353+
// + [Number: 2]
354+
345355
assert.deepStrictEqual(new String('foo'), Object('foo'));
346356
// OK because the object and the string are identical when unwrapped.
347357

348358
assert.deepStrictEqual(-0, -0);
349359
// OK
360+
361+
// Different zeros using the SameValue Comparison:
350362
assert.deepStrictEqual(0, -0);
351-
// AssertionError: 0 deepStrictEqual -0
363+
// AssertionError: Input A expected to strictly deep-equal input B:
364+
// + expected - actual
365+
// - 0
366+
// + -0
352367

353368
const symbol1 = Symbol();
354369
const symbol2 = Symbol();
355370
assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol1]: 1 });
356371
// OK, because it is the same symbol on both objects.
357372
assert.deepStrictEqual({ [symbol1]: 1 }, { [symbol2]: 1 });
358-
// Fails because symbol1 !== symbol2!
373+
// AssertionError [ERR_ASSERTION]: Input objects not identical:
374+
// {
375+
// [Symbol()]: 1
376+
// }
359377

360378
const weakMap1 = new WeakMap();
361379
const weakMap2 = new WeakMap([[{}, {}]]);
@@ -364,8 +382,16 @@ weakMap3.unequal = true;
364382

365383
assert.deepStrictEqual(weakMap1, weakMap2);
366384
// OK, because it is impossible to compare the entries
385+
386+
// Fails because weakMap3 has a property that weakMap1 does not contain:
367387
assert.deepStrictEqual(weakMap1, weakMap3);
368-
// Fails because weakMap3 has a property that weakMap1 does not contain!
388+
// AssertionError: Input A expected to strictly deep-equal input B:
389+
// + expected - actual
390+
// WeakMap {
391+
// - [items unknown]
392+
// + [items unknown],
393+
// + unequal: true
394+
// }
369395
```
370396

371397
If the values are not equal, an `AssertionError` is thrown with a `message`
@@ -639,7 +665,9 @@ changes:
639665
* `value` {any}
640666

641667
Throws `value` if `value` is not `undefined` or `null`. This is useful when
642-
testing the `error` argument in callbacks.
668+
testing the `error` argument in callbacks. The stack trace contains all frames
669+
from the error passed to `ifError()` including the potential new frames for
670+
`ifError()` itself. See below for an example.
643671

644672
```js
645673
const assert = require('assert').strict;
@@ -652,6 +680,19 @@ assert.ifError('error');
652680
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: 'error'
653681
assert.ifError(new Error());
654682
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: Error
683+
684+
// Create some random error frames.
685+
let err;
686+
(function errorFrame() {
687+
err = new Error('test error');
688+
})();
689+
690+
(function ifErrorFrame() {
691+
assert.ifError(err);
692+
})();
693+
// AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error
694+
// at ifErrorFrame
695+
// at errorFrame
655696
```
656697

657698
## assert.notDeepEqual(actual, expected[, message])
@@ -834,7 +875,7 @@ assert.notStrictEqual(1, 2);
834875
// OK
835876

836877
assert.notStrictEqual(1, 1);
837-
// AssertionError: 1 notStrictEqual 1
878+
// AssertionError [ERR_ASSERTION]: Identical input passed to notStrictEqual: 1
838879

839880
assert.notStrictEqual(1, '1');
840881
// OK
@@ -880,40 +921,34 @@ assert.ok(1);
880921
// OK
881922

882923
assert.ok();
883-
// throws:
884-
// "AssertionError: No value argument passed to `assert.ok`.
924+
// AssertionError: No value argument passed to `assert.ok()`
885925

886926
assert.ok(false, 'it\'s false');
887-
// throws "AssertionError: it's false"
927+
// AssertionError: it's false
888928

889929
// In the repl:
890930
assert.ok(typeof 123 === 'string');
891-
// throws:
892-
// "AssertionError: false == true
931+
// AssertionError: false == true
893932

894933
// In a file (e.g. test.js):
895934
assert.ok(typeof 123 === 'string');
896-
// throws:
897-
// "AssertionError: The expression evaluated to a falsy value:
935+
// AssertionError: The expression evaluated to a falsy value:
898936
//
899937
// assert.ok(typeof 123 === 'string')
900938

901939
assert.ok(false);
902-
// throws:
903-
// "AssertionError: The expression evaluated to a falsy value:
940+
// AssertionError: The expression evaluated to a falsy value:
904941
//
905942
// assert.ok(false)
906943

907944
assert.ok(0);
908-
// throws:
909-
// "AssertionError: The expression evaluated to a falsy value:
945+
// AssertionError: The expression evaluated to a falsy value:
910946
//
911947
// assert.ok(0)
912948

913949
// Using `assert()` works the same:
914950
assert(0);
915-
// throws:
916-
// "AssertionError: The expression evaluated to a falsy value:
951+
// AssertionError: The expression evaluated to a falsy value:
917952
//
918953
// assert(0)
919954
```
@@ -995,13 +1030,19 @@ determined by the [SameValue Comparison][].
9951030
const assert = require('assert').strict;
9961031

9971032
assert.strictEqual(1, 2);
998-
// AssertionError: 1 strictEqual 2
1033+
// AssertionError [ERR_ASSERTION]: Input A expected to strictly equal input B:
1034+
// + expected - actual
1035+
// - 1
1036+
// + 2
9991037

10001038
assert.strictEqual(1, 1);
10011039
// OK
10021040

10031041
assert.strictEqual(1, '1');
1004-
// AssertionError: 1 strictEqual '1'
1042+
// AssertionError [ERR_ASSERTION]: Input A expected to strictly equal input B:
1043+
// + expected - actual
1044+
// - 1
1045+
// + '1'
10051046
```
10061047

10071048
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
10351076
If specified, `message` will be the message provided by the `AssertionError` if
10361077
the block fails to throw.
10371078

1079+
Custom error object / error instance:
1080+
1081+
```js
1082+
const err = new TypeError('Wrong value');
1083+
err.code = 404;
1084+
1085+
assert.throws(
1086+
() => {
1087+
throw err;
1088+
},
1089+
{
1090+
name: 'TypeError',
1091+
message: 'Wrong value'
1092+
// Note that only properties on the error object will be tested!
1093+
}
1094+
);
1095+
1096+
// Fails due to the different `message` and `name` properties:
1097+
assert.throws(
1098+
() => {
1099+
const otherErr = new Error('Not found');
1100+
otherErr.code = 404;
1101+
throw otherErr;
1102+
},
1103+
err // This tests for `message`, `name` and `code`.
1104+
);
1105+
```
1106+
10381107
Validate instanceof using constructor:
10391108

10401109
```js
@@ -1076,39 +1145,12 @@ assert.throws(
10761145
);
10771146
```
10781147

1079-
Custom error object / error instance:
1080-
1081-
```js
1082-
const err = new TypeError('Wrong value');
1083-
err.code = 404;
1084-
1085-
assert.throws(
1086-
() => {
1087-
throw err;
1088-
},
1089-
{
1090-
name: 'TypeError',
1091-
message: 'Wrong value'
1092-
// Note that only properties on the error object will be tested!
1093-
}
1094-
);
1095-
1096-
// Fails due to the different `message` and `name` properties:
1097-
assert.throws(
1098-
() => {
1099-
const otherErr = new Error('Not found');
1100-
otherErr.code = 404;
1101-
throw otherErr;
1102-
},
1103-
err // This tests for `message`, `name` and `code`.
1104-
);
1105-
```
1106-
11071148
Note that `error` cannot be a string. If a string is provided as the second
11081149
argument, then `error` is assumed to be omitted and the string will be used for
1109-
`message` instead. This can lead to easy-to-miss mistakes. Please read the
1110-
example below carefully if using a string as the second argument gets
1111-
considered:
1150+
`message` instead. This can lead to easy-to-miss mistakes. Using the same
1151+
message as the thrown error message is going to result in an
1152+
`ERR_AMBIGUOUS_ARGUMENT` error. Please read the example below carefully if using
1153+
a string as the second argument gets considered:
11121154

11131155
<!-- eslint-disable no-restricted-syntax -->
11141156
```js
@@ -1121,10 +1163,15 @@ function throwingSecond() {
11211163
function notThrowing() {}
11221164

11231165
// The second argument is a string and the input function threw an Error.
1124-
// In that case both cases do not throw as neither is going to try to
1125-
// match for the error message thrown by the input function!
1166+
// The first case will not throw as it does not match for the error message
1167+
// thrown by the input function!
11261168
assert.throws(throwingFirst, 'Second');
1169+
// In the next example the message has no benefit over the message from the
1170+
// error and since it is not clear if the user intended to actually match
1171+
// against the error message, Node.js thrown an `ERR_AMBIGUOUS_ARGUMENT` error.
11271172
assert.throws(throwingSecond, 'Second');
1173+
// Throws an error:
1174+
// TypeError [ERR_AMBIGUOUS_ARGUMENT]
11281175

11291176
// The string is only used (as message) in case the function does not throw:
11301177
assert.throws(notThrowing, 'Second');
@@ -1134,7 +1181,7 @@ assert.throws(notThrowing, 'Second');
11341181
assert.throws(throwingSecond, /Second$/);
11351182
// Does not throw because the error messages match.
11361183
assert.throws(throwingFirst, /Second$/);
1137-
// Throws a error:
1184+
// Throws an error:
11381185
// Error: First
11391186
// at throwingFirst (repl:2:9)
11401187
```

0 commit comments

Comments
 (0)