Skip to content

Commit f03241f

Browse files
committed
assert: add partial support for evaluated code in simple assert
This makes sure using `assert.ok()` in `new Function()` statements visualizes the actual call site in the error message. PR-URL: #27781 Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent ef8f147 commit f03241f

File tree

2 files changed

+41
-21
lines changed

2 files changed

+41
-21
lines changed

lib/assert.js

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -269,24 +269,31 @@ function getErrMessage(message, fn) {
269269
Error.prepareStackTrace = tmpPrepare;
270270

271271
const filename = call.getFileName();
272-
273-
if (!filename) {
274-
return message;
275-
}
276-
277272
const line = call.getLineNumber() - 1;
278273
let column = call.getColumnNumber() - 1;
274+
let identifier;
275+
let code;
279276

280-
const identifier = `${filename}${line}${column}`;
277+
if (filename) {
278+
identifier = `${filename}${line}${column}`;
281279

282-
if (errorCache.has(identifier)) {
283-
return errorCache.get(identifier);
280+
// Skip Node.js modules!
281+
if (filename.endsWith('.js') &&
282+
NativeModule.exists(filename.slice(0, -3))) {
283+
errorCache.set(identifier, undefined);
284+
return;
285+
}
286+
} else {
287+
const fn = call.getFunction();
288+
if (!fn) {
289+
return message;
290+
}
291+
code = String(fn);
292+
identifier = `${code}${line}${column}`;
284293
}
285294

286-
// Skip Node.js modules!
287-
if (filename.endsWith('.js') && NativeModule.exists(filename.slice(0, -3))) {
288-
errorCache.set(identifier, undefined);
289-
return;
295+
if (errorCache.has(identifier)) {
296+
return errorCache.get(identifier);
290297
}
291298

292299
let fd;
@@ -295,16 +302,22 @@ function getErrMessage(message, fn) {
295302
// errors are handled faster.
296303
Error.stackTraceLimit = 0;
297304

298-
if (decoder === undefined) {
299-
const { StringDecoder } = require('string_decoder');
300-
decoder = new StringDecoder('utf8');
305+
if (filename) {
306+
if (decoder === undefined) {
307+
const { StringDecoder } = require('string_decoder');
308+
decoder = new StringDecoder('utf8');
309+
}
310+
fd = openSync(filename, 'r', 0o666);
311+
// Reset column and message.
312+
[column, message] = getCode(fd, line, column);
313+
// Flush unfinished multi byte characters.
314+
decoder.end();
315+
} else {
316+
for (let i = 0; i < line; i++) {
317+
code = code.slice(code.indexOf('\n') + 1);
318+
}
319+
[column, message] = parseCode(code, column);
301320
}
302-
303-
fd = openSync(filename, 'r', 0o666);
304-
// Reset column and message.
305-
[column, message] = getCode(fd, line, column);
306-
// Flush unfinished multi byte characters.
307-
decoder.end();
308321
// Always normalize indentation, otherwise the message could look weird.
309322
if (message.includes('\n')) {
310323
if (EOL === '\r\n') {

test/parallel/test-assert.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,13 @@ common.expectsError(
858858
{
859859
code: 'ERR_ASSERTION',
860860
type: assert.AssertionError,
861+
message: 'The expression evaluated to a falsy value:\n\n assert(1 === 2)\n'
862+
}
863+
);
864+
assert.throws(
865+
() => eval('console.log("FOO");\nassert.ok(1 === 2);'),
866+
{
867+
code: 'ERR_ASSERTION',
861868
message: 'false == true'
862869
}
863870
);

0 commit comments

Comments
 (0)