Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit d3f79aa

Browse filesBrowse files
authored
assert: allow printf-style messages as assertion error
Also add functions as allowed message input. This allows to have leavy message computation to become cheaper. PR-URL: #58849 Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
1 parent 8096aea commit d3f79aa
Copy full SHA for d3f79aa

6 files changed

+433-77Lines changed: 433 additions & 77 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎doc/api/assert.md‎

Copy file name to clipboardExpand all lines: doc/api/assert.md
+97-13Lines changed: 97 additions & 13 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,27 @@ strict methods. For example, [`assert.deepEqual()`][] will behave like
3939
In strict assertion mode, error messages for objects display a diff. In legacy
4040
assertion mode, error messages for objects display the objects, often truncated.
4141

42+
### Message parameter semantics
43+
44+
For assertion methods that accept an optional `message` parameter, the message
45+
may be provided in one of the following forms:
46+
47+
* **string**: Used as-is. If additional arguments are supplied after the
48+
`message` string, they are treated as printf-like substitutions (see
49+
[`util.format()`][]).
50+
* **Error**: If an `Error` instance is provided as `message`, that error is
51+
thrown directly instead of an `AssertionError`.
52+
* **function**: A function of the form `(actual, expected) => string`. It is
53+
called only when the assertion fails and should return a string to be used as
54+
the error message. Non-string return values are ignored and the default
55+
message is used instead.
56+
57+
If additional arguments are passed along with an `Error` or a function as
58+
`message`, the call is rejected with `ERR_AMBIGUOUS_ARGUMENT`.
59+
60+
If the first item is neither a string, `Error`, nor function, `ERR_INVALID_ARG_TYPE`
61+
is thrown.
62+
4263
To use strict assertion mode:
4364

