Skip to content

Commit 6150aa4

Browse files
committed
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.
1 parent dbd24b1 commit 6150aa4

File tree

2 files changed

+49
-14
lines changed

2 files changed

+49
-14
lines changed

doc/api/assert.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1748,14 +1748,22 @@ argument gets considered.
17481748
<!-- YAML
17491749
added: v0.1.21
17501750
changes:
1751+
- version: REPLACEME
1752+
pr-url: https://github.com/nodejs/node/pull/XXXXX
1753+
description: Message may now be a `printf`-like format string or function.
17511754
- version: v10.0.0
17521755
pr-url: https://github.com/nodejs/node/pull/17003
17531756
description: Used comparison changed from Strict Equality to `Object.is()`.
17541757
-->
17551758

17561759
* `actual` {any}
17571760
* `expected` {any}
1758-
* `message` {string|Error}
1761+
* `message` {string|Error|Function} Postfix `printf`-like arguments in case
1762+
it's used as format string. If a function is used, the function is called. If
1763+
that function call fails, the default message is generated instead.
1764+
`printf`-like format strings and functions are beneficial for performance
1765+
reasons in case arguments are passed through. In addition, it allows nice
1766+
formatting with ease.
17591767

17601768
Tests strict equality between the `actual` and `expected` parameters as
17611769
determined by [`Object.is()`][].
@@ -1784,8 +1792,17 @@ const oranges = 2;
17841792
assert.strictEqual(apples, oranges, `apples ${apples} !== oranges ${oranges}`);
17851793
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2
17861794

1795+
assert.strictEqual(apples, oranges, 'apples %s !== oranges %s', apples, oranges);
1796+
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2
1797+
17871798
assert.strictEqual(1, '1', new TypeError('Inputs are not identical'));
17881799
// TypeError: Inputs are not identical
1800+
1801+
assert.strictEqual(apples, oranges, () => {
1802+
// Do 'heavy' computations
1803+
return 'My error string'
1804+
});
1805+
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2
17891806
```
17901807

17911808
```cjs

