From 87fa636953b6de250c28b1ffb59d5d2195f54a83 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Thu, 19 Nov 2020 23:28:20 +0100 Subject: [PATCH] assert: refactor to use more primordials PR-URL: https://github.com/nodejs/node/pull/36234 Reviewed-By: Rich Trott Reviewed-By: James M Snell --- lib/assert.js | 60 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/lib/assert.js b/lib/assert.js index 48daa56a29c4bd..9a62b38b57efb9 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -21,16 +21,29 @@ 'use strict'; const { + ArrayPrototypeIndexOf, + ArrayPrototypeJoin, + ArrayPrototypePush, + ArrayPrototypeShift, + ArrayPrototypeSlice, Error, ErrorCaptureStackTrace, + FunctionPrototypeBind, + NumberIsNaN, ObjectAssign, ObjectIs, ObjectKeys, ObjectPrototypeIsPrototypeOf, - Map, - NumberIsNaN, + ReflectApply, RegExpPrototypeTest, + SafeMap, String, + StringPrototypeCharCodeAt, + StringPrototypeIncludes, + StringPrototypeIndexOf, + StringPrototypeReplace, + StringPrototypeSlice, + StringPrototypeSplit, } = primordials; const { Buffer } = require('buffer'); @@ -52,7 +65,7 @@ const { EOL } = require('internal/constants'); const { NativeModule } = require('internal/bootstrap/loaders'); const { isError } = require('internal/util'); -const errorCache = new Map(); +const errorCache = new SafeMap(); const CallTracker = require('internal/assert/calltracker'); let isDeepEqual; @@ -81,7 +94,7 @@ const meta = [ '\\u001e', '\\u001f' ]; -const escapeFn = (str) => meta[str.charCodeAt(0)]; +const escapeFn = (str) => meta[StringPrototypeCharCodeAt(str, 0)]; let warned = false; @@ -240,7 +253,7 @@ function parseCode(code, offset) { classFields, staticClassFeatures ); - parseExpressionAt = Parser.parseExpressionAt.bind(Parser); + parseExpressionAt = FunctionPrototypeBind(Parser.parseExpressionAt, Parser); } let node; let start = 0; @@ -265,8 +278,9 @@ function parseCode(code, offset) { return [ node.node.start, - code.slice(node.node.start, node.node.end) - .replace(escapeSequencesRegExp, escapeFn) + StringPrototypeReplace(StringPrototypeSlice(code, + node.node.start, node.node.end), + escapeSequencesRegExp, escapeFn) ]; } @@ -330,23 +344,24 @@ function getErrMessage(message, fn) { decoder.end(); } else { for (let i = 0; i < line; i++) { - code = code.slice(code.indexOf('\n') + 1); + code = StringPrototypeSlice(code, + StringPrototypeIndexOf(code, '\n') + 1); } [column, message] = parseCode(code, column); } // Always normalize indentation, otherwise the message could look weird. - if (message.includes('\n')) { + if (StringPrototypeIncludes(message, '\n')) { if (EOL === '\r\n') { - message = message.replace(/\r\n/g, '\n'); + message = StringPrototypeReplace(message, /\r\n/g, '\n'); } - const frames = message.split('\n'); - message = frames.shift(); + const frames = StringPrototypeSplit(message, '\n'); + message = ArrayPrototypeShift(frames); for (const frame of frames) { let pos = 0; while (pos < column && (frame[pos] === ' ' || frame[pos] === '\t')) { pos++; } - message += `\n ${frame.slice(pos)}`; + message += `\n ${StringPrototypeSlice(frame, pos)}`; } } message = `The expression evaluated to a falsy value:\n\n ${message}\n`; @@ -670,7 +685,7 @@ function expectedException(actual, expected, message, fn) { // Special handle errors to make sure the name and the message are // compared as well. if (expected instanceof Error) { - keys.push('name', 'message'); + ArrayPrototypePush(keys, 'name', 'message'); } else if (keys.length === 0) { throw new ERR_INVALID_ARG_VALUE('error', expected, 'may not be an empty object'); @@ -713,7 +728,7 @@ function expectedException(actual, expected, message, fn) { throwError = true; } else { // Check validation functions return value. - const res = expected.call({}, actual); + const res = ReflectApply(expected, {}, [actual]); if (res !== true) { if (!message) { generatedMessage = true; @@ -858,7 +873,7 @@ function hasMatchingError(actual, expected) { if (ObjectPrototypeIsPrototypeOf(Error, expected)) { return false; } - return expected.call({}, actual) === true; + return ReflectApply(expected, {}, [actual]) === true; } function expectsNoError(stackStartFn, actual, error, message) { @@ -959,20 +974,21 @@ assert.ifError = function ifError(err) { // This will remove any duplicated frames from the error frames taken // from within `ifError` and add the original error frames to the newly // created ones. - const tmp2 = origStack.split('\n'); - tmp2.shift(); + const tmp2 = StringPrototypeSplit(origStack, '\n'); + ArrayPrototypeShift(tmp2); // Filter all frames existing in err.stack. - let tmp1 = newErr.stack.split('\n'); + let tmp1 = StringPrototypeSplit(newErr.stack, '\n'); for (const errFrame of tmp2) { // Find the first occurrence of the frame. - const pos = tmp1.indexOf(errFrame); + const pos = ArrayPrototypeIndexOf(tmp1, errFrame); if (pos !== -1) { // Only keep new frames. - tmp1 = tmp1.slice(0, pos); + tmp1 = ArrayPrototypeSlice(tmp1, 0, pos); break; } } - newErr.stack = `${tmp1.join('\n')}\n${tmp2.join('\n')}`; + newErr.stack = + `${ArrayPrototypeJoin(tmp1, '\n')}\n${ArrayPrototypeJoin(tmp2, '\n')}`; } throw newErr;