From 1a0fd6027759296e66b691f9c4e841c69b8eb995 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Mon, 20 May 2019 12:56:21 +0200 Subject: 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: https://github.com/nodejs/node/pull/27781 Reviewed-By: Rich Trott --- lib/assert.js | 55 +++++++++++++++++++++++++++----------------- test/parallel/test-assert.js | 7 ++++++ 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/lib/assert.js b/lib/assert.js index fadc3ad530..855f844332 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -269,24 +269,31 @@ function getErrMessage(message, fn) { Error.prepareStackTrace = tmpPrepare; const filename = call.getFileName(); - - if (!filename) { - return message; - } - const line = call.getLineNumber() - 1; let column = call.getColumnNumber() - 1; + let identifier; + let code; - const identifier = `${filename}${line}${column}`; + if (filename) { + identifier = `${filename}${line}${column}`; - if (errorCache.has(identifier)) { - return errorCache.get(identifier); + // Skip Node.js modules! + if (filename.endsWith('.js') && + NativeModule.exists(filename.slice(0, -3))) { + errorCache.set(identifier, undefined); + return; + } + } else { + const fn = call.getFunction(); + if (!fn) { + return message; + } + code = String(fn); + identifier = `${code}${line}${column}`; } - // Skip Node.js modules! - if (filename.endsWith('.js') && NativeModule.exists(filename.slice(0, -3))) { - errorCache.set(identifier, undefined); - return; + if (errorCache.has(identifier)) { + return errorCache.get(identifier); } let fd; @@ -295,16 +302,22 @@ function getErrMessage(message, fn) { // errors are handled faster. Error.stackTraceLimit = 0; - if (decoder === undefined) { - const { StringDecoder } = require('string_decoder'); - decoder = new StringDecoder('utf8'); + if (filename) { + if (decoder === undefined) { + const { StringDecoder } = require('string_decoder'); + decoder = new StringDecoder('utf8'); + } + fd = openSync(filename, 'r', 0o666); + // Reset column and message. + [column, message] = getCode(fd, line, column); + // Flush unfinished multi byte characters. + decoder.end(); + } else { + for (let i = 0; i < line; i++) { + code = code.slice(code.indexOf('\n') + 1); + } + [column, message] = parseCode(code, column); } - - fd = openSync(filename, 'r', 0o666); - // Reset column and message. - [column, message] = getCode(fd, line, column); - // Flush unfinished multi byte characters. - decoder.end(); // Always normalize indentation, otherwise the message could look weird. if (message.includes('\n')) { if (EOL === '\r\n') { diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index af2b683bfa..b07b462387 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -859,6 +859,13 @@ common.expectsError( { code: 'ERR_ASSERTION', type: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n assert(1 === 2)\n' + } +); +assert.throws( + () => eval('console.log("FOO");\nassert.ok(1 === 2);'), + { + code: 'ERR_ASSERTION', message: 'false == true' } ); -- cgit v1.2.3