lib/assert.js

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const {
4949
},
5050
} = require('internal/errors');
5151
const AssertionError = require('internal/assert/assertion_error');
52-
const { inspect } = require('internal/util/inspect');
52+
const { inspect, format } = require('internal/util/inspect');
5353
const {
5454
isPromise,
5555
isRegExp,
@@ -87,7 +87,25 @@ const NO_EXCEPTION_SENTINEL = {};
8787
// display purposes.
8888

8989
function innerFail(obj) {
90-
if (obj.message instanceof Error) throw obj.message;
90+
if (obj.message.length === 0) {
91+
obj.message = undefined
92+
} else if (typeof obj.message[0] === 'string') {
93+
if (obj.message.length > 1) {
94+
obj.message = format(...obj.message);
95+
} else {
96+
obj.message = obj.message[0];
97+
}
98+
} else if (isError(obj.message[0])) {
99+
throw obj.message[0];
100+
} else if (typeof obj.message[0] === 'function') {
101+
obj.message = obj.message[0]();
102+
} else {
103+
throw new ERR_INVALID_ARG_TYPE(
104+
'message',
105+
['string', 'function'],
106+
obj.message[0],
107+
);
108+
}
91109

92110
throw new AssertionError(obj);
93111
}
@@ -141,7 +159,7 @@ assert.ok = ok;
141159
* @returns {void}
142160
*/
143161
/* eslint-disable no-restricted-properties */
144-
assert.equal = function equal(actual, expected, message) {
162+
assert.equal = function equal(actual, expected, ...message) {
145163
if (arguments.length < 2) {
146164
throw new ERR_MISSING_ARGS('actual', 'expected');
147165
}
@@ -165,7 +183,7 @@ assert.equal = function equal(actual, expected, message) {
165183
* @param {string | Error} [message]
166184
* @returns {void}
167185
*/
168-
assert.notEqual = function notEqual(actual, expected, message) {
186+
assert.notEqual = function notEqual(actual, expected, ...message) {
169187
if (arguments.length < 2) {
170188
throw new ERR_MISSING_ARGS('actual', 'expected');
171189
}
@@ -188,7 +206,7 @@ assert.notEqual = function notEqual(actual, expected, message) {
188206
* @param {string | Error} [message]
189207
* @returns {void}
190208
*/
191-
assert.deepEqual = function deepEqual(actual, expected, message) {
209+
assert.deepEqual = function deepEqual(actual, expected, ...message) {
192210
if (arguments.length < 2) {
193211
throw new ERR_MISSING_ARGS('actual', 'expected');
194212
}
@@ -211,7 +229,7 @@ assert.deepEqual = function deepEqual(actual, expected, message) {
211229
* @param {string | Error} [message]
212230
* @returns {void}
213231
*/
214-
assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
232+
assert.notDeepEqual = function notDeepEqual(actual, expected, ...message) {
215233
if (arguments.length < 2) {
216234
throw new ERR_MISSING_ARGS('actual', 'expected');
217235
}
@@ -236,7 +254,7 @@ assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
236254
* @param {string | Error} [message]
237255
* @returns {void}
238256
*/
239-
assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
257+
assert.deepStrictEqual = function deepStrictEqual(actual, expected, ...message) {
240258
if (arguments.length < 2) {
241259
throw new ERR_MISSING_ARGS('actual', 'expected');
242260
}
@@ -261,7 +279,7 @@ assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
261279
* @returns {void}
262280
*/
263281
assert.notDeepStrictEqual = notDeepStrictEqual;
264-
function notDeepStrictEqual(actual, expected, message) {
282+
function notDeepStrictEqual(actual, expected, ...message) {
265283
if (arguments.length < 2) {
266284
throw new ERR_MISSING_ARGS('actual', 'expected');
267285
}
@@ -284,7 +302,7 @@ function notDeepStrictEqual(actual, expected, message) {
284302
* @param {string | Error} [message]
285303
* @returns {void}
286304
*/
287-
assert.strictEqual = function strictEqual(actual, expected, message) {
305+
assert.strictEqual = function strictEqual(actual, expected, ...message) {
288306
if (arguments.length < 2) {
289307
throw new ERR_MISSING_ARGS('actual', 'expected');
290308
}
@@ -306,7 +324,7 @@ assert.strictEqual = function strictEqual(actual, expected, message) {
306324
* @param {string | Error} [message]
307325
* @returns {void}
308326
*/
309-
assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
327+
assert.notStrictEqual = function notStrictEqual(actual, expected, ...message) {
310328
if (arguments.length < 2) {
311329
throw new ERR_MISSING_ARGS('actual', 'expected');
312330
}
@@ -331,7 +349,7 @@ assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
331349
assert.partialDeepStrictEqual = function partialDeepStrictEqual(
332350
actual,
333351
expected,
334-
message,
352+
...message,
335353
) {
336354
if (arguments.length < 2) {
337355
throw new ERR_MISSING_ARGS('actual', 'expected');
@@ -783,7 +801,7 @@ function internalMatch(string, regexp, message, fn) {
783801
* @param {string | Error} [message]
784802
* @returns {void}
785803
*/
786-
assert.match = function match(string, regexp, message) {
804+
assert.match = function match(string, regexp, ...message) {
787805
internalMatch(string, regexp, message, match);
788806
};
789807

@@ -794,7 +812,7 @@ assert.match = function match(string, regexp, message) {
794812
* @param {string | Error} [message]
795813
* @returns {void}
796814
*/
797-
assert.doesNotMatch = function doesNotMatch(string, regexp, message) {
815+
assert.doesNotMatch = function doesNotMatch(string, regexp, ...message) {
798816
internalMatch(string, regexp, message, doesNotMatch);
799817
};
800818

0 commit comments

Comments
 (0)