11cb0ef41Sopenharmony_ci// Originally from narwhal.js (http://narwhaljs.org) 21cb0ef41Sopenharmony_ci// Copyright (c) 2009 Thomas Robinson <280north.com> 31cb0ef41Sopenharmony_ci// 41cb0ef41Sopenharmony_ci// Permission is hereby granted, free of charge, to any person obtaining a copy 51cb0ef41Sopenharmony_ci// of this software and associated documentation files (the 'Software'), to 61cb0ef41Sopenharmony_ci// deal in the Software without restriction, including without limitation the 71cb0ef41Sopenharmony_ci// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 81cb0ef41Sopenharmony_ci// sell copies of the Software, and to permit persons to whom the Software is 91cb0ef41Sopenharmony_ci// furnished to do so, subject to the following conditions: 101cb0ef41Sopenharmony_ci// 111cb0ef41Sopenharmony_ci// The above copyright notice and this permission notice shall be included in 121cb0ef41Sopenharmony_ci// all copies or substantial portions of the Software. 131cb0ef41Sopenharmony_ci// 141cb0ef41Sopenharmony_ci// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 151cb0ef41Sopenharmony_ci// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 161cb0ef41Sopenharmony_ci// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 171cb0ef41Sopenharmony_ci// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 181cb0ef41Sopenharmony_ci// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 191cb0ef41Sopenharmony_ci// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci'use strict'; 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ciconst { 241cb0ef41Sopenharmony_ci ArrayPrototypeIndexOf, 251cb0ef41Sopenharmony_ci ArrayPrototypeJoin, 261cb0ef41Sopenharmony_ci ArrayPrototypePush, 271cb0ef41Sopenharmony_ci ArrayPrototypeShift, 281cb0ef41Sopenharmony_ci ArrayPrototypeSlice, 291cb0ef41Sopenharmony_ci Error, 301cb0ef41Sopenharmony_ci ErrorCaptureStackTrace, 311cb0ef41Sopenharmony_ci FunctionPrototypeBind, 321cb0ef41Sopenharmony_ci NumberIsNaN, 331cb0ef41Sopenharmony_ci ObjectAssign, 341cb0ef41Sopenharmony_ci ObjectIs, 351cb0ef41Sopenharmony_ci ObjectKeys, 361cb0ef41Sopenharmony_ci ObjectPrototypeIsPrototypeOf, 371cb0ef41Sopenharmony_ci ReflectApply, 381cb0ef41Sopenharmony_ci RegExpPrototypeExec, 391cb0ef41Sopenharmony_ci RegExpPrototypeSymbolReplace, 401cb0ef41Sopenharmony_ci SafeMap, 411cb0ef41Sopenharmony_ci String, 421cb0ef41Sopenharmony_ci StringPrototypeCharCodeAt, 431cb0ef41Sopenharmony_ci StringPrototypeIncludes, 441cb0ef41Sopenharmony_ci StringPrototypeIndexOf, 451cb0ef41Sopenharmony_ci StringPrototypeReplace, 461cb0ef41Sopenharmony_ci StringPrototypeSlice, 471cb0ef41Sopenharmony_ci StringPrototypeSplit, 481cb0ef41Sopenharmony_ci StringPrototypeStartsWith, 491cb0ef41Sopenharmony_ci} = primordials; 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ciconst { Buffer } = require('buffer'); 521cb0ef41Sopenharmony_ciconst { 531cb0ef41Sopenharmony_ci codes: { 541cb0ef41Sopenharmony_ci ERR_AMBIGUOUS_ARGUMENT, 551cb0ef41Sopenharmony_ci ERR_INVALID_ARG_TYPE, 561cb0ef41Sopenharmony_ci ERR_INVALID_ARG_VALUE, 571cb0ef41Sopenharmony_ci ERR_INVALID_RETURN_VALUE, 581cb0ef41Sopenharmony_ci ERR_MISSING_ARGS, 591cb0ef41Sopenharmony_ci }, 601cb0ef41Sopenharmony_ci isErrorStackTraceLimitWritable, 611cb0ef41Sopenharmony_ci overrideStackTrace, 621cb0ef41Sopenharmony_ci} = require('internal/errors'); 631cb0ef41Sopenharmony_ciconst AssertionError = require('internal/assert/assertion_error'); 641cb0ef41Sopenharmony_ciconst { openSync, closeSync, readSync } = require('fs'); 651cb0ef41Sopenharmony_ciconst { inspect } = require('internal/util/inspect'); 661cb0ef41Sopenharmony_ciconst { isPromise, isRegExp } = require('internal/util/types'); 671cb0ef41Sopenharmony_ciconst { EOL } = require('internal/constants'); 681cb0ef41Sopenharmony_ciconst { BuiltinModule } = require('internal/bootstrap/realm'); 691cb0ef41Sopenharmony_ciconst { isError } = require('internal/util'); 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ciconst errorCache = new SafeMap(); 721cb0ef41Sopenharmony_ciconst CallTracker = require('internal/assert/calltracker'); 731cb0ef41Sopenharmony_ciconst { 741cb0ef41Sopenharmony_ci validateFunction, 751cb0ef41Sopenharmony_ci} = require('internal/validators'); 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_cilet isDeepEqual; 781cb0ef41Sopenharmony_cilet isDeepStrictEqual; 791cb0ef41Sopenharmony_cilet parseExpressionAt; 801cb0ef41Sopenharmony_cilet findNodeAround; 811cb0ef41Sopenharmony_cilet tokenizer; 821cb0ef41Sopenharmony_cilet decoder; 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_cifunction lazyLoadComparison() { 851cb0ef41Sopenharmony_ci const comparison = require('internal/util/comparisons'); 861cb0ef41Sopenharmony_ci isDeepEqual = comparison.isDeepEqual; 871cb0ef41Sopenharmony_ci isDeepStrictEqual = comparison.isDeepStrictEqual; 881cb0ef41Sopenharmony_ci} 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci// Escape control characters but not \n and \t to keep the line breaks and 911cb0ef41Sopenharmony_ci// indentation intact. 921cb0ef41Sopenharmony_ci// eslint-disable-next-line no-control-regex 931cb0ef41Sopenharmony_ciconst escapeSequencesRegExp = /[\x00-\x08\x0b\x0c\x0e-\x1f]/g; 941cb0ef41Sopenharmony_ciconst meta = [ 951cb0ef41Sopenharmony_ci '\\u0000', '\\u0001', '\\u0002', '\\u0003', '\\u0004', 961cb0ef41Sopenharmony_ci '\\u0005', '\\u0006', '\\u0007', '\\b', '', 971cb0ef41Sopenharmony_ci '', '\\u000b', '\\f', '', '\\u000e', 981cb0ef41Sopenharmony_ci '\\u000f', '\\u0010', '\\u0011', '\\u0012', '\\u0013', 991cb0ef41Sopenharmony_ci '\\u0014', '\\u0015', '\\u0016', '\\u0017', '\\u0018', 1001cb0ef41Sopenharmony_ci '\\u0019', '\\u001a', '\\u001b', '\\u001c', '\\u001d', 1011cb0ef41Sopenharmony_ci '\\u001e', '\\u001f', 1021cb0ef41Sopenharmony_ci]; 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ciconst escapeFn = (str) => meta[StringPrototypeCharCodeAt(str, 0)]; 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_cilet warned = false; 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci// The assert module provides functions that throw 1091cb0ef41Sopenharmony_ci// AssertionError's when particular conditions are not met. The 1101cb0ef41Sopenharmony_ci// assert module must conform to the following interface. 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ciconst assert = module.exports = ok; 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ciconst NO_EXCEPTION_SENTINEL = {}; 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci// All of the following functions must throw an AssertionError 1171cb0ef41Sopenharmony_ci// when a corresponding condition is not met, with a message that 1181cb0ef41Sopenharmony_ci// may be undefined if not provided. All assertion methods provide 1191cb0ef41Sopenharmony_ci// both the actual and expected values to the assertion error for 1201cb0ef41Sopenharmony_ci// display purposes. 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_cifunction innerFail(obj) { 1231cb0ef41Sopenharmony_ci if (obj.message instanceof Error) throw obj.message; 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci throw new AssertionError(obj); 1261cb0ef41Sopenharmony_ci} 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci/** 1291cb0ef41Sopenharmony_ci * @param {any} actual 1301cb0ef41Sopenharmony_ci * @param {any} expected 1311cb0ef41Sopenharmony_ci * @param {string | Error} [message] 1321cb0ef41Sopenharmony_ci * @param {string} [operator] 1331cb0ef41Sopenharmony_ci * @param {Function} [stackStartFn] 1341cb0ef41Sopenharmony_ci */ 1351cb0ef41Sopenharmony_cifunction fail(actual, expected, message, operator, stackStartFn) { 1361cb0ef41Sopenharmony_ci const argsLen = arguments.length; 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci let internalMessage = false; 1391cb0ef41Sopenharmony_ci if (actual == null && argsLen <= 1) { 1401cb0ef41Sopenharmony_ci internalMessage = true; 1411cb0ef41Sopenharmony_ci message = 'Failed'; 1421cb0ef41Sopenharmony_ci } else if (argsLen === 1) { 1431cb0ef41Sopenharmony_ci message = actual; 1441cb0ef41Sopenharmony_ci actual = undefined; 1451cb0ef41Sopenharmony_ci } else { 1461cb0ef41Sopenharmony_ci if (warned === false) { 1471cb0ef41Sopenharmony_ci warned = true; 1481cb0ef41Sopenharmony_ci process.emitWarning( 1491cb0ef41Sopenharmony_ci 'assert.fail() with more than one argument is deprecated. ' + 1501cb0ef41Sopenharmony_ci 'Please use assert.strictEqual() instead or only pass a message.', 1511cb0ef41Sopenharmony_ci 'DeprecationWarning', 1521cb0ef41Sopenharmony_ci 'DEP0094', 1531cb0ef41Sopenharmony_ci ); 1541cb0ef41Sopenharmony_ci } 1551cb0ef41Sopenharmony_ci if (argsLen === 2) 1561cb0ef41Sopenharmony_ci operator = '!='; 1571cb0ef41Sopenharmony_ci } 1581cb0ef41Sopenharmony_ci 1591cb0ef41Sopenharmony_ci if (message instanceof Error) throw message; 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_ci const errArgs = { 1621cb0ef41Sopenharmony_ci actual, 1631cb0ef41Sopenharmony_ci expected, 1641cb0ef41Sopenharmony_ci operator: operator === undefined ? 'fail' : operator, 1651cb0ef41Sopenharmony_ci stackStartFn: stackStartFn || fail, 1661cb0ef41Sopenharmony_ci message, 1671cb0ef41Sopenharmony_ci }; 1681cb0ef41Sopenharmony_ci const err = new AssertionError(errArgs); 1691cb0ef41Sopenharmony_ci if (internalMessage) { 1701cb0ef41Sopenharmony_ci err.generatedMessage = true; 1711cb0ef41Sopenharmony_ci } 1721cb0ef41Sopenharmony_ci throw err; 1731cb0ef41Sopenharmony_ci} 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ciassert.fail = fail; 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci// The AssertionError is defined in internal/error. 1781cb0ef41Sopenharmony_ciassert.AssertionError = AssertionError; 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_cifunction findColumn(fd, column, code) { 1811cb0ef41Sopenharmony_ci if (code.length > column + 100) { 1821cb0ef41Sopenharmony_ci try { 1831cb0ef41Sopenharmony_ci return parseCode(code, column); 1841cb0ef41Sopenharmony_ci } catch { 1851cb0ef41Sopenharmony_ci // End recursion in case no code could be parsed. The expression should 1861cb0ef41Sopenharmony_ci // have been found after 2500 characters, so stop trying. 1871cb0ef41Sopenharmony_ci if (code.length - column > 2500) { 1881cb0ef41Sopenharmony_ci // eslint-disable-next-line no-throw-literal 1891cb0ef41Sopenharmony_ci throw null; 1901cb0ef41Sopenharmony_ci } 1911cb0ef41Sopenharmony_ci } 1921cb0ef41Sopenharmony_ci } 1931cb0ef41Sopenharmony_ci // Read up to 2500 bytes more than necessary in columns. That way we address 1941cb0ef41Sopenharmony_ci // multi byte characters and read enough data to parse the code. 1951cb0ef41Sopenharmony_ci const bytesToRead = column - code.length + 2500; 1961cb0ef41Sopenharmony_ci const buffer = Buffer.allocUnsafe(bytesToRead); 1971cb0ef41Sopenharmony_ci const bytesRead = readSync(fd, buffer, 0, bytesToRead); 1981cb0ef41Sopenharmony_ci code += decoder.write(buffer.slice(0, bytesRead)); 1991cb0ef41Sopenharmony_ci // EOF: fast path. 2001cb0ef41Sopenharmony_ci if (bytesRead < bytesToRead) { 2011cb0ef41Sopenharmony_ci return parseCode(code, column); 2021cb0ef41Sopenharmony_ci } 2031cb0ef41Sopenharmony_ci // Read potentially missing code. 2041cb0ef41Sopenharmony_ci return findColumn(fd, column, code); 2051cb0ef41Sopenharmony_ci} 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_cifunction getCode(fd, line, column) { 2081cb0ef41Sopenharmony_ci let bytesRead = 0; 2091cb0ef41Sopenharmony_ci if (line === 0) { 2101cb0ef41Sopenharmony_ci // Special handle line number one. This is more efficient and simplifies the 2111cb0ef41Sopenharmony_ci // rest of the algorithm. Read more than the regular column number in bytes 2121cb0ef41Sopenharmony_ci // to prevent multiple reads in case multi byte characters are used. 2131cb0ef41Sopenharmony_ci return findColumn(fd, column, ''); 2141cb0ef41Sopenharmony_ci } 2151cb0ef41Sopenharmony_ci let lines = 0; 2161cb0ef41Sopenharmony_ci // Prevent blocking the event loop by limiting the maximum amount of 2171cb0ef41Sopenharmony_ci // data that may be read. 2181cb0ef41Sopenharmony_ci let maxReads = 32; // bytesPerRead * maxReads = 512 KiB 2191cb0ef41Sopenharmony_ci const bytesPerRead = 16384; 2201cb0ef41Sopenharmony_ci // Use a single buffer up front that is reused until the call site is found. 2211cb0ef41Sopenharmony_ci let buffer = Buffer.allocUnsafe(bytesPerRead); 2221cb0ef41Sopenharmony_ci while (maxReads-- !== 0) { 2231cb0ef41Sopenharmony_ci // Only allocate a new buffer in case the needed line is found. All data 2241cb0ef41Sopenharmony_ci // before that can be discarded. 2251cb0ef41Sopenharmony_ci buffer = lines < line ? buffer : Buffer.allocUnsafe(bytesPerRead); 2261cb0ef41Sopenharmony_ci bytesRead = readSync(fd, buffer, 0, bytesPerRead); 2271cb0ef41Sopenharmony_ci // Read the buffer until the required code line is found. 2281cb0ef41Sopenharmony_ci for (let i = 0; i < bytesRead; i++) { 2291cb0ef41Sopenharmony_ci if (buffer[i] === 10 && ++lines === line) { 2301cb0ef41Sopenharmony_ci // If the end of file is reached, directly parse the code and return. 2311cb0ef41Sopenharmony_ci if (bytesRead < bytesPerRead) { 2321cb0ef41Sopenharmony_ci return parseCode(buffer.toString('utf8', i + 1, bytesRead), column); 2331cb0ef41Sopenharmony_ci } 2341cb0ef41Sopenharmony_ci // Check if the read code is sufficient or read more until the whole 2351cb0ef41Sopenharmony_ci // expression is read. Make sure multi byte characters are preserved 2361cb0ef41Sopenharmony_ci // properly by using the decoder. 2371cb0ef41Sopenharmony_ci const code = decoder.write(buffer.slice(i + 1, bytesRead)); 2381cb0ef41Sopenharmony_ci return findColumn(fd, column, code); 2391cb0ef41Sopenharmony_ci } 2401cb0ef41Sopenharmony_ci } 2411cb0ef41Sopenharmony_ci } 2421cb0ef41Sopenharmony_ci} 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_cifunction parseCode(code, offset) { 2451cb0ef41Sopenharmony_ci // Lazy load acorn. 2461cb0ef41Sopenharmony_ci if (parseExpressionAt === undefined) { 2471cb0ef41Sopenharmony_ci const Parser = require('internal/deps/acorn/acorn/dist/acorn').Parser; 2481cb0ef41Sopenharmony_ci ({ findNodeAround } = require('internal/deps/acorn/acorn-walk/dist/walk')); 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_ci parseExpressionAt = FunctionPrototypeBind(Parser.parseExpressionAt, Parser); 2511cb0ef41Sopenharmony_ci tokenizer = FunctionPrototypeBind(Parser.tokenizer, Parser); 2521cb0ef41Sopenharmony_ci } 2531cb0ef41Sopenharmony_ci let node; 2541cb0ef41Sopenharmony_ci let start; 2551cb0ef41Sopenharmony_ci // Parse the read code until the correct expression is found. 2561cb0ef41Sopenharmony_ci for (const token of tokenizer(code, { ecmaVersion: 'latest' })) { 2571cb0ef41Sopenharmony_ci start = token.start; 2581cb0ef41Sopenharmony_ci if (start > offset) { 2591cb0ef41Sopenharmony_ci // No matching expression found. This could happen if the assert 2601cb0ef41Sopenharmony_ci // expression is bigger than the provided buffer. 2611cb0ef41Sopenharmony_ci break; 2621cb0ef41Sopenharmony_ci } 2631cb0ef41Sopenharmony_ci try { 2641cb0ef41Sopenharmony_ci node = parseExpressionAt(code, start, { ecmaVersion: 'latest' }); 2651cb0ef41Sopenharmony_ci // Find the CallExpression in the tree. 2661cb0ef41Sopenharmony_ci node = findNodeAround(node, offset, 'CallExpression'); 2671cb0ef41Sopenharmony_ci if (node?.node.end >= offset) { 2681cb0ef41Sopenharmony_ci return [ 2691cb0ef41Sopenharmony_ci node.node.start, 2701cb0ef41Sopenharmony_ci StringPrototypeReplace(StringPrototypeSlice(code, 2711cb0ef41Sopenharmony_ci node.node.start, node.node.end), 2721cb0ef41Sopenharmony_ci escapeSequencesRegExp, escapeFn), 2731cb0ef41Sopenharmony_ci ]; 2741cb0ef41Sopenharmony_ci } 2751cb0ef41Sopenharmony_ci // eslint-disable-next-line no-unused-vars 2761cb0ef41Sopenharmony_ci } catch (err) { 2771cb0ef41Sopenharmony_ci continue; 2781cb0ef41Sopenharmony_ci } 2791cb0ef41Sopenharmony_ci } 2801cb0ef41Sopenharmony_ci // eslint-disable-next-line no-throw-literal 2811cb0ef41Sopenharmony_ci throw null; 2821cb0ef41Sopenharmony_ci} 2831cb0ef41Sopenharmony_ci 2841cb0ef41Sopenharmony_cifunction getErrMessage(message, fn) { 2851cb0ef41Sopenharmony_ci const tmpLimit = Error.stackTraceLimit; 2861cb0ef41Sopenharmony_ci const errorStackTraceLimitIsWritable = isErrorStackTraceLimitWritable(); 2871cb0ef41Sopenharmony_ci // Make sure the limit is set to 1. Otherwise it could fail (<= 0) or it 2881cb0ef41Sopenharmony_ci // does to much work. 2891cb0ef41Sopenharmony_ci if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = 1; 2901cb0ef41Sopenharmony_ci // We only need the stack trace. To minimize the overhead use an object 2911cb0ef41Sopenharmony_ci // instead of an error. 2921cb0ef41Sopenharmony_ci const err = {}; 2931cb0ef41Sopenharmony_ci ErrorCaptureStackTrace(err, fn); 2941cb0ef41Sopenharmony_ci if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = tmpLimit; 2951cb0ef41Sopenharmony_ci 2961cb0ef41Sopenharmony_ci overrideStackTrace.set(err, (_, stack) => stack); 2971cb0ef41Sopenharmony_ci const call = err.stack[0]; 2981cb0ef41Sopenharmony_ci 2991cb0ef41Sopenharmony_ci const filename = call.getFileName(); 3001cb0ef41Sopenharmony_ci const line = call.getLineNumber() - 1; 3011cb0ef41Sopenharmony_ci let column = call.getColumnNumber() - 1; 3021cb0ef41Sopenharmony_ci let identifier; 3031cb0ef41Sopenharmony_ci let code; 3041cb0ef41Sopenharmony_ci 3051cb0ef41Sopenharmony_ci if (filename) { 3061cb0ef41Sopenharmony_ci identifier = `${filename}${line}${column}`; 3071cb0ef41Sopenharmony_ci 3081cb0ef41Sopenharmony_ci // Skip Node.js modules! 3091cb0ef41Sopenharmony_ci if (StringPrototypeStartsWith(filename, 'node:') && 3101cb0ef41Sopenharmony_ci BuiltinModule.exists(StringPrototypeSlice(filename, 5))) { 3111cb0ef41Sopenharmony_ci errorCache.set(identifier, undefined); 3121cb0ef41Sopenharmony_ci return; 3131cb0ef41Sopenharmony_ci } 3141cb0ef41Sopenharmony_ci } else { 3151cb0ef41Sopenharmony_ci return message; 3161cb0ef41Sopenharmony_ci } 3171cb0ef41Sopenharmony_ci 3181cb0ef41Sopenharmony_ci if (errorCache.has(identifier)) { 3191cb0ef41Sopenharmony_ci return errorCache.get(identifier); 3201cb0ef41Sopenharmony_ci } 3211cb0ef41Sopenharmony_ci 3221cb0ef41Sopenharmony_ci let fd; 3231cb0ef41Sopenharmony_ci try { 3241cb0ef41Sopenharmony_ci // Set the stack trace limit to zero. This makes sure unexpected token 3251cb0ef41Sopenharmony_ci // errors are handled faster. 3261cb0ef41Sopenharmony_ci if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = 0; 3271cb0ef41Sopenharmony_ci 3281cb0ef41Sopenharmony_ci if (filename) { 3291cb0ef41Sopenharmony_ci if (decoder === undefined) { 3301cb0ef41Sopenharmony_ci const { StringDecoder } = require('string_decoder'); 3311cb0ef41Sopenharmony_ci decoder = new StringDecoder('utf8'); 3321cb0ef41Sopenharmony_ci } 3331cb0ef41Sopenharmony_ci fd = openSync(filename, 'r', 0o666); 3341cb0ef41Sopenharmony_ci // Reset column and message. 3351cb0ef41Sopenharmony_ci ({ 0: column, 1: message } = getCode(fd, line, column)); 3361cb0ef41Sopenharmony_ci // Flush unfinished multi byte characters. 3371cb0ef41Sopenharmony_ci decoder.end(); 3381cb0ef41Sopenharmony_ci } else { 3391cb0ef41Sopenharmony_ci for (let i = 0; i < line; i++) { 3401cb0ef41Sopenharmony_ci code = StringPrototypeSlice(code, 3411cb0ef41Sopenharmony_ci StringPrototypeIndexOf(code, '\n') + 1); 3421cb0ef41Sopenharmony_ci } 3431cb0ef41Sopenharmony_ci ({ 0: column, 1: message } = parseCode(code, column)); 3441cb0ef41Sopenharmony_ci } 3451cb0ef41Sopenharmony_ci // Always normalize indentation, otherwise the message could look weird. 3461cb0ef41Sopenharmony_ci if (StringPrototypeIncludes(message, '\n')) { 3471cb0ef41Sopenharmony_ci if (EOL === '\r\n') { 3481cb0ef41Sopenharmony_ci message = RegExpPrototypeSymbolReplace(/\r\n/g, message, '\n'); 3491cb0ef41Sopenharmony_ci } 3501cb0ef41Sopenharmony_ci const frames = StringPrototypeSplit(message, '\n'); 3511cb0ef41Sopenharmony_ci message = ArrayPrototypeShift(frames); 3521cb0ef41Sopenharmony_ci for (const frame of frames) { 3531cb0ef41Sopenharmony_ci let pos = 0; 3541cb0ef41Sopenharmony_ci while (pos < column && (frame[pos] === ' ' || frame[pos] === '\t')) { 3551cb0ef41Sopenharmony_ci pos++; 3561cb0ef41Sopenharmony_ci } 3571cb0ef41Sopenharmony_ci message += `\n ${StringPrototypeSlice(frame, pos)}`; 3581cb0ef41Sopenharmony_ci } 3591cb0ef41Sopenharmony_ci } 3601cb0ef41Sopenharmony_ci message = `The expression evaluated to a falsy value:\n\n ${message}\n`; 3611cb0ef41Sopenharmony_ci // Make sure to always set the cache! No matter if the message is 3621cb0ef41Sopenharmony_ci // undefined or not 3631cb0ef41Sopenharmony_ci errorCache.set(identifier, message); 3641cb0ef41Sopenharmony_ci 3651cb0ef41Sopenharmony_ci return message; 3661cb0ef41Sopenharmony_ci } catch { 3671cb0ef41Sopenharmony_ci // Invalidate cache to prevent trying to read this part again. 3681cb0ef41Sopenharmony_ci errorCache.set(identifier, undefined); 3691cb0ef41Sopenharmony_ci } finally { 3701cb0ef41Sopenharmony_ci // Reset limit. 3711cb0ef41Sopenharmony_ci if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = tmpLimit; 3721cb0ef41Sopenharmony_ci if (fd !== undefined) 3731cb0ef41Sopenharmony_ci closeSync(fd); 3741cb0ef41Sopenharmony_ci } 3751cb0ef41Sopenharmony_ci} 3761cb0ef41Sopenharmony_ci 3771cb0ef41Sopenharmony_cifunction innerOk(fn, argLen, value, message) { 3781cb0ef41Sopenharmony_ci if (!value) { 3791cb0ef41Sopenharmony_ci let generatedMessage = false; 3801cb0ef41Sopenharmony_ci 3811cb0ef41Sopenharmony_ci if (argLen === 0) { 3821cb0ef41Sopenharmony_ci generatedMessage = true; 3831cb0ef41Sopenharmony_ci message = 'No value argument passed to `assert.ok()`'; 3841cb0ef41Sopenharmony_ci } else if (message == null) { 3851cb0ef41Sopenharmony_ci generatedMessage = true; 3861cb0ef41Sopenharmony_ci message = getErrMessage(message, fn); 3871cb0ef41Sopenharmony_ci } else if (message instanceof Error) { 3881cb0ef41Sopenharmony_ci throw message; 3891cb0ef41Sopenharmony_ci } 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ci const err = new AssertionError({ 3921cb0ef41Sopenharmony_ci actual: value, 3931cb0ef41Sopenharmony_ci expected: true, 3941cb0ef41Sopenharmony_ci message, 3951cb0ef41Sopenharmony_ci operator: '==', 3961cb0ef41Sopenharmony_ci stackStartFn: fn, 3971cb0ef41Sopenharmony_ci }); 3981cb0ef41Sopenharmony_ci err.generatedMessage = generatedMessage; 3991cb0ef41Sopenharmony_ci throw err; 4001cb0ef41Sopenharmony_ci } 4011cb0ef41Sopenharmony_ci} 4021cb0ef41Sopenharmony_ci 4031cb0ef41Sopenharmony_ci/** 4041cb0ef41Sopenharmony_ci * Pure assertion tests whether a value is truthy, as determined 4051cb0ef41Sopenharmony_ci * by !!value. 4061cb0ef41Sopenharmony_ci * @param {...any} args 4071cb0ef41Sopenharmony_ci * @returns {void} 4081cb0ef41Sopenharmony_ci */ 4091cb0ef41Sopenharmony_cifunction ok(...args) { 4101cb0ef41Sopenharmony_ci innerOk(ok, args.length, ...args); 4111cb0ef41Sopenharmony_ci} 4121cb0ef41Sopenharmony_ciassert.ok = ok; 4131cb0ef41Sopenharmony_ci 4141cb0ef41Sopenharmony_ci/** 4151cb0ef41Sopenharmony_ci * The equality assertion tests shallow, coercive equality with ==. 4161cb0ef41Sopenharmony_ci * @param {any} actual 4171cb0ef41Sopenharmony_ci * @param {any} expected 4181cb0ef41Sopenharmony_ci * @param {string | Error} [message] 4191cb0ef41Sopenharmony_ci * @returns {void} 4201cb0ef41Sopenharmony_ci */ 4211cb0ef41Sopenharmony_ci/* eslint-disable no-restricted-properties */ 4221cb0ef41Sopenharmony_ciassert.equal = function equal(actual, expected, message) { 4231cb0ef41Sopenharmony_ci if (arguments.length < 2) { 4241cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('actual', 'expected'); 4251cb0ef41Sopenharmony_ci } 4261cb0ef41Sopenharmony_ci // eslint-disable-next-line eqeqeq 4271cb0ef41Sopenharmony_ci if (actual != expected && (!NumberIsNaN(actual) || !NumberIsNaN(expected))) { 4281cb0ef41Sopenharmony_ci innerFail({ 4291cb0ef41Sopenharmony_ci actual, 4301cb0ef41Sopenharmony_ci expected, 4311cb0ef41Sopenharmony_ci message, 4321cb0ef41Sopenharmony_ci operator: '==', 4331cb0ef41Sopenharmony_ci stackStartFn: equal, 4341cb0ef41Sopenharmony_ci }); 4351cb0ef41Sopenharmony_ci } 4361cb0ef41Sopenharmony_ci}; 4371cb0ef41Sopenharmony_ci 4381cb0ef41Sopenharmony_ci/** 4391cb0ef41Sopenharmony_ci * The non-equality assertion tests for whether two objects are not 4401cb0ef41Sopenharmony_ci * equal with !=. 4411cb0ef41Sopenharmony_ci * @param {any} actual 4421cb0ef41Sopenharmony_ci * @param {any} expected 4431cb0ef41Sopenharmony_ci * @param {string | Error} [message] 4441cb0ef41Sopenharmony_ci * @returns {void} 4451cb0ef41Sopenharmony_ci */ 4461cb0ef41Sopenharmony_ciassert.notEqual = function notEqual(actual, expected, message) { 4471cb0ef41Sopenharmony_ci if (arguments.length < 2) { 4481cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('actual', 'expected'); 4491cb0ef41Sopenharmony_ci } 4501cb0ef41Sopenharmony_ci // eslint-disable-next-line eqeqeq 4511cb0ef41Sopenharmony_ci if (actual == expected || (NumberIsNaN(actual) && NumberIsNaN(expected))) { 4521cb0ef41Sopenharmony_ci innerFail({ 4531cb0ef41Sopenharmony_ci actual, 4541cb0ef41Sopenharmony_ci expected, 4551cb0ef41Sopenharmony_ci message, 4561cb0ef41Sopenharmony_ci operator: '!=', 4571cb0ef41Sopenharmony_ci stackStartFn: notEqual, 4581cb0ef41Sopenharmony_ci }); 4591cb0ef41Sopenharmony_ci } 4601cb0ef41Sopenharmony_ci}; 4611cb0ef41Sopenharmony_ci 4621cb0ef41Sopenharmony_ci/** 4631cb0ef41Sopenharmony_ci * The deep equivalence assertion tests a deep equality relation. 4641cb0ef41Sopenharmony_ci * @param {any} actual 4651cb0ef41Sopenharmony_ci * @param {any} expected 4661cb0ef41Sopenharmony_ci * @param {string | Error} [message] 4671cb0ef41Sopenharmony_ci * @returns {void} 4681cb0ef41Sopenharmony_ci */ 4691cb0ef41Sopenharmony_ciassert.deepEqual = function deepEqual(actual, expected, message) { 4701cb0ef41Sopenharmony_ci if (arguments.length < 2) { 4711cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('actual', 'expected'); 4721cb0ef41Sopenharmony_ci } 4731cb0ef41Sopenharmony_ci if (isDeepEqual === undefined) lazyLoadComparison(); 4741cb0ef41Sopenharmony_ci if (!isDeepEqual(actual, expected)) { 4751cb0ef41Sopenharmony_ci innerFail({ 4761cb0ef41Sopenharmony_ci actual, 4771cb0ef41Sopenharmony_ci expected, 4781cb0ef41Sopenharmony_ci message, 4791cb0ef41Sopenharmony_ci operator: 'deepEqual', 4801cb0ef41Sopenharmony_ci stackStartFn: deepEqual, 4811cb0ef41Sopenharmony_ci }); 4821cb0ef41Sopenharmony_ci } 4831cb0ef41Sopenharmony_ci}; 4841cb0ef41Sopenharmony_ci 4851cb0ef41Sopenharmony_ci/** 4861cb0ef41Sopenharmony_ci * The deep non-equivalence assertion tests for any deep inequality. 4871cb0ef41Sopenharmony_ci * @param {any} actual 4881cb0ef41Sopenharmony_ci * @param {any} expected 4891cb0ef41Sopenharmony_ci * @param {string | Error} [message] 4901cb0ef41Sopenharmony_ci * @returns {void} 4911cb0ef41Sopenharmony_ci */ 4921cb0ef41Sopenharmony_ciassert.notDeepEqual = function notDeepEqual(actual, expected, message) { 4931cb0ef41Sopenharmony_ci if (arguments.length < 2) { 4941cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('actual', 'expected'); 4951cb0ef41Sopenharmony_ci } 4961cb0ef41Sopenharmony_ci if (isDeepEqual === undefined) lazyLoadComparison(); 4971cb0ef41Sopenharmony_ci if (isDeepEqual(actual, expected)) { 4981cb0ef41Sopenharmony_ci innerFail({ 4991cb0ef41Sopenharmony_ci actual, 5001cb0ef41Sopenharmony_ci expected, 5011cb0ef41Sopenharmony_ci message, 5021cb0ef41Sopenharmony_ci operator: 'notDeepEqual', 5031cb0ef41Sopenharmony_ci stackStartFn: notDeepEqual, 5041cb0ef41Sopenharmony_ci }); 5051cb0ef41Sopenharmony_ci } 5061cb0ef41Sopenharmony_ci}; 5071cb0ef41Sopenharmony_ci/* eslint-enable */ 5081cb0ef41Sopenharmony_ci 5091cb0ef41Sopenharmony_ci/** 5101cb0ef41Sopenharmony_ci * The deep strict equivalence assertion tests a deep strict equality 5111cb0ef41Sopenharmony_ci * relation. 5121cb0ef41Sopenharmony_ci * @param {any} actual 5131cb0ef41Sopenharmony_ci * @param {any} expected 5141cb0ef41Sopenharmony_ci * @param {string | Error} [message] 5151cb0ef41Sopenharmony_ci * @returns {void} 5161cb0ef41Sopenharmony_ci */ 5171cb0ef41Sopenharmony_ciassert.deepStrictEqual = function deepStrictEqual(actual, expected, message) { 5181cb0ef41Sopenharmony_ci if (arguments.length < 2) { 5191cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('actual', 'expected'); 5201cb0ef41Sopenharmony_ci } 5211cb0ef41Sopenharmony_ci if (isDeepEqual === undefined) lazyLoadComparison(); 5221cb0ef41Sopenharmony_ci if (!isDeepStrictEqual(actual, expected)) { 5231cb0ef41Sopenharmony_ci innerFail({ 5241cb0ef41Sopenharmony_ci actual, 5251cb0ef41Sopenharmony_ci expected, 5261cb0ef41Sopenharmony_ci message, 5271cb0ef41Sopenharmony_ci operator: 'deepStrictEqual', 5281cb0ef41Sopenharmony_ci stackStartFn: deepStrictEqual, 5291cb0ef41Sopenharmony_ci }); 5301cb0ef41Sopenharmony_ci } 5311cb0ef41Sopenharmony_ci}; 5321cb0ef41Sopenharmony_ci 5331cb0ef41Sopenharmony_ci/** 5341cb0ef41Sopenharmony_ci * The deep strict non-equivalence assertion tests for any deep strict 5351cb0ef41Sopenharmony_ci * inequality. 5361cb0ef41Sopenharmony_ci * @param {any} actual 5371cb0ef41Sopenharmony_ci * @param {any} expected 5381cb0ef41Sopenharmony_ci * @param {string | Error} [message] 5391cb0ef41Sopenharmony_ci * @returns {void} 5401cb0ef41Sopenharmony_ci */ 5411cb0ef41Sopenharmony_ciassert.notDeepStrictEqual = notDeepStrictEqual; 5421cb0ef41Sopenharmony_cifunction notDeepStrictEqual(actual, expected, message) { 5431cb0ef41Sopenharmony_ci if (arguments.length < 2) { 5441cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('actual', 'expected'); 5451cb0ef41Sopenharmony_ci } 5461cb0ef41Sopenharmony_ci if (isDeepEqual === undefined) lazyLoadComparison(); 5471cb0ef41Sopenharmony_ci if (isDeepStrictEqual(actual, expected)) { 5481cb0ef41Sopenharmony_ci innerFail({ 5491cb0ef41Sopenharmony_ci actual, 5501cb0ef41Sopenharmony_ci expected, 5511cb0ef41Sopenharmony_ci message, 5521cb0ef41Sopenharmony_ci operator: 'notDeepStrictEqual', 5531cb0ef41Sopenharmony_ci stackStartFn: notDeepStrictEqual, 5541cb0ef41Sopenharmony_ci }); 5551cb0ef41Sopenharmony_ci } 5561cb0ef41Sopenharmony_ci} 5571cb0ef41Sopenharmony_ci 5581cb0ef41Sopenharmony_ci/** 5591cb0ef41Sopenharmony_ci * The strict equivalence assertion tests a strict equality relation. 5601cb0ef41Sopenharmony_ci * @param {any} actual 5611cb0ef41Sopenharmony_ci * @param {any} expected 5621cb0ef41Sopenharmony_ci * @param {string | Error} [message] 5631cb0ef41Sopenharmony_ci * @returns {void} 5641cb0ef41Sopenharmony_ci */ 5651cb0ef41Sopenharmony_ciassert.strictEqual = function strictEqual(actual, expected, message) { 5661cb0ef41Sopenharmony_ci if (arguments.length < 2) { 5671cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('actual', 'expected'); 5681cb0ef41Sopenharmony_ci } 5691cb0ef41Sopenharmony_ci if (!ObjectIs(actual, expected)) { 5701cb0ef41Sopenharmony_ci innerFail({ 5711cb0ef41Sopenharmony_ci actual, 5721cb0ef41Sopenharmony_ci expected, 5731cb0ef41Sopenharmony_ci message, 5741cb0ef41Sopenharmony_ci operator: 'strictEqual', 5751cb0ef41Sopenharmony_ci stackStartFn: strictEqual, 5761cb0ef41Sopenharmony_ci }); 5771cb0ef41Sopenharmony_ci } 5781cb0ef41Sopenharmony_ci}; 5791cb0ef41Sopenharmony_ci 5801cb0ef41Sopenharmony_ci/** 5811cb0ef41Sopenharmony_ci * The strict non-equivalence assertion tests for any strict inequality. 5821cb0ef41Sopenharmony_ci * @param {any} actual 5831cb0ef41Sopenharmony_ci * @param {any} expected 5841cb0ef41Sopenharmony_ci * @param {string | Error} [message] 5851cb0ef41Sopenharmony_ci * @returns {void} 5861cb0ef41Sopenharmony_ci */ 5871cb0ef41Sopenharmony_ciassert.notStrictEqual = function notStrictEqual(actual, expected, message) { 5881cb0ef41Sopenharmony_ci if (arguments.length < 2) { 5891cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('actual', 'expected'); 5901cb0ef41Sopenharmony_ci } 5911cb0ef41Sopenharmony_ci if (ObjectIs(actual, expected)) { 5921cb0ef41Sopenharmony_ci innerFail({ 5931cb0ef41Sopenharmony_ci actual, 5941cb0ef41Sopenharmony_ci expected, 5951cb0ef41Sopenharmony_ci message, 5961cb0ef41Sopenharmony_ci operator: 'notStrictEqual', 5971cb0ef41Sopenharmony_ci stackStartFn: notStrictEqual, 5981cb0ef41Sopenharmony_ci }); 5991cb0ef41Sopenharmony_ci } 6001cb0ef41Sopenharmony_ci}; 6011cb0ef41Sopenharmony_ci 6021cb0ef41Sopenharmony_ciclass Comparison { 6031cb0ef41Sopenharmony_ci constructor(obj, keys, actual) { 6041cb0ef41Sopenharmony_ci for (const key of keys) { 6051cb0ef41Sopenharmony_ci if (key in obj) { 6061cb0ef41Sopenharmony_ci if (actual !== undefined && 6071cb0ef41Sopenharmony_ci typeof actual[key] === 'string' && 6081cb0ef41Sopenharmony_ci isRegExp(obj[key]) && 6091cb0ef41Sopenharmony_ci RegExpPrototypeExec(obj[key], actual[key]) !== null) { 6101cb0ef41Sopenharmony_ci this[key] = actual[key]; 6111cb0ef41Sopenharmony_ci } else { 6121cb0ef41Sopenharmony_ci this[key] = obj[key]; 6131cb0ef41Sopenharmony_ci } 6141cb0ef41Sopenharmony_ci } 6151cb0ef41Sopenharmony_ci } 6161cb0ef41Sopenharmony_ci } 6171cb0ef41Sopenharmony_ci} 6181cb0ef41Sopenharmony_ci 6191cb0ef41Sopenharmony_cifunction compareExceptionKey(actual, expected, key, message, keys, fn) { 6201cb0ef41Sopenharmony_ci if (!(key in actual) || !isDeepStrictEqual(actual[key], expected[key])) { 6211cb0ef41Sopenharmony_ci if (!message) { 6221cb0ef41Sopenharmony_ci // Create placeholder objects to create a nice output. 6231cb0ef41Sopenharmony_ci const a = new Comparison(actual, keys); 6241cb0ef41Sopenharmony_ci const b = new Comparison(expected, keys, actual); 6251cb0ef41Sopenharmony_ci 6261cb0ef41Sopenharmony_ci const err = new AssertionError({ 6271cb0ef41Sopenharmony_ci actual: a, 6281cb0ef41Sopenharmony_ci expected: b, 6291cb0ef41Sopenharmony_ci operator: 'deepStrictEqual', 6301cb0ef41Sopenharmony_ci stackStartFn: fn, 6311cb0ef41Sopenharmony_ci }); 6321cb0ef41Sopenharmony_ci err.actual = actual; 6331cb0ef41Sopenharmony_ci err.expected = expected; 6341cb0ef41Sopenharmony_ci err.operator = fn.name; 6351cb0ef41Sopenharmony_ci throw err; 6361cb0ef41Sopenharmony_ci } 6371cb0ef41Sopenharmony_ci innerFail({ 6381cb0ef41Sopenharmony_ci actual, 6391cb0ef41Sopenharmony_ci expected, 6401cb0ef41Sopenharmony_ci message, 6411cb0ef41Sopenharmony_ci operator: fn.name, 6421cb0ef41Sopenharmony_ci stackStartFn: fn, 6431cb0ef41Sopenharmony_ci }); 6441cb0ef41Sopenharmony_ci } 6451cb0ef41Sopenharmony_ci} 6461cb0ef41Sopenharmony_ci 6471cb0ef41Sopenharmony_cifunction expectedException(actual, expected, message, fn) { 6481cb0ef41Sopenharmony_ci let generatedMessage = false; 6491cb0ef41Sopenharmony_ci let throwError = false; 6501cb0ef41Sopenharmony_ci 6511cb0ef41Sopenharmony_ci if (typeof expected !== 'function') { 6521cb0ef41Sopenharmony_ci // Handle regular expressions. 6531cb0ef41Sopenharmony_ci if (isRegExp(expected)) { 6541cb0ef41Sopenharmony_ci const str = String(actual); 6551cb0ef41Sopenharmony_ci if (RegExpPrototypeExec(expected, str) !== null) 6561cb0ef41Sopenharmony_ci return; 6571cb0ef41Sopenharmony_ci 6581cb0ef41Sopenharmony_ci if (!message) { 6591cb0ef41Sopenharmony_ci generatedMessage = true; 6601cb0ef41Sopenharmony_ci message = 'The input did not match the regular expression ' + 6611cb0ef41Sopenharmony_ci `${inspect(expected)}. Input:\n\n${inspect(str)}\n`; 6621cb0ef41Sopenharmony_ci } 6631cb0ef41Sopenharmony_ci throwError = true; 6641cb0ef41Sopenharmony_ci // Handle primitives properly. 6651cb0ef41Sopenharmony_ci } else if (typeof actual !== 'object' || actual === null) { 6661cb0ef41Sopenharmony_ci const err = new AssertionError({ 6671cb0ef41Sopenharmony_ci actual, 6681cb0ef41Sopenharmony_ci expected, 6691cb0ef41Sopenharmony_ci message, 6701cb0ef41Sopenharmony_ci operator: 'deepStrictEqual', 6711cb0ef41Sopenharmony_ci stackStartFn: fn, 6721cb0ef41Sopenharmony_ci }); 6731cb0ef41Sopenharmony_ci err.operator = fn.name; 6741cb0ef41Sopenharmony_ci throw err; 6751cb0ef41Sopenharmony_ci } else { 6761cb0ef41Sopenharmony_ci // Handle validation objects. 6771cb0ef41Sopenharmony_ci const keys = ObjectKeys(expected); 6781cb0ef41Sopenharmony_ci // Special handle errors to make sure the name and the message are 6791cb0ef41Sopenharmony_ci // compared as well. 6801cb0ef41Sopenharmony_ci if (expected instanceof Error) { 6811cb0ef41Sopenharmony_ci ArrayPrototypePush(keys, 'name', 'message'); 6821cb0ef41Sopenharmony_ci } else if (keys.length === 0) { 6831cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE('error', 6841cb0ef41Sopenharmony_ci expected, 'may not be an empty object'); 6851cb0ef41Sopenharmony_ci } 6861cb0ef41Sopenharmony_ci if (isDeepEqual === undefined) lazyLoadComparison(); 6871cb0ef41Sopenharmony_ci for (const key of keys) { 6881cb0ef41Sopenharmony_ci if (typeof actual[key] === 'string' && 6891cb0ef41Sopenharmony_ci isRegExp(expected[key]) && 6901cb0ef41Sopenharmony_ci RegExpPrototypeExec(expected[key], actual[key]) !== null) { 6911cb0ef41Sopenharmony_ci continue; 6921cb0ef41Sopenharmony_ci } 6931cb0ef41Sopenharmony_ci compareExceptionKey(actual, expected, key, message, keys, fn); 6941cb0ef41Sopenharmony_ci } 6951cb0ef41Sopenharmony_ci return; 6961cb0ef41Sopenharmony_ci } 6971cb0ef41Sopenharmony_ci // Guard instanceof against arrow functions as they don't have a prototype. 6981cb0ef41Sopenharmony_ci // Check for matching Error classes. 6991cb0ef41Sopenharmony_ci } else if (expected.prototype !== undefined && actual instanceof expected) { 7001cb0ef41Sopenharmony_ci return; 7011cb0ef41Sopenharmony_ci } else if (ObjectPrototypeIsPrototypeOf(Error, expected)) { 7021cb0ef41Sopenharmony_ci if (!message) { 7031cb0ef41Sopenharmony_ci generatedMessage = true; 7041cb0ef41Sopenharmony_ci message = 'The error is expected to be an instance of ' + 7051cb0ef41Sopenharmony_ci `"${expected.name}". Received `; 7061cb0ef41Sopenharmony_ci if (isError(actual)) { 7071cb0ef41Sopenharmony_ci const name = (actual.constructor && actual.constructor.name) || 7081cb0ef41Sopenharmony_ci actual.name; 7091cb0ef41Sopenharmony_ci if (expected.name === name) { 7101cb0ef41Sopenharmony_ci message += 'an error with identical name but a different prototype.'; 7111cb0ef41Sopenharmony_ci } else { 7121cb0ef41Sopenharmony_ci message += `"${name}"`; 7131cb0ef41Sopenharmony_ci } 7141cb0ef41Sopenharmony_ci if (actual.message) { 7151cb0ef41Sopenharmony_ci message += `\n\nError message:\n\n${actual.message}`; 7161cb0ef41Sopenharmony_ci } 7171cb0ef41Sopenharmony_ci } else { 7181cb0ef41Sopenharmony_ci message += `"${inspect(actual, { depth: -1 })}"`; 7191cb0ef41Sopenharmony_ci } 7201cb0ef41Sopenharmony_ci } 7211cb0ef41Sopenharmony_ci throwError = true; 7221cb0ef41Sopenharmony_ci } else { 7231cb0ef41Sopenharmony_ci // Check validation functions return value. 7241cb0ef41Sopenharmony_ci const res = ReflectApply(expected, {}, [actual]); 7251cb0ef41Sopenharmony_ci if (res !== true) { 7261cb0ef41Sopenharmony_ci if (!message) { 7271cb0ef41Sopenharmony_ci generatedMessage = true; 7281cb0ef41Sopenharmony_ci const name = expected.name ? `"${expected.name}" ` : ''; 7291cb0ef41Sopenharmony_ci message = `The ${name}validation function is expected to return` + 7301cb0ef41Sopenharmony_ci ` "true". Received ${inspect(res)}`; 7311cb0ef41Sopenharmony_ci 7321cb0ef41Sopenharmony_ci if (isError(actual)) { 7331cb0ef41Sopenharmony_ci message += `\n\nCaught error:\n\n${actual}`; 7341cb0ef41Sopenharmony_ci } 7351cb0ef41Sopenharmony_ci } 7361cb0ef41Sopenharmony_ci throwError = true; 7371cb0ef41Sopenharmony_ci } 7381cb0ef41Sopenharmony_ci } 7391cb0ef41Sopenharmony_ci 7401cb0ef41Sopenharmony_ci if (throwError) { 7411cb0ef41Sopenharmony_ci const err = new AssertionError({ 7421cb0ef41Sopenharmony_ci actual, 7431cb0ef41Sopenharmony_ci expected, 7441cb0ef41Sopenharmony_ci message, 7451cb0ef41Sopenharmony_ci operator: fn.name, 7461cb0ef41Sopenharmony_ci stackStartFn: fn, 7471cb0ef41Sopenharmony_ci }); 7481cb0ef41Sopenharmony_ci err.generatedMessage = generatedMessage; 7491cb0ef41Sopenharmony_ci throw err; 7501cb0ef41Sopenharmony_ci } 7511cb0ef41Sopenharmony_ci} 7521cb0ef41Sopenharmony_ci 7531cb0ef41Sopenharmony_cifunction getActual(fn) { 7541cb0ef41Sopenharmony_ci validateFunction(fn, 'fn'); 7551cb0ef41Sopenharmony_ci try { 7561cb0ef41Sopenharmony_ci fn(); 7571cb0ef41Sopenharmony_ci } catch (e) { 7581cb0ef41Sopenharmony_ci return e; 7591cb0ef41Sopenharmony_ci } 7601cb0ef41Sopenharmony_ci return NO_EXCEPTION_SENTINEL; 7611cb0ef41Sopenharmony_ci} 7621cb0ef41Sopenharmony_ci 7631cb0ef41Sopenharmony_cifunction checkIsPromise(obj) { 7641cb0ef41Sopenharmony_ci // Accept native ES6 promises and promises that are implemented in a similar 7651cb0ef41Sopenharmony_ci // way. Do not accept thenables that use a function as `obj` and that have no 7661cb0ef41Sopenharmony_ci // `catch` handler. 7671cb0ef41Sopenharmony_ci return isPromise(obj) || 7681cb0ef41Sopenharmony_ci (obj !== null && typeof obj === 'object' && 7691cb0ef41Sopenharmony_ci typeof obj.then === 'function' && 7701cb0ef41Sopenharmony_ci typeof obj.catch === 'function'); 7711cb0ef41Sopenharmony_ci} 7721cb0ef41Sopenharmony_ci 7731cb0ef41Sopenharmony_ciasync function waitForActual(promiseFn) { 7741cb0ef41Sopenharmony_ci let resultPromise; 7751cb0ef41Sopenharmony_ci if (typeof promiseFn === 'function') { 7761cb0ef41Sopenharmony_ci // Return a rejected promise if `promiseFn` throws synchronously. 7771cb0ef41Sopenharmony_ci resultPromise = promiseFn(); 7781cb0ef41Sopenharmony_ci // Fail in case no promise is returned. 7791cb0ef41Sopenharmony_ci if (!checkIsPromise(resultPromise)) { 7801cb0ef41Sopenharmony_ci throw new ERR_INVALID_RETURN_VALUE('instance of Promise', 7811cb0ef41Sopenharmony_ci 'promiseFn', resultPromise); 7821cb0ef41Sopenharmony_ci } 7831cb0ef41Sopenharmony_ci } else if (checkIsPromise(promiseFn)) { 7841cb0ef41Sopenharmony_ci resultPromise = promiseFn; 7851cb0ef41Sopenharmony_ci } else { 7861cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 7871cb0ef41Sopenharmony_ci 'promiseFn', ['Function', 'Promise'], promiseFn); 7881cb0ef41Sopenharmony_ci } 7891cb0ef41Sopenharmony_ci 7901cb0ef41Sopenharmony_ci try { 7911cb0ef41Sopenharmony_ci await resultPromise; 7921cb0ef41Sopenharmony_ci } catch (e) { 7931cb0ef41Sopenharmony_ci return e; 7941cb0ef41Sopenharmony_ci } 7951cb0ef41Sopenharmony_ci return NO_EXCEPTION_SENTINEL; 7961cb0ef41Sopenharmony_ci} 7971cb0ef41Sopenharmony_ci 7981cb0ef41Sopenharmony_cifunction expectsError(stackStartFn, actual, error, message) { 7991cb0ef41Sopenharmony_ci if (typeof error === 'string') { 8001cb0ef41Sopenharmony_ci if (arguments.length === 4) { 8011cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE('error', 8021cb0ef41Sopenharmony_ci ['Object', 'Error', 'Function', 'RegExp'], 8031cb0ef41Sopenharmony_ci error); 8041cb0ef41Sopenharmony_ci } 8051cb0ef41Sopenharmony_ci if (typeof actual === 'object' && actual !== null) { 8061cb0ef41Sopenharmony_ci if (actual.message === error) { 8071cb0ef41Sopenharmony_ci throw new ERR_AMBIGUOUS_ARGUMENT( 8081cb0ef41Sopenharmony_ci 'error/message', 8091cb0ef41Sopenharmony_ci `The error message "${actual.message}" is identical to the message.`, 8101cb0ef41Sopenharmony_ci ); 8111cb0ef41Sopenharmony_ci } 8121cb0ef41Sopenharmony_ci } else if (actual === error) { 8131cb0ef41Sopenharmony_ci throw new ERR_AMBIGUOUS_ARGUMENT( 8141cb0ef41Sopenharmony_ci 'error/message', 8151cb0ef41Sopenharmony_ci `The error "${actual}" is identical to the message.`, 8161cb0ef41Sopenharmony_ci ); 8171cb0ef41Sopenharmony_ci } 8181cb0ef41Sopenharmony_ci message = error; 8191cb0ef41Sopenharmony_ci error = undefined; 8201cb0ef41Sopenharmony_ci } else if (error != null && 8211cb0ef41Sopenharmony_ci typeof error !== 'object' && 8221cb0ef41Sopenharmony_ci typeof error !== 'function') { 8231cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE('error', 8241cb0ef41Sopenharmony_ci ['Object', 'Error', 'Function', 'RegExp'], 8251cb0ef41Sopenharmony_ci error); 8261cb0ef41Sopenharmony_ci } 8271cb0ef41Sopenharmony_ci 8281cb0ef41Sopenharmony_ci if (actual === NO_EXCEPTION_SENTINEL) { 8291cb0ef41Sopenharmony_ci let details = ''; 8301cb0ef41Sopenharmony_ci if (error && error.name) { 8311cb0ef41Sopenharmony_ci details += ` (${error.name})`; 8321cb0ef41Sopenharmony_ci } 8331cb0ef41Sopenharmony_ci details += message ? `: ${message}` : '.'; 8341cb0ef41Sopenharmony_ci const fnType = stackStartFn === assert.rejects ? 'rejection' : 'exception'; 8351cb0ef41Sopenharmony_ci innerFail({ 8361cb0ef41Sopenharmony_ci actual: undefined, 8371cb0ef41Sopenharmony_ci expected: error, 8381cb0ef41Sopenharmony_ci operator: stackStartFn.name, 8391cb0ef41Sopenharmony_ci message: `Missing expected ${fnType}${details}`, 8401cb0ef41Sopenharmony_ci stackStartFn, 8411cb0ef41Sopenharmony_ci }); 8421cb0ef41Sopenharmony_ci } 8431cb0ef41Sopenharmony_ci 8441cb0ef41Sopenharmony_ci if (!error) 8451cb0ef41Sopenharmony_ci return; 8461cb0ef41Sopenharmony_ci 8471cb0ef41Sopenharmony_ci expectedException(actual, error, message, stackStartFn); 8481cb0ef41Sopenharmony_ci} 8491cb0ef41Sopenharmony_ci 8501cb0ef41Sopenharmony_cifunction hasMatchingError(actual, expected) { 8511cb0ef41Sopenharmony_ci if (typeof expected !== 'function') { 8521cb0ef41Sopenharmony_ci if (isRegExp(expected)) { 8531cb0ef41Sopenharmony_ci const str = String(actual); 8541cb0ef41Sopenharmony_ci return RegExpPrototypeExec(expected, str) !== null; 8551cb0ef41Sopenharmony_ci } 8561cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 8571cb0ef41Sopenharmony_ci 'expected', ['Function', 'RegExp'], expected, 8581cb0ef41Sopenharmony_ci ); 8591cb0ef41Sopenharmony_ci } 8601cb0ef41Sopenharmony_ci // Guard instanceof against arrow functions as they don't have a prototype. 8611cb0ef41Sopenharmony_ci if (expected.prototype !== undefined && actual instanceof expected) { 8621cb0ef41Sopenharmony_ci return true; 8631cb0ef41Sopenharmony_ci } 8641cb0ef41Sopenharmony_ci if (ObjectPrototypeIsPrototypeOf(Error, expected)) { 8651cb0ef41Sopenharmony_ci return false; 8661cb0ef41Sopenharmony_ci } 8671cb0ef41Sopenharmony_ci return ReflectApply(expected, {}, [actual]) === true; 8681cb0ef41Sopenharmony_ci} 8691cb0ef41Sopenharmony_ci 8701cb0ef41Sopenharmony_cifunction expectsNoError(stackStartFn, actual, error, message) { 8711cb0ef41Sopenharmony_ci if (actual === NO_EXCEPTION_SENTINEL) 8721cb0ef41Sopenharmony_ci return; 8731cb0ef41Sopenharmony_ci 8741cb0ef41Sopenharmony_ci if (typeof error === 'string') { 8751cb0ef41Sopenharmony_ci message = error; 8761cb0ef41Sopenharmony_ci error = undefined; 8771cb0ef41Sopenharmony_ci } 8781cb0ef41Sopenharmony_ci 8791cb0ef41Sopenharmony_ci if (!error || hasMatchingError(actual, error)) { 8801cb0ef41Sopenharmony_ci const details = message ? `: ${message}` : '.'; 8811cb0ef41Sopenharmony_ci const fnType = stackStartFn === assert.doesNotReject ? 8821cb0ef41Sopenharmony_ci 'rejection' : 'exception'; 8831cb0ef41Sopenharmony_ci innerFail({ 8841cb0ef41Sopenharmony_ci actual, 8851cb0ef41Sopenharmony_ci expected: error, 8861cb0ef41Sopenharmony_ci operator: stackStartFn.name, 8871cb0ef41Sopenharmony_ci message: `Got unwanted ${fnType}${details}\n` + 8881cb0ef41Sopenharmony_ci `Actual message: "${actual && actual.message}"`, 8891cb0ef41Sopenharmony_ci stackStartFn, 8901cb0ef41Sopenharmony_ci }); 8911cb0ef41Sopenharmony_ci } 8921cb0ef41Sopenharmony_ci throw actual; 8931cb0ef41Sopenharmony_ci} 8941cb0ef41Sopenharmony_ci 8951cb0ef41Sopenharmony_ci/** 8961cb0ef41Sopenharmony_ci * Expects the function `promiseFn` to throw an error. 8971cb0ef41Sopenharmony_ci * @param {() => any} promiseFn 8981cb0ef41Sopenharmony_ci * @param {...any} [args] 8991cb0ef41Sopenharmony_ci * @returns {void} 9001cb0ef41Sopenharmony_ci */ 9011cb0ef41Sopenharmony_ciassert.throws = function throws(promiseFn, ...args) { 9021cb0ef41Sopenharmony_ci expectsError(throws, getActual(promiseFn), ...args); 9031cb0ef41Sopenharmony_ci}; 9041cb0ef41Sopenharmony_ci 9051cb0ef41Sopenharmony_ci/** 9061cb0ef41Sopenharmony_ci * Expects `promiseFn` function or its value to reject. 9071cb0ef41Sopenharmony_ci * @param {() => Promise<any>} promiseFn 9081cb0ef41Sopenharmony_ci * @param {...any} [args] 9091cb0ef41Sopenharmony_ci * @returns {Promise<void>} 9101cb0ef41Sopenharmony_ci */ 9111cb0ef41Sopenharmony_ciassert.rejects = async function rejects(promiseFn, ...args) { 9121cb0ef41Sopenharmony_ci expectsError(rejects, await waitForActual(promiseFn), ...args); 9131cb0ef41Sopenharmony_ci}; 9141cb0ef41Sopenharmony_ci 9151cb0ef41Sopenharmony_ci/** 9161cb0ef41Sopenharmony_ci * Asserts that the function `fn` does not throw an error. 9171cb0ef41Sopenharmony_ci * @param {() => any} fn 9181cb0ef41Sopenharmony_ci * @param {...any} [args] 9191cb0ef41Sopenharmony_ci * @returns {void} 9201cb0ef41Sopenharmony_ci */ 9211cb0ef41Sopenharmony_ciassert.doesNotThrow = function doesNotThrow(fn, ...args) { 9221cb0ef41Sopenharmony_ci expectsNoError(doesNotThrow, getActual(fn), ...args); 9231cb0ef41Sopenharmony_ci}; 9241cb0ef41Sopenharmony_ci 9251cb0ef41Sopenharmony_ci/** 9261cb0ef41Sopenharmony_ci * Expects `fn` or its value to not reject. 9271cb0ef41Sopenharmony_ci * @param {() => Promise<any>} fn 9281cb0ef41Sopenharmony_ci * @param {...any} [args] 9291cb0ef41Sopenharmony_ci * @returns {Promise<void>} 9301cb0ef41Sopenharmony_ci */ 9311cb0ef41Sopenharmony_ciassert.doesNotReject = async function doesNotReject(fn, ...args) { 9321cb0ef41Sopenharmony_ci expectsNoError(doesNotReject, await waitForActual(fn), ...args); 9331cb0ef41Sopenharmony_ci}; 9341cb0ef41Sopenharmony_ci 9351cb0ef41Sopenharmony_ci/** 9361cb0ef41Sopenharmony_ci * Throws `value` if the value is not `null` or `undefined`. 9371cb0ef41Sopenharmony_ci * @param {any} err 9381cb0ef41Sopenharmony_ci * @returns {void} 9391cb0ef41Sopenharmony_ci */ 9401cb0ef41Sopenharmony_ciassert.ifError = function ifError(err) { 9411cb0ef41Sopenharmony_ci if (err !== null && err !== undefined) { 9421cb0ef41Sopenharmony_ci let message = 'ifError got unwanted exception: '; 9431cb0ef41Sopenharmony_ci if (typeof err === 'object' && typeof err.message === 'string') { 9441cb0ef41Sopenharmony_ci if (err.message.length === 0 && err.constructor) { 9451cb0ef41Sopenharmony_ci message += err.constructor.name; 9461cb0ef41Sopenharmony_ci } else { 9471cb0ef41Sopenharmony_ci message += err.message; 9481cb0ef41Sopenharmony_ci } 9491cb0ef41Sopenharmony_ci } else { 9501cb0ef41Sopenharmony_ci message += inspect(err); 9511cb0ef41Sopenharmony_ci } 9521cb0ef41Sopenharmony_ci 9531cb0ef41Sopenharmony_ci const newErr = new AssertionError({ 9541cb0ef41Sopenharmony_ci actual: err, 9551cb0ef41Sopenharmony_ci expected: null, 9561cb0ef41Sopenharmony_ci operator: 'ifError', 9571cb0ef41Sopenharmony_ci message, 9581cb0ef41Sopenharmony_ci stackStartFn: ifError, 9591cb0ef41Sopenharmony_ci }); 9601cb0ef41Sopenharmony_ci 9611cb0ef41Sopenharmony_ci // Make sure we actually have a stack trace! 9621cb0ef41Sopenharmony_ci const origStack = err.stack; 9631cb0ef41Sopenharmony_ci 9641cb0ef41Sopenharmony_ci if (typeof origStack === 'string') { 9651cb0ef41Sopenharmony_ci // This will remove any duplicated frames from the error frames taken 9661cb0ef41Sopenharmony_ci // from within `ifError` and add the original error frames to the newly 9671cb0ef41Sopenharmony_ci // created ones. 9681cb0ef41Sopenharmony_ci const origStackStart = StringPrototypeIndexOf(origStack, '\n at'); 9691cb0ef41Sopenharmony_ci if (origStackStart !== -1) { 9701cb0ef41Sopenharmony_ci const originalFrames = StringPrototypeSplit( 9711cb0ef41Sopenharmony_ci StringPrototypeSlice(origStack, origStackStart + 1), 9721cb0ef41Sopenharmony_ci '\n', 9731cb0ef41Sopenharmony_ci ); 9741cb0ef41Sopenharmony_ci // Filter all frames existing in err.stack. 9751cb0ef41Sopenharmony_ci let newFrames = StringPrototypeSplit(newErr.stack, '\n'); 9761cb0ef41Sopenharmony_ci for (const errFrame of originalFrames) { 9771cb0ef41Sopenharmony_ci // Find the first occurrence of the frame. 9781cb0ef41Sopenharmony_ci const pos = ArrayPrototypeIndexOf(newFrames, errFrame); 9791cb0ef41Sopenharmony_ci if (pos !== -1) { 9801cb0ef41Sopenharmony_ci // Only keep new frames. 9811cb0ef41Sopenharmony_ci newFrames = ArrayPrototypeSlice(newFrames, 0, pos); 9821cb0ef41Sopenharmony_ci break; 9831cb0ef41Sopenharmony_ci } 9841cb0ef41Sopenharmony_ci } 9851cb0ef41Sopenharmony_ci const stackStart = ArrayPrototypeJoin(newFrames, '\n'); 9861cb0ef41Sopenharmony_ci const stackEnd = ArrayPrototypeJoin(originalFrames, '\n'); 9871cb0ef41Sopenharmony_ci newErr.stack = `${stackStart}\n${stackEnd}`; 9881cb0ef41Sopenharmony_ci } 9891cb0ef41Sopenharmony_ci } 9901cb0ef41Sopenharmony_ci 9911cb0ef41Sopenharmony_ci throw newErr; 9921cb0ef41Sopenharmony_ci } 9931cb0ef41Sopenharmony_ci}; 9941cb0ef41Sopenharmony_ci 9951cb0ef41Sopenharmony_cifunction internalMatch(string, regexp, message, fn) { 9961cb0ef41Sopenharmony_ci if (!isRegExp(regexp)) { 9971cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 9981cb0ef41Sopenharmony_ci 'regexp', 'RegExp', regexp, 9991cb0ef41Sopenharmony_ci ); 10001cb0ef41Sopenharmony_ci } 10011cb0ef41Sopenharmony_ci const match = fn === assert.match; 10021cb0ef41Sopenharmony_ci if (typeof string !== 'string' || 10031cb0ef41Sopenharmony_ci RegExpPrototypeExec(regexp, string) !== null !== match) { 10041cb0ef41Sopenharmony_ci if (message instanceof Error) { 10051cb0ef41Sopenharmony_ci throw message; 10061cb0ef41Sopenharmony_ci } 10071cb0ef41Sopenharmony_ci 10081cb0ef41Sopenharmony_ci const generatedMessage = !message; 10091cb0ef41Sopenharmony_ci 10101cb0ef41Sopenharmony_ci // 'The input was expected to not match the regular expression ' + 10111cb0ef41Sopenharmony_ci message = message || (typeof string !== 'string' ? 10121cb0ef41Sopenharmony_ci 'The "string" argument must be of type string. Received type ' + 10131cb0ef41Sopenharmony_ci `${typeof string} (${inspect(string)})` : 10141cb0ef41Sopenharmony_ci (match ? 10151cb0ef41Sopenharmony_ci 'The input did not match the regular expression ' : 10161cb0ef41Sopenharmony_ci 'The input was expected to not match the regular expression ') + 10171cb0ef41Sopenharmony_ci `${inspect(regexp)}. Input:\n\n${inspect(string)}\n`); 10181cb0ef41Sopenharmony_ci const err = new AssertionError({ 10191cb0ef41Sopenharmony_ci actual: string, 10201cb0ef41Sopenharmony_ci expected: regexp, 10211cb0ef41Sopenharmony_ci message, 10221cb0ef41Sopenharmony_ci operator: fn.name, 10231cb0ef41Sopenharmony_ci stackStartFn: fn, 10241cb0ef41Sopenharmony_ci }); 10251cb0ef41Sopenharmony_ci err.generatedMessage = generatedMessage; 10261cb0ef41Sopenharmony_ci throw err; 10271cb0ef41Sopenharmony_ci } 10281cb0ef41Sopenharmony_ci} 10291cb0ef41Sopenharmony_ci 10301cb0ef41Sopenharmony_ci/** 10311cb0ef41Sopenharmony_ci * Expects the `string` input to match the regular expression. 10321cb0ef41Sopenharmony_ci * @param {string} string 10331cb0ef41Sopenharmony_ci * @param {RegExp} regexp 10341cb0ef41Sopenharmony_ci * @param {string | Error} [message] 10351cb0ef41Sopenharmony_ci * @returns {void} 10361cb0ef41Sopenharmony_ci */ 10371cb0ef41Sopenharmony_ciassert.match = function match(string, regexp, message) { 10381cb0ef41Sopenharmony_ci internalMatch(string, regexp, message, match); 10391cb0ef41Sopenharmony_ci}; 10401cb0ef41Sopenharmony_ci 10411cb0ef41Sopenharmony_ci/** 10421cb0ef41Sopenharmony_ci * Expects the `string` input not to match the regular expression. 10431cb0ef41Sopenharmony_ci * @param {string} string 10441cb0ef41Sopenharmony_ci * @param {RegExp} regexp 10451cb0ef41Sopenharmony_ci * @param {string | Error} [message] 10461cb0ef41Sopenharmony_ci * @returns {void} 10471cb0ef41Sopenharmony_ci */ 10481cb0ef41Sopenharmony_ciassert.doesNotMatch = function doesNotMatch(string, regexp, message) { 10491cb0ef41Sopenharmony_ci internalMatch(string, regexp, message, doesNotMatch); 10501cb0ef41Sopenharmony_ci}; 10511cb0ef41Sopenharmony_ci 10521cb0ef41Sopenharmony_ciassert.CallTracker = CallTracker; 10531cb0ef41Sopenharmony_ci 10541cb0ef41Sopenharmony_ci/** 10551cb0ef41Sopenharmony_ci * Expose a strict only variant of assert. 10561cb0ef41Sopenharmony_ci * @param {...any} args 10571cb0ef41Sopenharmony_ci * @returns {void} 10581cb0ef41Sopenharmony_ci */ 10591cb0ef41Sopenharmony_cifunction strict(...args) { 10601cb0ef41Sopenharmony_ci innerOk(strict, args.length, ...args); 10611cb0ef41Sopenharmony_ci} 10621cb0ef41Sopenharmony_ci 10631cb0ef41Sopenharmony_ciassert.strict = ObjectAssign(strict, assert, { 10641cb0ef41Sopenharmony_ci equal: assert.strictEqual, 10651cb0ef41Sopenharmony_ci deepEqual: assert.deepStrictEqual, 10661cb0ef41Sopenharmony_ci notEqual: assert.notStrictEqual, 10671cb0ef41Sopenharmony_ci notDeepEqual: assert.notDeepStrictEqual, 10681cb0ef41Sopenharmony_ci}); 10691cb0ef41Sopenharmony_ci 10701cb0ef41Sopenharmony_ciassert.strict.strict = assert.strict; 1071