4465
```mjs
@@ -305,10 +326,14 @@ destructuring and call methods directly on the instance.
305326

306327
<!-- YAML
307328
added: v0.5.9
329+
changes:
330+
- version: REPLACEME
331+
pr-url: https://github.com/nodejs/node/pull/58849
332+
description: Message may now be a `printf`-like format string or function.
308333
-->
309334

310335
* `value` {any} The input that is checked for being truthy.
311-
* `message` {string|Error}
336+
* `message` {string|Error|Function}
312337

313338
An alias of [`assert.ok()`][].
314339

@@ -324,6 +349,9 @@ changes:
324349
- version: v25.0.0
325350
pr-url: https://github.com/nodejs/node/pull/57627
326351
description: Invalid dates are now considered equal.
352+
- version: REPLACEME
353+
pr-url: https://github.com/nodejs/node/pull/58849
354+
description: Message may now be a `printf`-like format string or function.
327355
- version: v24.0.0
328356
pr-url: https://github.com/nodejs/node/pull/57622
329357
description: Recursion now stops when either side encounters a circular
@@ -375,7 +403,7 @@ changes:
375403

376404
* `actual` {any}
377405
* `expected` {any}
378-
* `message` {string|Error}
406+
* `message` {string|Error|Function}
379407

380408
**Strict assertion mode**
381409

@@ -524,6 +552,9 @@ changes:
524552
- version: v25.0.0
525553
pr-url: https://github.com/nodejs/node/pull/57627
526554
description: Invalid dates are now considered equal.
555+
- version: REPLACEME
556+
pr-url: https://github.com/nodejs/node/pull/58849
557+
description: Message may now be a `printf`-like format string or function.
527558
- version: v24.0.0
528559
pr-url: https://github.com/nodejs/node/pull/57622
529560
description: Recursion now stops when either side encounters a circular
@@ -567,7 +598,7 @@ changes:
567598

568599
* `actual` {any}
569600
* `expected` {any}
570-
* `message` {string|Error}
601+
* `message` {string|Error|Function}
571602

572603
Tests for deep equality between the `actual` and `expected` parameters.
573604
"Deep" equality means that the enumerable "own" properties of child objects
@@ -829,14 +860,17 @@ added:
829860
- v13.6.0
830861
- v12.16.0
831862
changes:
863+
- version: REPLACEME
864+
pr-url: https://github.com/nodejs/node/pull/58849
865+
description: Message may now be a `printf`-like format string or function.
832866
- version: v16.0.0
833867
pr-url: https://github.com/nodejs/node/pull/38111
834868
description: This API is no longer experimental.
835869
-->
836870

837871
* `string` {string}
838872
* `regexp` {RegExp}
839-
* `message` {string|Error}
873+
* `message` {string|Error|Function}
840874

841875
Expects the `string` input not to match the regular expression.
842876

@@ -1069,6 +1103,9 @@ assert.doesNotThrow(
10691103
<!-- YAML
10701104
added: v0.1.21
10711105
changes:
1106+
- version: REPLACEME
1107+
pr-url: https://github.com/nodejs/node/pull/58849
1108+
description: Message may now be a `printf`-like format string or function.
10721109
- version:
10731110
- v16.0.0
10741111
- v14.18.0
@@ -1083,7 +1120,7 @@ changes:
10831120

10841121
* `actual` {any}
10851122
* `expected` {any}
1086-
* `message` {string|Error}
1123+
* `message` {string|Error|Function}
10871124

10881125
**Strict assertion mode**
10891126

@@ -1254,14 +1291,17 @@ added:
12541291
- v13.6.0
12551292
- v12.16.0
12561293
changes:
1294+
- version: REPLACEME
1295+
pr-url: https://github.com/nodejs/node/pull/58849
1296+
description: Message may now be a `printf`-like format string or function.
12571297
- version: v16.0.0
12581298
pr-url: https://github.com/nodejs/node/pull/38111
12591299
description: This API is no longer experimental.
12601300
-->
12611301

12621302
* `string` {string}
12631303
* `regexp` {RegExp}
1264-
* `message` {string|Error}
1304+
* `message` {string|Error|Function}
12651305

12661306
Expects the `string` input to match the regular expression.
12671307

@@ -1303,6 +1343,9 @@ instance of {Error} then it will be thrown instead of the
13031343
<!-- YAML
13041344
added: v0.1.21
13051345
changes:
1346+
- version: REPLACEME
1347+
pr-url: https://github.com/nodejs/node/pull/58849
1348+
description: Message may now be a `printf`-like format string or function.
13061349
- version:
13071350
- v16.0.0
13081351
- v14.18.0
@@ -1338,7 +1381,7 @@ changes:
13381381

13391382
* `actual` {any}
13401383
* `expected` {any}
1341-
* `message` {string|Error}
1384+
* `message` {string|Error|Function}
13421385

13431386
**Strict assertion mode**
13441387

@@ -1427,6 +1470,9 @@ instead of the `AssertionError`.
14271470
<!-- YAML
14281471
added: v1.2.0
14291472
changes:
1473+
- version: REPLACEME
1474+
pr-url: https://github.com/nodejs/node/pull/58849
1475+
description: Message may now be a `printf`-like format string or function.
14301476
- version: v9.0.0
14311477
pr-url: https://github.com/nodejs/node/pull/15398
14321478
description: The `-0` and `+0` are not considered equal anymore.
@@ -1458,7 +1504,7 @@ changes:
14581504

14591505
* `actual` {any}
14601506
* `expected` {any}
1461-
* `message` {string|Error}
1507+
* `message` {string|Error|Function}
14621508

14631509
Tests for deep strict inequality. Opposite of [`assert.deepStrictEqual()`][].
14641510

@@ -1487,6 +1533,9 @@ instead of the [`AssertionError`][].
14871533
<!-- YAML
14881534
added: v0.1.21
14891535
changes:
1536+
- version: REPLACEME
1537+
pr-url: https://github.com/nodejs/node/pull/58849
1538+
description: Message may now be a `printf`-like format string or function.
14901539
- version:
14911540
- v16.0.0
14921541
- v14.18.0
@@ -1501,7 +1550,7 @@ changes:
15011550

15021551
* `actual` {any}
15031552
* `expected` {any}
1504-
* `message` {string|Error}
1553+
* `message` {string|Error|Function}
15051554

15061555
**Strict assertion mode**
15071556

@@ -1551,14 +1600,17 @@ parameter is an instance of {Error} then it will be thrown instead of the
15511600
<!-- YAML
15521601
added: v0.1.21
15531602
changes:
1603+
- version: REPLACEME
1604+
pr-url: https://github.com/nodejs/node/pull/58849
1605+
description: Message may now be a `printf`-like format string or function.
15541606
- version: v10.0.0
15551607
pr-url: https://github.com/nodejs/node/pull/17003
15561608
description: Used comparison changed from Strict Equality to `Object.is()`.
15571609
-->
15581610

15591611
* `actual` {any}
15601612
* `expected` {any}
1561-
* `message` {string|Error}
1613+
* `message` {string|Error|Function}
15621614

15631615
Tests strict inequality between the `actual` and `expected` parameters as
15641616
determined by [`Object.is()`][].
@@ -1604,14 +1656,17 @@ instead of the `AssertionError`.
16041656
<!-- YAML
16051657
added: v0.1.21
16061658
changes:
1659+
- version: REPLACEME
1660+
pr-url: https://github.com/nodejs/node/pull/58849
1661+
description: Message may now be a `printf`-like format string or function.
16071662
- version: v10.0.0
16081663
pr-url: https://github.com/nodejs/node/pull/18319
16091664
description: The `assert.ok()` (no arguments) will now use a predefined
16101665
error message.
16111666
-->
16121667

16131668
* `value` {any}
1614-
* `message` {string|Error}
1669+
* `message` {string|Error|Function}
16151670

16161671
Tests if `value` is truthy. It is equivalent to
16171672
`assert.equal(!!value, true, message)`.
@@ -1844,14 +1899,24 @@ argument gets considered.
18441899
<!-- YAML
18451900
added: v0.1.21
18461901
changes:
1902+
- version: REPLACEME
1903+
pr-url: https://github.com/nodejs/node/pull/58849
1904+
description: Message may now be a `printf`-like format string or function.
18471905
- version: v10.0.0
18481906
pr-url: https://github.com/nodejs/node/pull/17003
18491907
description: Used comparison changed from Strict Equality to `Object.is()`.
18501908
-->
18511909

18521910
* `actual` {any}
18531911
* `expected` {any}
1854-
* `message` {string|Error}
1912+
* `message` {string|Error|Function} Postfix `printf`-like arguments in case
1913+
it's used as format string.
1914+
If message is a function, it is called in case of a comparison failure. The
1915+
function receives the `actual` and `expected` arguments and has to return a
1916+
string that is going to be used as error message.
1917+
`printf`-like format strings and functions are beneficial for performance
1918+
reasons in case arguments are passed through. In addition, it allows nice
1919+
formatting with ease.
18551920

18561921
Tests strict equality between the `actual` and `expected` parameters as
18571922
determined by [`Object.is()`][].
@@ -1880,8 +1945,17 @@ const oranges = 2;
18801945
assert.strictEqual(apples, oranges, `apples ${apples} !== oranges ${oranges}`);
18811946
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2
18821947

1948+
assert.strictEqual(apples, oranges, 'apples %s !== oranges %s', apples, oranges);
1949+
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2
1950+
18831951
assert.strictEqual(1, '1', new TypeError('Inputs are not identical'));
18841952
// TypeError: Inputs are not identical
1953+
1954+
assert.strictEqual(apples, oranges, (actual, expected) => {
1955+
// Do 'heavy' computations
1956+
return `I expected ${expected} but I got ${actual}`;
1957+
});
1958+
// AssertionError [ERR_ASSERTION]: I expected oranges but I got apples
18851959
```
18861960

