// deno-fmt-ignore-file // deno-lint-ignore-file // Copyright Joyent and Node contributors. All rights reserved. MIT license. // Taken from Node 15.5.1 // This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually // Flags: --expose-internals // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; const common = require('../common'); const assert = require('assert'); const { inspect } = require('util'); // TODO(kt3k): Enable these when "vm" is ready. // const vm = require('vm'); // TODO(kt3k): Enable these when "internal/test/binding" is ready. // const { internalBinding } = require('internal/test/binding'); const a = assert; // Disable colored output to prevent color codes from breaking assertion // message comparisons. This should only be an issue when process.stdout // is a TTY. if (process.stdout.isTTY) process.env.NODE_DISABLE_COLORS = '1'; const strictEqualMessageStart = 'Expected values to be strictly equal:\n'; const start = 'Expected values to be strictly deep-equal:'; const actExp = '+ actual - expected'; assert.ok(a.AssertionError.prototype instanceof Error, 'a.AssertionError instanceof Error'); assert.throws(() => a(false), a.AssertionError, 'ok(false)'); assert.throws(() => a.ok(false), a.AssertionError, 'ok(false)'); // Throw message if the message is instanceof Error. { let threw = false; try { assert.ok(false, new Error('ok(false)')); } catch (e) { threw = true; assert.ok(e instanceof Error); } assert.ok(threw, 'Error: ok(false)'); } a(true); a('test', 'ok(\'test\')'); a.ok(true); a.ok('test'); assert.throws(() => a.equal(true, false), a.AssertionError, 'equal(true, false)'); a.equal(null, null); a.equal(undefined, undefined); a.equal(null, undefined); a.equal(true, true); a.equal(2, '2'); a.notEqual(true, false); assert.throws(() => a.notEqual(true, true), a.AssertionError, 'notEqual(true, true)'); assert.throws(() => a.strictEqual(2, '2'), a.AssertionError, 'strictEqual(2, \'2\')'); assert.throws(() => a.strictEqual(null, undefined), a.AssertionError, 'strictEqual(null, undefined)'); assert.throws( () => a.notStrictEqual(2, 2), { message: 'Expected "actual" to be strictly unequal to: 2\n', name: 'AssertionError' } ); assert.throws( () => a.notStrictEqual('a '.repeat(30), 'a '.repeat(30)), { message: 'Expected "actual" to be strictly unequal to: ' + `"${'a '.repeat(30)}"\n`, name: 'AssertionError' } ); assert.throws( () => a.notEqual(1, 1), { message: '1 != 1', operator: '!=' } ); a.notStrictEqual(2, '2'); // Testing the throwing. function thrower(errorConstructor) { throw new errorConstructor({}); } // The basic calls work. assert.throws(() => thrower(a.AssertionError), a.AssertionError, 'message'); assert.throws(() => thrower(a.AssertionError), a.AssertionError); assert.throws(() => thrower(a.AssertionError)); // If not passing an error, catch all. assert.throws(() => thrower(TypeError)); // When passing a type, only catch errors of the appropriate type. assert.throws( () => a.throws(() => thrower(TypeError), a.AssertionError), { // generatedMessage: true, // actual: new TypeError({}), expected: a.AssertionError, code: 'ERR_ASSERTION', name: 'AssertionError', operator: 'throws', message: 'The error is expected to be an instance of "AssertionError". ' + 'Received "TypeError"\n\nError message:\n\n[object Object]' } ); // doesNotThrow should pass through all errors. { let threw = false; try { a.doesNotThrow(() => thrower(TypeError), a.AssertionError); } catch (e) { threw = true; assert.ok(e instanceof TypeError); } assert(threw, 'a.doesNotThrow with an explicit error is eating extra errors'); } // Key difference is that throwing our correct error makes an assertion error. { let threw = false; try { a.doesNotThrow(() => thrower(TypeError), TypeError); } catch (e) { threw = true; assert.ok(e instanceof a.AssertionError); // Commented out the following assertion // assert.ok(!e.stack.includes('at Function.doesNotThrow')); } assert.ok(threw, 'a.doesNotThrow is not catching type matching errors'); } assert.throws( () => a.doesNotThrow(() => thrower(Error), 'user message'), { name: 'AssertionError', code: 'ERR_ASSERTION', operator: 'doesNotThrow', message: 'Got unwanted exception: user message\n' + 'Actual message: "[object Object]"' } ); assert.throws( () => a.doesNotThrow(() => thrower(Error)), { code: 'ERR_ASSERTION', message: 'Got unwanted exception.\nActual message: "[object Object]"' } ); assert.throws( () => a.doesNotThrow(() => thrower(Error), /\[[a-z]{6}\s[A-z]{6}\]/g, 'user message'), { name: 'AssertionError', code: 'ERR_ASSERTION', operator: 'doesNotThrow', message: 'Got unwanted exception: user message\n' + 'Actual message: "[object Object]"' } ); // Make sure that validating using constructor really works. { let threw = false; try { assert.throws( () => { throw ({}); }, Array ); } catch { threw = true; } assert.ok(threw, 'wrong constructor validation'); } // Use a RegExp to validate the error message. { a.throws(() => thrower(TypeError), /\[object Object\]/); const symbol = Symbol('foo'); a.throws(() => { throw symbol; }, /foo/); a.throws(() => { a.throws(() => { throw symbol; }, /abc/); }, { message: 'The input did not match the regular expression /abc/. ' + "Input:\n\n'Symbol(foo)'\n", code: 'ERR_ASSERTION', operator: 'throws', actual: symbol, expected: /abc/ }); } // Use a fn to validate the error object. a.throws(() => thrower(TypeError), (err) => { if ((err instanceof TypeError) && /\[object Object\]/.test(err)) { return true; } }); // https://github.com/nodejs/node/issues/3188 { let actual; assert.throws( () => { const ES6Error = class extends Error {}; const AnotherErrorType = class extends Error {}; assert.throws(() => { actual = new AnotherErrorType('foo'); throw actual; }, ES6Error); }, (err) => { assert.strictEqual( err.message, 'The error is expected to be an instance of "ES6Error". ' + 'Received "AnotherErrorType"\n\nError message:\n\nfoo' ); assert.strictEqual(err.actual, actual); return true; } ); } // Check messages from assert.throws(). { const noop = () => {}; assert.throws( () => { a.throws((noop)); }, { code: 'ERR_ASSERTION', message: 'Missing expected exception.', operator: 'throws', actual: undefined, expected: undefined }); assert.throws( () => { a.throws(noop, TypeError); }, { code: 'ERR_ASSERTION', message: 'Missing expected exception (TypeError).', actual: undefined, expected: TypeError }); assert.throws( () => { a.throws(noop, 'fhqwhgads'); }, { code: 'ERR_ASSERTION', message: 'Missing expected exception: fhqwhgads', actual: undefined, expected: undefined }); assert.throws( () => { a.throws(noop, TypeError, 'fhqwhgads'); }, { code: 'ERR_ASSERTION', message: 'Missing expected exception (TypeError): fhqwhgads', actual: undefined, expected: TypeError }); let threw = false; try { a.throws(noop); } catch (e) { threw = true; assert.ok(e instanceof a.AssertionError); // TODO(kt3k): enable this assertion // assert.ok(!e.stack.includes('at Function.throws')); } assert.ok(threw); } const circular = { y: 1 }; circular.x = circular; function testAssertionMessage(actual, expected, msg) { assert.throws( () => assert.strictEqual(actual, ''), { generatedMessage: true, message: msg || strictEqualMessageStart + `+ actual - expected\n\n+ ${expected}\n- ''` } ); } function testShortAssertionMessage(actual, expected) { testAssertionMessage(actual, expected, strictEqualMessageStart + `\n${inspect(actual)} !== ''\n`); } // TODO(kt3k): Do we need completely simulate // Node.js assertion error messages? /* testShortAssertionMessage(null, 'null'); testShortAssertionMessage(true, 'true'); testShortAssertionMessage(false, 'false'); testShortAssertionMessage(100, '100'); testShortAssertionMessage(NaN, 'NaN'); testShortAssertionMessage(Infinity, 'Infinity'); testShortAssertionMessage('a', '"a"'); testShortAssertionMessage('foo', '\'foo\''); testShortAssertionMessage(0, '0'); testShortAssertionMessage(Symbol(), 'Symbol()'); testShortAssertionMessage(undefined, 'undefined'); testShortAssertionMessage(-Infinity, '-Infinity'); testAssertionMessage([], '[]'); testAssertionMessage(/a/, '/a/'); testAssertionMessage(/abc/gim, '/abc/gim'); testAssertionMessage({}, '{}'); testAssertionMessage([1, 2, 3], '[\n+ 1,\n+ 2,\n+ 3\n+ ]'); testAssertionMessage(function f() {}, '[Function: f]'); testAssertionMessage(function() {}, '[Function (anonymous)]'); testAssertionMessage(circular, ' {\n+ x: [Circular *1],\n+ y: 1\n+ }'); testAssertionMessage({ a: undefined, b: null }, '{\n+ a: undefined,\n+ b: null\n+ }'); testAssertionMessage({ a: NaN, b: Infinity, c: -Infinity }, '{\n+ a: NaN,\n+ b: Infinity,\n+ c: -Infinity\n+ }'); */ // https://github.com/nodejs/node-v0.x-archive/issues/5292 assert.throws( () => assert.strictEqual(1, 2), /* Memo: Disabled this object assertion { message: `${strictEqualMessageStart}\n1 !== 2\n`, generatedMessage: true } */ ); assert.throws( () => assert.strictEqual(1, 2, 'oh no'), { message: 'oh no', generatedMessage: false } ); { let threw = false; const rangeError = new RangeError('my range'); // Verify custom errors. try { assert.strictEqual(1, 2, rangeError); } catch (e) { assert.strictEqual(e, rangeError); threw = true; assert.ok(e instanceof RangeError, 'Incorrect error type thrown'); } assert.ok(threw); threw = false; // Verify AssertionError is the result from doesNotThrow with custom Error. try { a.doesNotThrow(() => { throw new TypeError('wrong type'); }, TypeError, rangeError); } catch (e) { threw = true; assert.ok(e.message.includes(rangeError.message)); assert.ok(e instanceof assert.AssertionError); // TODO(kt3k): Enable this assertion // assert.ok(!e.stack.includes('doesNotThrow'), e); } assert.ok(threw); } { // Verify that throws() and doesNotThrow() throw on non-functions. const testBlockTypeError = (method, fn) => { assert.throws( () => method(fn), { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', message: 'The "fn" argument must be of type function.' + common.invalidArgTypeHelper(fn) } ); }; testBlockTypeError(assert.throws, 'string'); testBlockTypeError(assert.doesNotThrow, 'string'); testBlockTypeError(assert.throws, 1); testBlockTypeError(assert.doesNotThrow, 1); testBlockTypeError(assert.throws, true); testBlockTypeError(assert.doesNotThrow, true); testBlockTypeError(assert.throws, false); testBlockTypeError(assert.doesNotThrow, false); testBlockTypeError(assert.throws, []); testBlockTypeError(assert.doesNotThrow, []); testBlockTypeError(assert.throws, {}); testBlockTypeError(assert.doesNotThrow, {}); testBlockTypeError(assert.throws, /foo/); testBlockTypeError(assert.doesNotThrow, /foo/); testBlockTypeError(assert.throws, null); testBlockTypeError(assert.doesNotThrow, null); testBlockTypeError(assert.throws, undefined); testBlockTypeError(assert.doesNotThrow, undefined); } // https://github.com/nodejs/node/issues/3275 assert.throws(() => { throw 'error'; }, (err) => err === 'error'); assert.throws(() => { throw new Error(); }, (err) => err instanceof Error); // Long values should be truncated for display. assert.throws(() => { assert.strictEqual('A'.repeat(1000), ''); }, (err) => { assert.strictEqual(err.code, 'ERR_ASSERTION'); /* TODO(kt3k): Enable this assertion assert.strictEqual(err.message, `${strictEqualMessageStart}+ actual - expected\n\n` + `+ '${'A'.repeat(1000)}'\n- ''`); */ assert.strictEqual(err.actual.length, 1000); // TODO(kt3k): Enable this after fixing 'inspect' // assert.ok(inspect(err).includes(`actual: '${'A'.repeat(488)}...'`)); return true; }); // Output that extends beyond 10 lines should also be truncated for display. { const multilineString = 'fhqwhgads\n'.repeat(15); assert.throws(() => { assert.strictEqual(multilineString, ''); }, (err) => { assert.strictEqual(err.code, 'ERR_ASSERTION'); // TODO(kt3k): Enable these assertion when the strictEqual message is aligned // to Node.js API. // assert.strictEqual(err.message.split('\n').length, 19); assert.strictEqual(err.actual.split('\n').length, 16); // TODO(kt3k): inspect(err) causes Maximum call stack error. /* assert.ok(inspect(err).includes( "actual: 'fhqwhgads\\n' +\n" + " 'fhqwhgads\\n' +\n".repeat(9) + " '...'")); */ return true; }); } { // Bad args to AssertionError constructor should throw TypeError. const args = [1, true, false, '', null, Infinity, Symbol('test'), undefined]; args.forEach((input) => { assert.throws( () => new assert.AssertionError(input), { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', message: 'The "options" argument must be of type object.' + common.invalidArgTypeHelper(input) }); }); } assert.throws( () => assert.strictEqual(new Error('foo'), new Error('foobar')), { code: 'ERR_ASSERTION', name: 'AssertionError', /* TODO(kt3k): Enable this assertion when the assertion error message is fixed. message: 'Expected "actual" to be reference-equal to "expected":\n' + '+ actual - expected\n\n' + '+ [Error: foo]\n- [Error: foobar]' */ } ); a.equal(NaN, NaN); a.throws( () => a.notEqual(NaN, NaN), a.AssertionError ); // Test strict assert. { const a = require('assert'); const assert = require('assert').strict; assert.throws(() => assert.equal(1, true), assert.AssertionError); assert.notEqual(0, false); assert.throws(() => assert.deepEqual(1, true), assert.AssertionError); assert.notDeepEqual(0, false); assert.equal(assert.strict, assert.strict.strict); assert.equal(assert.equal, assert.strictEqual); assert.equal(assert.deepEqual, assert.deepStrictEqual); assert.equal(assert.notEqual, assert.notStrictEqual); assert.equal(assert.notDeepEqual, assert.notDeepStrictEqual); assert.equal(Object.keys(assert).length, Object.keys(a).length); assert(7); assert.throws( () => assert(...[]), { message: 'No value argument passed to `assert.ok()`', name: 'AssertionError', // TODO(kt3k): Enable this // generatedMessage: true } ); assert.throws( () => a(), { message: 'No value argument passed to `assert.ok()`', name: 'AssertionError' } ); // Test setting the limit to zero and that assert.strict works properly. const tmpLimit = Error.stackTraceLimit; Error.stackTraceLimit = 0; assert.throws( () => { assert.ok( typeof 123 === 'string' ); }, { code: 'ERR_ASSERTION', constructor: assert.AssertionError, /* TODO(kt3k): Enable this assertion message: 'The expression evaluated to a falsy value:\n\n ' + "assert.ok(\n typeof 123 === 'string'\n )\n" */ } ); Error.stackTraceLimit = tmpLimit; // Test error diffs. let message = [ start, `${actExp} ... Lines skipped`, '', ' [', ' [', ' [', ' 1,', ' 2,', '+ 3', "- '3'", ' ]', '...', ' 4,', ' 5', ' ]'].join('\n'); assert.throws( () => assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]), /* TODO(kt3k): Enable this assertion { message } */ ); message = [ start, `${actExp} ... Lines skipped`, '', ' [', ' 1,', '...', ' 1,', ' 0,', '- 1,', ' 1,', '...', ' 1,', ' 1', ' ]' ].join('\n'); assert.throws( () => assert.deepEqual( [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1]), /* TODO(kt3k): Enable this assertion { message } */ ); message = [ start, `${actExp} ... Lines skipped`, '', ' [', ' 1,', '...', ' 1,', ' 0,', '+ 1,', ' 1,', ' 1,', ' 1', ' ]' ].join('\n'); assert.throws( () => assert.deepEqual( [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1]), /* TODO(kt3k): Enable this assertion { message } */ ); message = [ start, actExp, '', ' [', ' 1,', '+ 2,', '- 1,', ' 1,', ' 1,', ' 0,', '+ 1,', ' 1', ' ]' ].join('\n'); assert.throws( () => assert.deepEqual( [1, 2, 1, 1, 0, 1, 1], [1, 1, 1, 1, 0, 1]), /* TODO(kt3k): Enable this assertion { message } */ ); message = [ start, actExp, '', '+ [', '+ 1,', '+ 2,', '+ 1', '+ ]', '- undefined', ].join('\n'); assert.throws( () => assert.deepEqual([1, 2, 1], undefined), /* TODO(kt3k): Enable this assertion { message } */ ); message = [ start, actExp, '', ' [', '+ 1,', ' 2,', ' 1', ' ]' ].join('\n'); assert.throws( () => assert.deepEqual([1, 2, 1], [2, 1]), /* TODO(kt3k): Enable this assertion { message } */ ); message = `${start}\n` + `${actExp} ... Lines skipped\n` + '\n' + ' [\n' + '+ 1,\n'.repeat(25) + '...\n' + '- 2,\n'.repeat(25) + '...'; assert.throws( () => assert.deepEqual(Array(28).fill(1), Array(28).fill(2)), /* TODO(kt3k): Enable this assertion { message } */ ); const obj1 = {}; const obj2 = { loop: 'forever' }; obj2[inspect.custom] = () => '{}'; // No infinite loop and no custom inspect. assert.throws(() => assert.deepEqual(obj1, obj2), { code: "ERR_ASSERTION", /* TODO(kt3k): Enable this assertion message: `${start}\n` + `${actExp}\n` + '\n' + '+ {}\n' + '- {\n' + '- [Symbol(nodejs.util.inspect.custom)]: [Function (anonymous)],\n' + "- loop: 'forever'\n" + '- }' */ }); // notDeepEqual tests assert.throws( () => assert.notDeepEqual([1], [1]), { code: "ERR_ASSERTION", /* TODO(kt3k): Enable this assertion message: 'Expected "actual" not to be strictly deep-equal to:\n\n' + '[\n 1\n]\n' */ } ); message = 'Expected "actual" not to be strictly deep-equal to:' + `\n\n[${'\n 1,'.repeat(45)}\n...\n`; const data = Array(51).fill(1); assert.throws( () => assert.notDeepEqual(data, data), /* TODO(kt3k): Enable this assertion { message } */ ); } assert.throws( () => assert.ok(null), { code: 'ERR_ASSERTION', constructor: assert.AssertionError, generatedMessage: true, /* TODO(kt3k): Enable this assertion message: 'The expression evaluated to a falsy value:\n\n ' + 'assert.ok(null)\n' */ } ); assert.throws( () => assert(typeof 123n === 'string'), { code: 'ERR_ASSERTION', constructor: assert.AssertionError, generatedMessage: true, /* TODO(kt3k): Enable this assertion message: 'The expression evaluated to a falsy value:\n\n ' + "assert(typeof 123n === 'string')\n" */ } ); assert.throws( () => assert(false, Symbol('foo')), { code: 'ERR_ASSERTION', constructor: assert.AssertionError, /* TODO(kt3k): Enable this assertion generatedMessage: false, message: 'Symbol(foo)' */ } ); // TODO(kt3k): Enable these when "internal/test/binding" is ready. /* { // Test caching. const fs = internalBinding('fs'); const tmp = fs.close; fs.close = common.mustCall(tmp, 1); function throwErr() { assert( (Buffer.from('test') instanceof Error) ); } assert.throws( () => throwErr(), { code: 'ERR_ASSERTION', constructor: assert.AssertionError, message: 'The expression evaluated to a falsy value:\n\n ' + "assert(\n (Buffer.from('test') instanceof Error)\n )\n" } ); assert.throws( () => throwErr(), { code: 'ERR_ASSERTION', constructor: assert.AssertionError, message: 'The expression evaluated to a falsy value:\n\n ' + "assert(\n (Buffer.from('test') instanceof Error)\n )\n" } ); fs.close = tmp; } */ assert.throws( () => { a( (() => 'string')() === 123 instanceof Buffer ); }, { code: 'ERR_ASSERTION', constructor: assert.AssertionError, /* TODO(kt3k): Enable this assertion message: 'The expression evaluated to a falsy value:\n\n' + ' a(\n' + ' (() => \'string\')()\n' + ' ===\n' + ' 123 instanceof\n' + ' Buffer\n' + ' )\n' */ } ); assert.throws( () => { a( (() => 'string')() === 123 instanceof Buffer ); }, { code: 'ERR_ASSERTION', constructor: assert.AssertionError, /* TODO(kt3k): Enable this assertion message: 'The expression evaluated to a falsy value:\n\n' + ' a(\n' + ' (() => \'string\')()\n' + ' ===\n' + ' 123 instanceof\n' + ' Buffer\n' + ' )\n' */ } ); assert.throws(() => { a(( () => 'string')() === 123 instanceof Buffer ); }, { code: 'ERR_ASSERTION', constructor: assert.AssertionError, /* TODO(kt3k): Enable this assertion message: 'The expression evaluated to a falsy value:\n\n' + ' a((\n' + ' () => \'string\')() ===\n' + ' 123 instanceof\n' + ' Buffer\n' + ' )\n' */ } ); assert.throws( () => { assert(true); assert(null, undefined); }, { code: 'ERR_ASSERTION', constructor: assert.AssertionError, /* TODO(kt3k): Enable this assertion message: 'The expression evaluated to a falsy value:\n\n ' + 'assert(null, undefined)\n' */ } ); assert.throws( () => { assert .ok(null, undefined); }, { code: 'ERR_ASSERTION', constructor: assert.AssertionError, /* TODO(kt3k): Enable this assertion message: 'The expression evaluated to a falsy value:\n\n ' + 'ok(null, undefined)\n' */ } ); assert.throws( () => assert['ok']["apply"](null, [0]), { code: 'ERR_ASSERTION', constructor: assert.AssertionError, /* TODO(kt3k): Enable this assertion message: 'The expression evaluated to a falsy value:\n\n ' + 'assert[\'ok\']["apply"](null, [0])\n' */ } ); assert.throws( () => { const wrapper = (fn, value) => fn(value); wrapper(assert, false); }, { code: 'ERR_ASSERTION', constructor: assert.AssertionError, /* TODO(kt3k): Enable this assertion message: 'The expression evaluated to a falsy value:\n\n fn(value)\n' */ } ); assert.throws( () => assert.ok.call(null, 0), { code: 'ERR_ASSERTION', constructor: assert.AssertionError, /* TODO(kt3k): Enable this assertion message: 'The expression evaluated to a falsy value:\n\n ' + 'assert.ok.call(null, 0)\n', generatedMessage: true */ } ); assert.throws( () => assert.ok.call(null, 0, 'test'), { code: 'ERR_ASSERTION', constructor: assert.AssertionError, message: 'test', generatedMessage: false } ); // Works in eval. assert.throws( () => new Function('assert', 'assert(1 === 2);')(assert), { code: 'ERR_ASSERTION', constructor: assert.AssertionError, /* TODO(kt3k): Enable this assertion 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', /* TODO(kt3k): Enable this assertion message: 'false == true' */ } ); assert.throws( () => assert.throws(() => {}, 'Error message', 'message'), { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', /* TODO(kt3k): Enable this assertion message: 'The "error" argument must be of type function or ' + 'an instance of Error, RegExp, or Object. Received type string ' + "('Error message')" */ } ); [ 1, false, Symbol() ].forEach((input) => { assert.throws( () => assert.throws(() => {}, input), { code: 'ERR_INVALID_ARG_TYPE', /* TODO(kt3k): Enable this assertion message: 'The "error" argument must be of type function or ' + 'an instance of Error, RegExp, or Object.' + common.invalidArgTypeHelper(input) */ } ); }); { assert.throws(() => { assert.ok((() => Boolean('' === false))()); }, { code: "ERR_ASSERTION", /* TODO(kt3k): Enable this assertion message: 'The expression evaluated to a falsy value:\n\n' + " assert.ok((() => Boolean('\\u0001' === false))())\n" */ }); const errFn = () => { const err = new TypeError('Wrong value'); err.code = 404; throw err; }; const errObj = { name: 'TypeError', message: 'Wrong value' }; assert.throws(errFn, errObj); errObj.code = 404; assert.throws(errFn, errObj); // Fail in case a expected property is undefined and not existent on the // error. errObj.foo = undefined; assert.throws( () => assert.throws(errFn, errObj), { code: 'ERR_ASSERTION', name: 'AssertionError', /* TODO(kt3k): Enable this assertion message: `${start}\n${actExp}\n\n` + ' Comparison {\n' + ' code: 404,\n' + '- foo: undefined,\n' + " message: 'Wrong value',\n" + " name: 'TypeError'\n" + ' }' */ } ); // Show multiple wrong properties at the same time. errObj.code = '404'; assert.throws( () => assert.throws(errFn, errObj), { code: 'ERR_ASSERTION', name: 'AssertionError', /* TODO(kt3k): Enable this assertion message: `${start}\n${actExp}\n\n` + ' Comparison {\n' + '+ code: 404,\n' + "- code: '404',\n" + '- foo: undefined,\n' + " message: 'Wrong value',\n" + " name: 'TypeError'\n" + ' }' */ } ); assert.throws( () => assert.throws(() => { throw new Error(); }, { foo: 'bar' }, 'foobar'), { constructor: assert.AssertionError, code: 'ERR_ASSERTION', message: 'foobar' } ); assert.throws( () => a.doesNotThrow(() => { throw new Error(); }, { foo: 'bar' }), { name: 'TypeError', code: 'ERR_INVALID_ARG_TYPE', /* TODO(kt3k): Enable this assertion message: 'The "expected" argument must be of type function or an ' + 'instance of RegExp. Received an instance of Object' */ } ); assert.throws(() => { throw new Error('e'); }, new Error('e')); assert.throws( () => assert.throws(() => { throw new TypeError('e'); }, new Error('e')), { name: 'AssertionError', code: 'ERR_ASSERTION', /* TODO(kt3k): Enable this assertion message: `${start}\n${actExp}\n\n` + ' Comparison {\n' + " message: 'e',\n" + "+ name: 'TypeError'\n" + "- name: 'Error'\n" + ' }' */ } ); assert.throws( () => assert.throws(() => { throw new Error('foo'); }, new Error('')), { name: 'AssertionError', code: 'ERR_ASSERTION', /* TODO(kt3k): Enable this assertion generatedMessage: true, message: `${start}\n${actExp}\n\n` + ' Comparison {\n' + "+ message: 'foo',\n" + "- message: '',\n" + " name: 'Error'\n" + ' }' */ } ); assert.throws(() => { throw undefined; }, /undefined/); assert.throws( () => a.doesNotThrow(() => { throw undefined; }), { name: 'AssertionError', code: 'ERR_ASSERTION', message: 'Got unwanted exception.\nActual message: "undefined"' } ); } assert.throws( () => assert.throws(() => { throw new Error(); }, {}), { message: "The argument 'error' may not be an empty object. Received {}", code: 'ERR_INVALID_ARG_VALUE' } ); assert.throws( () => a.throws( () => { throw 'foo'; }, 'foo' ), { code: 'ERR_AMBIGUOUS_ARGUMENT', message: 'The "error/message" argument is ambiguous. ' + 'The error "foo" is identical to the message.' } ); assert.throws( () => a.throws( () => { throw new TypeError('foo'); }, 'foo' ), { code: 'ERR_AMBIGUOUS_ARGUMENT', message: 'The "error/message" argument is ambiguous. ' + 'The error message "foo" is identical to the message.' } ); // Should not throw. assert.throws(() => { throw null; }, 'foo'); assert.throws( () => assert.strictEqual([], []), { code: 'ERR_ASSERTION', /* TODO(kt3k): Enable this assertion message: 'Values have same structure but are not reference-equal:\n\n[]\n' */ } ); { const args = (function() { return arguments; })('a'); assert.throws( () => assert.strictEqual(args, { 0: 'a' }), { code: 'ERR_ASSERTION', /* TODO(kt3k): Enable this assertion message: 'Expected "actual" to be reference-equal to "expected":\n' + '+ actual - expected\n\n' + "+ [Arguments] {\n- {\n '0': 'a'\n }" */ } ); } assert.throws( () => { throw new TypeError('foobar'); }, { message: /foo/, name: /^TypeError$/ } ); assert.throws( () => assert.throws( () => { throw new TypeError('foobar'); }, { message: /fooa/, name: /^TypeError$/ } ), { code: 'ERR_ASSERTION', /* TODO(kt3k): Enable this assertion message: `${start}\n${actExp}\n\n` + ' Comparison {\n' + "+ message: 'foobar',\n" + '- message: /fooa/,\n' + " name: 'TypeError'\n" + ' }' */ } ); { let actual = null; const expected = { message: 'foo' }; assert.throws( () => assert.throws( () => { throw actual; }, expected ), { operator: 'throws', actual, expected, code: 'ERR_ASSERTION', /* TODO(kt3k): Enable this assertion generatedMessage: true, message: `${start}\n${actExp}\n\n` + '+ null\n' + '- {\n' + "- message: 'foo'\n" + '- }' */ } ); actual = 'foobar'; const message = 'message'; assert.throws( () => assert.throws( () => { throw actual; }, { message: 'foobar' }, message ), { actual, message, operator: 'throws', generatedMessage: false } ); } // Indicate where the strings diverge. assert.throws( () => assert.strictEqual('test test', 'test foobar'), { code: 'ERR_ASSERTION', name: 'AssertionError', /* TODO(kt3k): Enable this assertion message: strictEqualMessageStart + '+ actual - expected\n\n' + "+ 'test test'\n" + "- 'test foobar'\n" + ' ^' */ } ); // Check for reference-equal objects in `notStrictEqual()` assert.throws( () => { const obj = {}; assert.notStrictEqual(obj, obj); }, { code: 'ERR_ASSERTION', name: 'AssertionError', /* TODO(kt3k): Enable this assertion message: 'Expected "actual" not to be reference-equal to "expected": {}' */ } ); assert.throws( () => { const obj = { a: true }; assert.notStrictEqual(obj, obj); }, { code: 'ERR_ASSERTION', name: 'AssertionError', /* TODO(kt3k): Enable this assertion message: 'Expected "actual" not to be reference-equal to "expected":\n\n' + '{\n a: true\n}\n' */ } ); { let threw = false; try { assert.deepStrictEqual(Array(100).fill(1), 'foobar'); } catch (err) { threw = true; /* TODO(kt3k): Enable this assertion assert(/actual: \[Array],\n expected: 'foobar',/.test(inspect(err))); */ } assert(threw); } assert.throws( () => a.equal(1), { code: 'ERR_MISSING_ARGS' } ); assert.throws( () => a.deepEqual(/a/), { code: 'ERR_MISSING_ARGS' } ); assert.throws( () => a.notEqual(null), { code: 'ERR_MISSING_ARGS' } ); assert.throws( () => a.notDeepEqual('test'), { code: 'ERR_MISSING_ARGS' } ); assert.throws( () => a.strictEqual({}), { code: 'ERR_MISSING_ARGS' } ); assert.throws( () => a.deepStrictEqual(Symbol()), { code: 'ERR_MISSING_ARGS' } ); assert.throws( () => a.notStrictEqual(5n), { code: 'ERR_MISSING_ARGS' } ); assert.throws( () => a.notDeepStrictEqual(undefined), { code: 'ERR_MISSING_ARGS' } ); assert.throws( () => a.strictEqual(), { code: 'ERR_MISSING_ARGS' } ); assert.throws( () => a.deepStrictEqual(), { code: 'ERR_MISSING_ARGS' } ); // Verify that `stackStartFunction` works as alternative to `stackStartFn`. { (function hidden() { const err = new assert.AssertionError({ actual: 'foo', operator: 'strictEqual', stackStartFunction: hidden }); const err2 = new assert.AssertionError({ actual: 'foo', operator: 'strictEqual', stackStartFn: hidden }); assert(!err.stack.includes('hidden')); assert(!err2.stack.includes('hidden')); })(); } assert.throws( () => assert.throws(() => { throw Symbol('foo'); }, RangeError), { code: 'ERR_ASSERTION', /* TODO(kt3k): Enable this assertion message: 'The error is expected to be an instance of "RangeError". ' + 'Received "Symbol(foo)"' */ } ); assert.throws( () => assert.throws(() => { throw [1, 2]; }, RangeError), { code: 'ERR_ASSERTION', /* TODO(kt3k): Enable this assertion message: 'The error is expected to be an instance of "RangeError". ' + 'Received "[Array]"' */ } ); { const err = new TypeError('foo'); const validate = (() => () => ({ a: true, b: [ 1, 2, 3 ] }))(); assert.throws( () => assert.throws(() => { throw err; }, validate), { message: 'The validation function is expected to ' + `return "true". Received ${inspect(validate())}\n\nCaught ` + `error:\n\n${err}`, code: 'ERR_ASSERTION', actual: err, expected: validate, name: 'AssertionError', operator: 'throws', } ); } // TODO(kt3k): Enable these when "vm" is ready. /* assert.throws( () => { const script = new vm.Script('new RangeError("foobar");'); const context = vm.createContext(); const err = script.runInContext(context); assert.throws(() => { throw err; }, RangeError); }, { message: 'The error is expected to be an instance of "RangeError". ' + 'Received an error with identical name but a different ' + 'prototype.\n\nError message:\n\nfoobar' } ); */ // Multiple assert.match() tests. { assert.throws( () => assert.match(/abc/, 'string'), { code: 'ERR_INVALID_ARG_TYPE', /* TODO(kt3k): Enable this assertion message: 'The "regexp" argument must be an instance of RegExp. ' + "Received type string ('string')" */ } ); assert.throws( () => assert.match('string', /abc/), { actual: 'string', expected: /abc/, operator: 'match', /* TODO(kt3k): Enable this assertion message: 'The input did not match the regular expression /abc/. ' + "Input:\n\n'string'\n", generatedMessage: true */ } ); assert.throws( () => assert.match('string', /abc/, 'foobar'), { actual: 'string', expected: /abc/, operator: 'match', message: 'foobar', generatedMessage: false } ); const errorMessage = new RangeError('foobar'); assert.throws( () => assert.match('string', /abc/, errorMessage), errorMessage ); assert.throws( () => assert.match({ abc: 123 }, /abc/), { actual: { abc: 123 }, expected: /abc/, operator: 'match', /* TODO(kt3k): Enable this assertion message: 'The "string" argument must be of type string. ' + 'Received type object ({ abc: 123 })', generatedMessage: true */ } ); assert.match('I will pass', /pass$/); } // Multiple assert.doesNotMatch() tests. { assert.throws( () => assert.doesNotMatch(/abc/, 'string'), { code: 'ERR_INVALID_ARG_TYPE', /* TODO(kt3k): Enable this assertion message: 'The "regexp" argument must be an instance of RegExp. ' + "Received type string ('string')" */ } ); assert.throws( () => assert.doesNotMatch('string', /string/), { actual: 'string', expected: /string/, operator: 'doesNotMatch', /* TODO(kt3k): Enable this assertion message: 'The input was expected to not match the regular expression ' + "/string/. Input:\n\n'string'\n", generatedMessage: true */ } ); assert.throws( () => assert.doesNotMatch('string', /string/, 'foobar'), { actual: 'string', expected: /string/, operator: 'doesNotMatch', message: 'foobar', generatedMessage: false } ); const errorMessage = new RangeError('foobar'); assert.throws( () => assert.doesNotMatch('string', /string/, errorMessage), errorMessage ); assert.throws( () => assert.doesNotMatch({ abc: 123 }, /abc/), { actual: { abc: 123 }, expected: /abc/, operator: 'doesNotMatch', message: 'The "string" argument must be of type string. ' + 'Received type object ({ abc: 123 })', /* TODO(kt3k): Enable this assertion generatedMessage: true */ } ); assert.doesNotMatch('I will pass', /different$/); } { const tempColor = inspect.defaultOptions.colors; assert.throws(() => { inspect.defaultOptions.colors = true; // Guarantee the position indicator is placed correctly. assert.strictEqual(111554n, 11111115); }, (err) => { // TODO(kt3k): Enable this assertion // assert.strictEqual(inspect(err).split('\n')[5], ' ^'); inspect.defaultOptions.colors = tempColor; return true; }); }