18871961
```cjs
@@ -1908,8 +1982,17 @@ const oranges = 2;
19081982
assert.strictEqual(apples, oranges, `apples ${apples} !== oranges ${oranges}`);
19091983
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2
19101984

1985+
assert.strictEqual(apples, oranges, 'apples %s !== oranges %s', apples, oranges);
1986+
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2
1987+
19111988
assert.strictEqual(1, '1', new TypeError('Inputs are not identical'));
19121989
// TypeError: Inputs are not identical
1990+
1991+
assert.strictEqual(apples, oranges, (actual, expected) => {
1992+
// Do 'heavy' computations
1993+
return `I expected ${expected} but I got ${actual}`;
1994+
});
1995+
// AssertionError [ERR_ASSERTION]: I expected oranges but I got apples
19131996
```
19141997

19151998
If the values are not strictly equal, an [`AssertionError`][] is thrown with a
@@ -2295,7 +2378,7 @@ changes:
22952378

22962379
* `actual` {any}
22972380
* `expected` {any}
2298-
* `message` {string|Error}
2381+
* `message` {string|Error|Function}
22992382

23002383
Tests for partial deep equality between the `actual` and `expected` parameters.
23012384
"Deep" equality means that the enumerable "own" properties of child objects
@@ -2460,5 +2543,6 @@ assert.partialDeepStrictEqual(
24602543
[`assert.strictEqual()`]: #assertstrictequalactual-expected-message
24612544
[`assert.throws()`]: #assertthrowsfn-error-message
24622545
[`getColorDepth()`]: tty.md#writestreamgetcolordepthenv
2546+
[`util.format()`]: util.md#utilformatformat-args
24632547
[enumerable "own" properties]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties
24642548
[prototype-spec]: https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.