1// Flags: --expose-internals 2// Copyright Joyent, Inc. and other Node contributors. 3// 4// Permission is hereby granted, free of charge, to any person obtaining a 5// copy of this software and associated documentation files (the 6// "Software"), to deal in the Software without restriction, including 7// without limitation the rights to use, copy, modify, merge, publish, 8// distribute, sublicense, and/or sell copies of the Software, and to permit 9// persons to whom the Software is furnished to do so, subject to the 10// following conditions: 11// 12// The above copyright notice and this permission notice shall be included 13// in all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 18// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21// USE OR OTHER DEALINGS IN THE SOFTWARE. 22 23'use strict'; 24 25const common = require('../common'); 26const assert = require('assert'); 27const { inspect } = require('util'); 28const vm = require('vm'); 29const { internalBinding } = require('internal/test/binding'); 30const a = assert; 31 32// Disable colored output to prevent color codes from breaking assertion 33// message comparisons. This should only be an issue when process.stdout 34// is a TTY. 35if (process.stdout.isTTY) 36 process.env.NODE_DISABLE_COLORS = '1'; 37 38const strictEqualMessageStart = 'Expected values to be strictly equal:\n'; 39const start = 'Expected values to be strictly deep-equal:'; 40const actExp = '+ actual - expected'; 41 42assert.ok(a.AssertionError.prototype instanceof Error, 43 'a.AssertionError instanceof Error'); 44 45assert.throws(() => a(false), a.AssertionError, 'ok(false)'); 46assert.throws(() => a.ok(false), a.AssertionError, 'ok(false)'); 47 48// Throw message if the message is instanceof Error. 49{ 50 let threw = false; 51 try { 52 assert.ok(false, new Error('ok(false)')); 53 } catch (e) { 54 threw = true; 55 assert.ok(e instanceof Error); 56 } 57 assert.ok(threw, 'Error: ok(false)'); 58} 59 60 61a(true); 62a('test', 'ok(\'test\')'); 63a.ok(true); 64a.ok('test'); 65 66assert.throws(() => a.equal(true, false), 67 a.AssertionError, 'equal(true, false)'); 68 69a.equal(null, null); 70a.equal(undefined, undefined); 71a.equal(null, undefined); 72a.equal(true, true); 73a.equal(2, '2'); 74a.notEqual(true, false); 75 76assert.throws(() => a.notEqual(true, true), 77 a.AssertionError, 'notEqual(true, true)'); 78 79assert.throws(() => a.strictEqual(2, '2'), 80 a.AssertionError, 'strictEqual(2, \'2\')'); 81 82/* eslint-disable no-restricted-syntax */ 83assert.throws(() => a.strictEqual(null, undefined), 84 a.AssertionError, 'strictEqual(null, undefined)'); 85 86assert.throws( 87 () => a.notStrictEqual(2, 2), 88 { 89 message: 'Expected "actual" to be strictly unequal to: 2', 90 name: 'AssertionError' 91 } 92); 93 94assert.throws( 95 () => a.notStrictEqual('a '.repeat(30), 'a '.repeat(30)), 96 { 97 message: 'Expected "actual" to be strictly unequal to:\n\n' + 98 `'${'a '.repeat(30)}'`, 99 name: 'AssertionError' 100 } 101); 102 103assert.throws( 104 () => a.notEqual(1, 1), 105 { 106 message: '1 != 1', 107 operator: '!=' 108 } 109); 110 111a.notStrictEqual(2, '2'); 112 113// Testing the throwing. 114function thrower(errorConstructor) { 115 throw new errorConstructor({}); 116} 117 118// The basic calls work. 119assert.throws(() => thrower(a.AssertionError), a.AssertionError, 'message'); 120assert.throws(() => thrower(a.AssertionError), a.AssertionError); 121assert.throws(() => thrower(a.AssertionError)); 122 123// If not passing an error, catch all. 124assert.throws(() => thrower(TypeError)); 125 126// When passing a type, only catch errors of the appropriate type. 127assert.throws( 128 () => a.throws(() => thrower(TypeError), a.AssertionError), 129 { 130 generatedMessage: true, 131 actual: new TypeError({}), 132 expected: a.AssertionError, 133 code: 'ERR_ASSERTION', 134 name: 'AssertionError', 135 operator: 'throws', 136 message: 'The error is expected to be an instance of "AssertionError". ' + 137 'Received "TypeError"\n\nError message:\n\n[object Object]' 138 } 139); 140 141// doesNotThrow should pass through all errors. 142{ 143 let threw = false; 144 try { 145 a.doesNotThrow(() => thrower(TypeError), a.AssertionError); 146 } catch (e) { 147 threw = true; 148 assert.ok(e instanceof TypeError); 149 } 150 assert(threw, 'a.doesNotThrow with an explicit error is eating extra errors'); 151} 152 153// Key difference is that throwing our correct error makes an assertion error. 154{ 155 let threw = false; 156 try { 157 a.doesNotThrow(() => thrower(TypeError), TypeError); 158 } catch (e) { 159 threw = true; 160 assert.ok(e instanceof a.AssertionError); 161 assert.ok(!e.stack.includes('at Function.doesNotThrow')); 162 } 163 assert.ok(threw, 'a.doesNotThrow is not catching type matching errors'); 164} 165 166assert.throws( 167 () => a.doesNotThrow(() => thrower(Error), 'user message'), 168 { 169 name: 'AssertionError', 170 code: 'ERR_ASSERTION', 171 operator: 'doesNotThrow', 172 message: 'Got unwanted exception: user message\n' + 173 'Actual message: "[object Object]"' 174 } 175); 176 177assert.throws( 178 () => a.doesNotThrow(() => thrower(Error)), 179 { 180 code: 'ERR_ASSERTION', 181 message: 'Got unwanted exception.\nActual message: "[object Object]"' 182 } 183); 184 185assert.throws( 186 () => a.doesNotThrow(() => thrower(Error), /\[[a-z]{6}\s[A-z]{6}\]/g, 'user message'), 187 { 188 name: 'AssertionError', 189 code: 'ERR_ASSERTION', 190 operator: 'doesNotThrow', 191 message: 'Got unwanted exception: user message\n' + 192 'Actual message: "[object Object]"' 193 } 194); 195 196// Make sure that validating using constructor really works. 197{ 198 let threw = false; 199 try { 200 assert.throws( 201 () => { 202 throw ({}); // eslint-disable-line no-throw-literal 203 }, 204 Array 205 ); 206 } catch { 207 threw = true; 208 } 209 assert.ok(threw, 'wrong constructor validation'); 210} 211 212// Use a RegExp to validate the error message. 213{ 214 a.throws(() => thrower(TypeError), /\[object Object\]/); 215 216 const symbol = Symbol('foo'); 217 a.throws(() => { 218 throw symbol; 219 }, /foo/); 220 221 a.throws(() => { 222 a.throws(() => { 223 throw symbol; 224 }, /abc/); 225 }, { 226 message: 'The input did not match the regular expression /abc/. ' + 227 "Input:\n\n'Symbol(foo)'\n", 228 code: 'ERR_ASSERTION', 229 operator: 'throws', 230 actual: symbol, 231 expected: /abc/ 232 }); 233} 234 235// Use a fn to validate the error object. 236a.throws(() => thrower(TypeError), (err) => { 237 if ((err instanceof TypeError) && /\[object Object\]/.test(err)) { 238 return true; 239 } 240}); 241 242// https://github.com/nodejs/node/issues/3188 243{ 244 let actual; 245 assert.throws( 246 () => { 247 const ES6Error = class extends Error {}; 248 const AnotherErrorType = class extends Error {}; 249 250 assert.throws(() => { 251 actual = new AnotherErrorType('foo'); 252 throw actual; 253 }, ES6Error); 254 }, 255 (err) => { 256 assert.strictEqual( 257 err.message, 258 'The error is expected to be an instance of "ES6Error". ' + 259 'Received "AnotherErrorType"\n\nError message:\n\nfoo' 260 ); 261 assert.strictEqual(err.actual, actual); 262 return true; 263 } 264 ); 265} 266 267// Check messages from assert.throws(). 268{ 269 const noop = () => {}; 270 assert.throws( 271 () => { a.throws((noop)); }, 272 { 273 code: 'ERR_ASSERTION', 274 message: 'Missing expected exception.', 275 operator: 'throws', 276 actual: undefined, 277 expected: undefined 278 }); 279 280 assert.throws( 281 () => { a.throws(noop, TypeError); }, 282 { 283 code: 'ERR_ASSERTION', 284 message: 'Missing expected exception (TypeError).', 285 actual: undefined, 286 expected: TypeError 287 }); 288 289 assert.throws( 290 () => { a.throws(noop, 'fhqwhgads'); }, 291 { 292 code: 'ERR_ASSERTION', 293 message: 'Missing expected exception: fhqwhgads', 294 actual: undefined, 295 expected: undefined 296 }); 297 298 assert.throws( 299 () => { a.throws(noop, TypeError, 'fhqwhgads'); }, 300 { 301 code: 'ERR_ASSERTION', 302 message: 'Missing expected exception (TypeError): fhqwhgads', 303 actual: undefined, 304 expected: TypeError 305 }); 306 307 let threw = false; 308 try { 309 a.throws(noop); 310 } catch (e) { 311 threw = true; 312 assert.ok(e instanceof a.AssertionError); 313 assert.ok(!e.stack.includes('at Function.throws')); 314 } 315 assert.ok(threw); 316} 317 318const circular = { y: 1 }; 319circular.x = circular; 320 321function testAssertionMessage(actual, expected, msg) { 322 assert.throws( 323 () => assert.strictEqual(actual, ''), 324 { 325 generatedMessage: true, 326 message: msg || strictEqualMessageStart + 327 `+ actual - expected\n\n+ ${expected}\n- ''` 328 } 329 ); 330} 331 332function testShortAssertionMessage(actual, expected) { 333 testAssertionMessage(actual, expected, strictEqualMessageStart + 334 `\n${inspect(actual)} !== ''\n`); 335} 336 337testShortAssertionMessage(null, 'null'); 338testShortAssertionMessage(true, 'true'); 339testShortAssertionMessage(false, 'false'); 340testShortAssertionMessage(100, '100'); 341testShortAssertionMessage(NaN, 'NaN'); 342testShortAssertionMessage(Infinity, 'Infinity'); 343testShortAssertionMessage('a', '"a"'); 344testShortAssertionMessage('foo', '\'foo\''); 345testShortAssertionMessage(0, '0'); 346testShortAssertionMessage(Symbol(), 'Symbol()'); 347testShortAssertionMessage(undefined, 'undefined'); 348testShortAssertionMessage(-Infinity, '-Infinity'); 349testAssertionMessage([], '[]'); 350testAssertionMessage(/a/, '/a/'); 351testAssertionMessage(/abc/gim, '/abc/gim'); 352testAssertionMessage({}, '{}'); 353testAssertionMessage([1, 2, 3], '[\n+ 1,\n+ 2,\n+ 3\n+ ]'); 354testAssertionMessage(function f() {}, '[Function: f]'); 355testAssertionMessage(function() {}, '[Function (anonymous)]'); 356testAssertionMessage(circular, 357 '<ref *1> {\n+ x: [Circular *1],\n+ y: 1\n+ }'); 358testAssertionMessage({ a: undefined, b: null }, 359 '{\n+ a: undefined,\n+ b: null\n+ }'); 360testAssertionMessage({ a: NaN, b: Infinity, c: -Infinity }, 361 '{\n+ a: NaN,\n+ b: Infinity,\n+ c: -Infinity\n+ }'); 362 363// https://github.com/nodejs/node-v0.x-archive/issues/5292 364assert.throws( 365 () => assert.strictEqual(1, 2), 366 { 367 message: `${strictEqualMessageStart}\n1 !== 2\n`, 368 generatedMessage: true 369 } 370); 371 372assert.throws( 373 () => assert.strictEqual(1, 2, 'oh no'), 374 { 375 message: 'oh no', 376 generatedMessage: false 377 } 378); 379 380{ 381 let threw = false; 382 const rangeError = new RangeError('my range'); 383 384 // Verify custom errors. 385 try { 386 assert.strictEqual(1, 2, rangeError); 387 } catch (e) { 388 assert.strictEqual(e, rangeError); 389 threw = true; 390 assert.ok(e instanceof RangeError, 'Incorrect error type thrown'); 391 } 392 assert.ok(threw); 393 threw = false; 394 395 // Verify AssertionError is the result from doesNotThrow with custom Error. 396 try { 397 a.doesNotThrow(() => { 398 throw new TypeError('wrong type'); 399 }, TypeError, rangeError); 400 } catch (e) { 401 threw = true; 402 assert.ok(e.message.includes(rangeError.message)); 403 assert.ok(e instanceof assert.AssertionError); 404 assert.ok(!e.stack.includes('doesNotThrow'), e); 405 } 406 assert.ok(threw); 407} 408 409{ 410 // Verify that throws() and doesNotThrow() throw on non-functions. 411 const testBlockTypeError = (method, fn) => { 412 assert.throws( 413 () => method(fn), 414 { 415 code: 'ERR_INVALID_ARG_TYPE', 416 name: 'TypeError', 417 message: 'The "fn" argument must be of type function.' + 418 common.invalidArgTypeHelper(fn) 419 } 420 ); 421 }; 422 423 testBlockTypeError(assert.throws, 'string'); 424 testBlockTypeError(assert.doesNotThrow, 'string'); 425 testBlockTypeError(assert.throws, 1); 426 testBlockTypeError(assert.doesNotThrow, 1); 427 testBlockTypeError(assert.throws, true); 428 testBlockTypeError(assert.doesNotThrow, true); 429 testBlockTypeError(assert.throws, false); 430 testBlockTypeError(assert.doesNotThrow, false); 431 testBlockTypeError(assert.throws, []); 432 testBlockTypeError(assert.doesNotThrow, []); 433 testBlockTypeError(assert.throws, {}); 434 testBlockTypeError(assert.doesNotThrow, {}); 435 testBlockTypeError(assert.throws, /foo/); 436 testBlockTypeError(assert.doesNotThrow, /foo/); 437 testBlockTypeError(assert.throws, null); 438 testBlockTypeError(assert.doesNotThrow, null); 439 testBlockTypeError(assert.throws, undefined); 440 testBlockTypeError(assert.doesNotThrow, undefined); 441} 442 443// https://github.com/nodejs/node/issues/3275 444// eslint-disable-next-line no-throw-literal 445assert.throws(() => { throw 'error'; }, (err) => err === 'error'); 446assert.throws(() => { throw new Error(); }, (err) => err instanceof Error); 447 448// Long values should be truncated for display. 449assert.throws(() => { 450 assert.strictEqual('A'.repeat(1000), ''); 451}, (err) => { 452 assert.strictEqual(err.code, 'ERR_ASSERTION'); 453 assert.strictEqual(err.message, 454 `${strictEqualMessageStart}+ actual - expected\n\n` + 455 `+ '${'A'.repeat(1000)}'\n- ''`); 456 assert.strictEqual(err.actual.length, 1000); 457 assert.ok(inspect(err).includes(`actual: '${'A'.repeat(488)}...'`)); 458 return true; 459}); 460 461// Output that extends beyond 10 lines should also be truncated for display. 462{ 463 const multilineString = 'fhqwhgads\n'.repeat(15); 464 assert.throws(() => { 465 assert.strictEqual(multilineString, ''); 466 }, (err) => { 467 assert.strictEqual(err.code, 'ERR_ASSERTION'); 468 assert.strictEqual(err.message.split('\n').length, 19); 469 assert.strictEqual(err.actual.split('\n').length, 16); 470 assert.ok(inspect(err).includes( 471 "actual: 'fhqwhgads\\n' +\n" + 472 " 'fhqwhgads\\n' +\n".repeat(9) + 473 " '...'")); 474 return true; 475 }); 476} 477 478{ 479 // Bad args to AssertionError constructor should throw TypeError. 480 const args = [1, true, false, '', null, Infinity, Symbol('test'), undefined]; 481 args.forEach((input) => { 482 assert.throws( 483 () => new assert.AssertionError(input), 484 { 485 code: 'ERR_INVALID_ARG_TYPE', 486 name: 'TypeError', 487 message: 'The "options" argument must be of type object.' + 488 common.invalidArgTypeHelper(input) 489 }); 490 }); 491} 492 493assert.throws( 494 () => assert.strictEqual(new Error('foo'), new Error('foobar')), 495 { 496 code: 'ERR_ASSERTION', 497 name: 'AssertionError', 498 message: 'Expected "actual" to be reference-equal to "expected":\n' + 499 '+ actual - expected\n\n' + 500 '+ [Error: foo]\n- [Error: foobar]' 501 } 502); 503 504a.equal(NaN, NaN); 505a.throws( 506 () => a.notEqual(NaN, NaN), 507 a.AssertionError 508); 509 510// Test strict assert. 511{ 512 const a = require('assert'); 513 const assert = require('assert').strict; 514 /* eslint-disable no-restricted-properties */ 515 assert.throws(() => assert.equal(1, true), assert.AssertionError); 516 assert.notEqual(0, false); 517 assert.throws(() => assert.deepEqual(1, true), assert.AssertionError); 518 assert.notDeepEqual(0, false); 519 assert.equal(assert.strict, assert.strict.strict); 520 assert.equal(assert.equal, assert.strictEqual); 521 assert.equal(assert.deepEqual, assert.deepStrictEqual); 522 assert.equal(assert.notEqual, assert.notStrictEqual); 523 assert.equal(assert.notDeepEqual, assert.notDeepStrictEqual); 524 assert.equal(Object.keys(assert).length, Object.keys(a).length); 525 assert(7); 526 assert.throws( 527 () => assert(...[]), 528 { 529 message: 'No value argument passed to `assert.ok()`', 530 name: 'AssertionError', 531 generatedMessage: true 532 } 533 ); 534 assert.throws( 535 () => a(), 536 { 537 message: 'No value argument passed to `assert.ok()`', 538 name: 'AssertionError' 539 } 540 ); 541 542 // Test setting the limit to zero and that assert.strict works properly. 543 const tmpLimit = Error.stackTraceLimit; 544 Error.stackTraceLimit = 0; 545 assert.throws( 546 () => { 547 assert.ok( 548 typeof 123 === 'string' 549 ); 550 }, 551 { 552 code: 'ERR_ASSERTION', 553 constructor: assert.AssertionError, 554 message: 'The expression evaluated to a falsy value:\n\n ' + 555 "assert.ok(\n typeof 123 === 'string'\n )\n" 556 } 557 ); 558 Error.stackTraceLimit = tmpLimit; 559 560 // Test error diffs. 561 let message = [ 562 start, 563 `${actExp} ... Lines skipped`, 564 '', 565 ' [', 566 ' [', 567 ' [', 568 ' 1,', 569 ' 2,', 570 '+ 3', 571 "- '3'", 572 ' ]', 573 '...', 574 ' 4,', 575 ' 5', 576 ' ]'].join('\n'); 577 assert.throws( 578 () => assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]), 579 { message }); 580 581 message = [ 582 start, 583 `${actExp} ... Lines skipped`, 584 '', 585 ' [', 586 ' 1,', 587 '...', 588 ' 1,', 589 ' 0,', 590 '- 1,', 591 ' 1,', 592 '...', 593 ' 1,', 594 ' 1', 595 ' ]', 596 ].join('\n'); 597 assert.throws( 598 () => assert.deepEqual( 599 [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], 600 [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1]), 601 { message }); 602 603 message = [ 604 start, 605 `${actExp} ... Lines skipped`, 606 '', 607 ' [', 608 ' 1,', 609 '...', 610 ' 1,', 611 ' 0,', 612 '+ 1,', 613 ' 1,', 614 ' 1,', 615 ' 1', 616 ' ]', 617 ].join('\n'); 618 assert.throws( 619 () => assert.deepEqual( 620 [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], 621 [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1]), 622 { message }); 623 624 message = [ 625 start, 626 actExp, 627 '', 628 ' [', 629 ' 1,', 630 '+ 2,', 631 '- 1,', 632 ' 1,', 633 ' 1,', 634 ' 0,', 635 '+ 1,', 636 ' 1', 637 ' ]', 638 ].join('\n'); 639 assert.throws( 640 () => assert.deepEqual( 641 [1, 2, 1, 1, 0, 1, 1], 642 [1, 1, 1, 1, 0, 1]), 643 { message }); 644 645 message = [ 646 start, 647 actExp, 648 '', 649 '+ [', 650 '+ 1,', 651 '+ 2,', 652 '+ 1', 653 '+ ]', 654 '- undefined', 655 ].join('\n'); 656 assert.throws( 657 () => assert.deepEqual([1, 2, 1], undefined), 658 { message }); 659 660 message = [ 661 start, 662 actExp, 663 '', 664 ' [', 665 '+ 1,', 666 ' 2,', 667 ' 1', 668 ' ]', 669 ].join('\n'); 670 assert.throws( 671 () => assert.deepEqual([1, 2, 1], [2, 1]), 672 { message }); 673 674 message = `${start}\n` + 675 `${actExp} ... Lines skipped\n` + 676 '\n' + 677 ' [\n' + 678 '+ 1,\n'.repeat(25) + 679 '...\n' + 680 '- 2,\n'.repeat(25) + 681 '...'; 682 assert.throws( 683 () => assert.deepEqual(Array(28).fill(1), Array(28).fill(2)), 684 { message }); 685 686 const obj1 = {}; 687 const obj2 = { loop: 'forever' }; 688 obj2[inspect.custom] = () => '{}'; 689 // No infinite loop and no custom inspect. 690 assert.throws(() => assert.deepEqual(obj1, obj2), { 691 message: `${start}\n` + 692 `${actExp}\n` + 693 '\n' + 694 '+ {}\n' + 695 '- {\n' + 696 '- [Symbol(nodejs.util.inspect.custom)]: [Function (anonymous)],\n' + 697 "- loop: 'forever'\n" + 698 '- }' 699 }); 700 701 // notDeepEqual tests 702 assert.throws( 703 () => assert.notDeepEqual([1], [1]), 704 { 705 message: 'Expected "actual" not to be strictly deep-equal to:\n\n' + 706 '[\n 1\n]\n' 707 } 708 ); 709 710 message = 'Expected "actual" not to be strictly deep-equal to:' + 711 `\n\n[${'\n 1,'.repeat(45)}\n...\n`; 712 const data = Array(51).fill(1); 713 assert.throws( 714 () => assert.notDeepEqual(data, data), 715 { message }); 716 /* eslint-enable no-restricted-properties */ 717} 718 719assert.throws( 720 () => assert.ok(null), 721 { 722 code: 'ERR_ASSERTION', 723 constructor: assert.AssertionError, 724 generatedMessage: true, 725 message: 'The expression evaluated to a falsy value:\n\n ' + 726 'assert.ok(null)\n' 727 } 728); 729assert.throws( 730 () => { 731 // This test case checks if `try` left brace without a line break 732 // before the assertion causes any wrong assertion message. 733 // Therefore, don't reformat the following code. 734 // Refs: https://github.com/nodejs/node/issues/30872 735 try { assert.ok(0); // eslint-disable-line no-useless-catch, brace-style 736 } catch (err) { 737 throw err; 738 } 739 }, 740 { 741 code: 'ERR_ASSERTION', 742 constructor: assert.AssertionError, 743 generatedMessage: true, 744 message: 'The expression evaluated to a falsy value:\n\n ' + 745 'assert.ok(0)\n' 746 } 747); 748assert.throws( 749 () => { 750 try { 751 throw new Error(); 752 // This test case checks if `catch` left brace without a line break 753 // before the assertion causes any wrong assertion message. 754 // Therefore, don't reformat the following code. 755 // Refs: https://github.com/nodejs/node/issues/30872 756 } catch (err) { assert.ok(0); } // eslint-disable-line no-unused-vars 757 }, 758 { 759 code: 'ERR_ASSERTION', 760 constructor: assert.AssertionError, 761 generatedMessage: true, 762 message: 'The expression evaluated to a falsy value:\n\n ' + 763 'assert.ok(0)\n' 764 } 765); 766assert.throws( 767 () => { 768 // This test case checks if `function` left brace without a line break 769 // before the assertion causes any wrong assertion message. 770 // Therefore, don't reformat the following code. 771 // Refs: https://github.com/nodejs/node/issues/30872 772 function test() { assert.ok(0); // eslint-disable-line brace-style 773 } 774 test(); 775 }, 776 { 777 code: 'ERR_ASSERTION', 778 constructor: assert.AssertionError, 779 generatedMessage: true, 780 message: 'The expression evaluated to a falsy value:\n\n ' + 781 'assert.ok(0)\n' 782 } 783); 784assert.throws( 785 () => assert(typeof 123n === 'string'), 786 { 787 code: 'ERR_ASSERTION', 788 constructor: assert.AssertionError, 789 generatedMessage: true, 790 message: 'The expression evaluated to a falsy value:\n\n ' + 791 "assert(typeof 123n === 'string')\n" 792 } 793); 794 795assert.throws( 796 () => assert(false, Symbol('foo')), 797 { 798 code: 'ERR_ASSERTION', 799 constructor: assert.AssertionError, 800 generatedMessage: false, 801 message: 'Symbol(foo)' 802 } 803); 804 805{ 806 // Test caching. 807 const fs = internalBinding('fs'); 808 const tmp = fs.close; 809 fs.close = common.mustCall(tmp, 1); 810 function throwErr() { 811 assert( 812 (Buffer.from('test') instanceof Error) 813 ); 814 } 815 assert.throws( 816 () => throwErr(), 817 { 818 code: 'ERR_ASSERTION', 819 constructor: assert.AssertionError, 820 message: 'The expression evaluated to a falsy value:\n\n ' + 821 "assert(\n (Buffer.from('test') instanceof Error)\n )\n" 822 } 823 ); 824 assert.throws( 825 () => throwErr(), 826 { 827 code: 'ERR_ASSERTION', 828 constructor: assert.AssertionError, 829 message: 'The expression evaluated to a falsy value:\n\n ' + 830 "assert(\n (Buffer.from('test') instanceof Error)\n )\n" 831 } 832 ); 833 fs.close = tmp; 834} 835 836assert.throws( 837 () => { 838 a( 839 (() => 'string')() 840 // eslint-disable-next-line operator-linebreak 841 === 842 123 instanceof 843 Buffer 844 ); 845 }, 846 { 847 code: 'ERR_ASSERTION', 848 constructor: assert.AssertionError, 849 message: 'The expression evaluated to a falsy value:\n\n' + 850 ' a(\n' + 851 ' (() => \'string\')()\n' + 852 ' // eslint-disable-next-line operator-linebreak\n' + 853 ' ===\n' + 854 ' 123 instanceof\n' + 855 ' Buffer\n' + 856 ' )\n' 857 } 858); 859 860assert.throws( 861 () => { 862 a( 863 (() => 'string')() 864 // eslint-disable-next-line operator-linebreak 865 === 866 123 instanceof 867 Buffer 868 ); 869 }, 870 { 871 code: 'ERR_ASSERTION', 872 constructor: assert.AssertionError, 873 message: 'The expression evaluated to a falsy value:\n\n' + 874 ' a(\n' + 875 ' (() => \'string\')()\n' + 876 ' // eslint-disable-next-line operator-linebreak\n' + 877 ' ===\n' + 878 ' 123 instanceof\n' + 879 ' Buffer\n' + 880 ' )\n' 881 } 882); 883 884/* eslint-disable indent */ 885assert.throws(() => { 886a(( 887 () => 'string')() === 888123 instanceof 889Buffer 890); 891}, { 892 code: 'ERR_ASSERTION', 893 constructor: assert.AssertionError, 894 message: 'The expression evaluated to a falsy value:\n\n' + 895 ' a((\n' + 896 ' () => \'string\')() ===\n' + 897 ' 123 instanceof\n' + 898 ' Buffer\n' + 899 ' )\n' 900 } 901); 902/* eslint-enable indent */ 903 904assert.throws( 905 () => { 906 assert(true); assert(null, undefined); 907 }, 908 { 909 code: 'ERR_ASSERTION', 910 constructor: assert.AssertionError, 911 message: 'The expression evaluated to a falsy value:\n\n ' + 912 'assert(null, undefined)\n' 913 } 914); 915 916assert.throws( 917 () => { 918 assert 919 .ok(null, undefined); 920 }, 921 { 922 code: 'ERR_ASSERTION', 923 constructor: assert.AssertionError, 924 message: 'The expression evaluated to a falsy value:\n\n ' + 925 'ok(null, undefined)\n' 926 } 927); 928 929assert.throws( 930 // eslint-disable-next-line dot-notation, quotes 931 () => assert['ok']["apply"](null, [0]), 932 { 933 code: 'ERR_ASSERTION', 934 constructor: assert.AssertionError, 935 message: 'The expression evaluated to a falsy value:\n\n ' + 936 'assert[\'ok\']["apply"](null, [0])\n' 937 } 938); 939 940assert.throws( 941 () => { 942 const wrapper = (fn, value) => fn(value); 943 wrapper(assert, false); 944 }, 945 { 946 code: 'ERR_ASSERTION', 947 constructor: assert.AssertionError, 948 message: 'The expression evaluated to a falsy value:\n\n fn(value)\n' 949 } 950); 951 952assert.throws( 953 () => assert.ok.call(null, 0), 954 { 955 code: 'ERR_ASSERTION', 956 constructor: assert.AssertionError, 957 message: 'The expression evaluated to a falsy value:\n\n ' + 958 'assert.ok.call(null, 0)\n', 959 generatedMessage: true 960 } 961); 962 963assert.throws( 964 () => assert.ok.call(null, 0, 'test'), 965 { 966 code: 'ERR_ASSERTION', 967 constructor: assert.AssertionError, 968 message: 'test', 969 generatedMessage: false 970 } 971); 972 973// Works in eval. 974assert.throws( 975 () => new Function('assert', 'assert(1 === 2);')(assert), 976 { 977 code: 'ERR_ASSERTION', 978 constructor: assert.AssertionError, 979 message: 'false == true' 980 } 981); 982assert.throws( 983 () => eval('console.log("FOO");\nassert.ok(1 === 2);'), 984 { 985 code: 'ERR_ASSERTION', 986 message: 'false == true' 987 } 988); 989 990assert.throws( 991 () => assert.throws(() => {}, 'Error message', 'message'), 992 { 993 code: 'ERR_INVALID_ARG_TYPE', 994 name: 'TypeError', 995 message: 'The "error" argument must be of type function or ' + 996 'an instance of Error, RegExp, or Object. Received type string ' + 997 "('Error message')" 998 } 999); 1000 1001[ 1002 1, 1003 false, 1004 Symbol(), 1005].forEach((input) => { 1006 assert.throws( 1007 () => assert.throws(() => {}, input), 1008 { 1009 code: 'ERR_INVALID_ARG_TYPE', 1010 message: 'The "error" argument must be of type function or ' + 1011 'an instance of Error, RegExp, or Object.' + 1012 common.invalidArgTypeHelper(input) 1013 } 1014 ); 1015}); 1016 1017{ 1018 1019 assert.throws(() => { 1020 assert.ok((() => Boolean('' === false))()); 1021 }, { 1022 message: 'The expression evaluated to a falsy value:\n\n' + 1023 " assert.ok((() => Boolean('\\u0001' === false))())\n" 1024 }); 1025 1026 const errFn = () => { 1027 const err = new TypeError('Wrong value'); 1028 err.code = 404; 1029 throw err; 1030 }; 1031 const errObj = { 1032 name: 'TypeError', 1033 message: 'Wrong value' 1034 }; 1035 assert.throws(errFn, errObj); 1036 1037 errObj.code = 404; 1038 assert.throws(errFn, errObj); 1039 1040 // Fail in case a expected property is undefined and not existent on the 1041 // error. 1042 errObj.foo = undefined; 1043 assert.throws( 1044 () => assert.throws(errFn, errObj), 1045 { 1046 code: 'ERR_ASSERTION', 1047 name: 'AssertionError', 1048 message: `${start}\n${actExp}\n\n` + 1049 ' Comparison {\n' + 1050 ' code: 404,\n' + 1051 '- foo: undefined,\n' + 1052 " message: 'Wrong value',\n" + 1053 " name: 'TypeError'\n" + 1054 ' }' 1055 } 1056 ); 1057 1058 // Show multiple wrong properties at the same time. 1059 errObj.code = '404'; 1060 assert.throws( 1061 () => assert.throws(errFn, errObj), 1062 { 1063 code: 'ERR_ASSERTION', 1064 name: 'AssertionError', 1065 message: `${start}\n${actExp}\n\n` + 1066 ' Comparison {\n' + 1067 '+ code: 404,\n' + 1068 "- code: '404',\n" + 1069 '- foo: undefined,\n' + 1070 " message: 'Wrong value',\n" + 1071 " name: 'TypeError'\n" + 1072 ' }' 1073 } 1074 ); 1075 1076 assert.throws( 1077 () => assert.throws(() => { throw new Error(); }, { foo: 'bar' }, 'foobar'), 1078 { 1079 constructor: assert.AssertionError, 1080 code: 'ERR_ASSERTION', 1081 message: 'foobar' 1082 } 1083 ); 1084 1085 assert.throws( 1086 () => a.doesNotThrow(() => { throw new Error(); }, { foo: 'bar' }), 1087 { 1088 name: 'TypeError', 1089 code: 'ERR_INVALID_ARG_TYPE', 1090 message: 'The "expected" argument must be of type function or an ' + 1091 'instance of RegExp. Received an instance of Object' 1092 } 1093 ); 1094 1095 assert.throws(() => { throw new Error('e'); }, new Error('e')); 1096 assert.throws( 1097 () => assert.throws(() => { throw new TypeError('e'); }, new Error('e')), 1098 { 1099 name: 'AssertionError', 1100 code: 'ERR_ASSERTION', 1101 message: `${start}\n${actExp}\n\n` + 1102 ' Comparison {\n' + 1103 " message: 'e',\n" + 1104 "+ name: 'TypeError'\n" + 1105 "- name: 'Error'\n" + 1106 ' }' 1107 } 1108 ); 1109 assert.throws( 1110 () => assert.throws(() => { throw new Error('foo'); }, new Error('')), 1111 { 1112 name: 'AssertionError', 1113 code: 'ERR_ASSERTION', 1114 generatedMessage: true, 1115 message: `${start}\n${actExp}\n\n` + 1116 ' Comparison {\n' + 1117 "+ message: 'foo',\n" + 1118 "- message: '',\n" + 1119 " name: 'Error'\n" + 1120 ' }' 1121 } 1122 ); 1123 1124 // eslint-disable-next-line no-throw-literal 1125 assert.throws(() => { throw undefined; }, /undefined/); 1126 assert.throws( 1127 // eslint-disable-next-line no-throw-literal 1128 () => a.doesNotThrow(() => { throw undefined; }), 1129 { 1130 name: 'AssertionError', 1131 code: 'ERR_ASSERTION', 1132 message: 'Got unwanted exception.\nActual message: "undefined"' 1133 } 1134 ); 1135} 1136 1137assert.throws( 1138 () => assert.throws(() => { throw new Error(); }, {}), 1139 { 1140 message: "The argument 'error' may not be an empty object. Received {}", 1141 code: 'ERR_INVALID_ARG_VALUE' 1142 } 1143); 1144 1145assert.throws( 1146 () => a.throws( 1147 // eslint-disable-next-line no-throw-literal 1148 () => { throw 'foo'; }, 1149 'foo' 1150 ), 1151 { 1152 code: 'ERR_AMBIGUOUS_ARGUMENT', 1153 message: 'The "error/message" argument is ambiguous. ' + 1154 'The error "foo" is identical to the message.' 1155 } 1156); 1157 1158assert.throws( 1159 () => a.throws( 1160 () => { throw new TypeError('foo'); }, 1161 'foo' 1162 ), 1163 { 1164 code: 'ERR_AMBIGUOUS_ARGUMENT', 1165 message: 'The "error/message" argument is ambiguous. ' + 1166 'The error message "foo" is identical to the message.' 1167 } 1168); 1169/* eslint-enable no-restricted-syntax */ 1170 1171// Should not throw. 1172// eslint-disable-next-line no-restricted-syntax, no-throw-literal 1173assert.throws(() => { throw null; }, 'foo'); 1174 1175assert.throws( 1176 () => assert.strictEqual([], []), 1177 { 1178 message: 'Values have same structure but are not reference-equal:\n\n[]\n' 1179 } 1180); 1181 1182{ 1183 const args = (function() { return arguments; })('a'); 1184 assert.throws( 1185 () => assert.strictEqual(args, { 0: 'a' }), 1186 { 1187 message: 'Expected "actual" to be reference-equal to "expected":\n' + 1188 '+ actual - expected\n\n' + 1189 "+ [Arguments] {\n- {\n '0': 'a'\n }" 1190 } 1191 ); 1192} 1193 1194assert.throws( 1195 () => { throw new TypeError('foobar'); }, 1196 { 1197 message: /foo/, 1198 name: /^TypeError$/ 1199 } 1200); 1201 1202assert.throws( 1203 () => assert.throws( 1204 () => { throw new TypeError('foobar'); }, 1205 { 1206 message: /fooa/, 1207 name: /^TypeError$/ 1208 } 1209 ), 1210 { 1211 message: `${start}\n${actExp}\n\n` + 1212 ' Comparison {\n' + 1213 "+ message: 'foobar',\n" + 1214 '- message: /fooa/,\n' + 1215 " name: 'TypeError'\n" + 1216 ' }' 1217 } 1218); 1219 1220{ 1221 let actual = null; 1222 const expected = { message: 'foo' }; 1223 assert.throws( 1224 () => assert.throws( 1225 () => { throw actual; }, 1226 expected 1227 ), 1228 { 1229 operator: 'throws', 1230 actual, 1231 expected, 1232 generatedMessage: true, 1233 message: `${start}\n${actExp}\n\n` + 1234 '+ null\n' + 1235 '- {\n' + 1236 "- message: 'foo'\n" + 1237 '- }' 1238 } 1239 ); 1240 1241 actual = 'foobar'; 1242 const message = 'message'; 1243 assert.throws( 1244 () => assert.throws( 1245 () => { throw actual; }, 1246 { message: 'foobar' }, 1247 message 1248 ), 1249 { 1250 actual, 1251 message, 1252 operator: 'throws', 1253 generatedMessage: false 1254 } 1255 ); 1256} 1257 1258// Indicate where the strings diverge. 1259assert.throws( 1260 () => assert.strictEqual('test test', 'test foobar'), 1261 { 1262 code: 'ERR_ASSERTION', 1263 name: 'AssertionError', 1264 message: strictEqualMessageStart + 1265 '+ actual - expected\n\n' + 1266 "+ 'test test'\n" + 1267 "- 'test foobar'\n" + 1268 ' ^' 1269 } 1270); 1271 1272// Check for reference-equal objects in `notStrictEqual()` 1273assert.throws( 1274 () => { 1275 const obj = {}; 1276 assert.notStrictEqual(obj, obj); 1277 }, 1278 { 1279 code: 'ERR_ASSERTION', 1280 name: 'AssertionError', 1281 message: 'Expected "actual" not to be reference-equal to "expected": {}' 1282 } 1283); 1284 1285assert.throws( 1286 () => { 1287 const obj = { a: true }; 1288 assert.notStrictEqual(obj, obj); 1289 }, 1290 { 1291 code: 'ERR_ASSERTION', 1292 name: 'AssertionError', 1293 message: 'Expected "actual" not to be reference-equal to "expected":\n\n' + 1294 '{\n a: true\n}\n' 1295 } 1296); 1297 1298{ 1299 let threw = false; 1300 try { 1301 // eslint-disable-next-line no-restricted-syntax 1302 assert.deepStrictEqual(Array(100).fill(1), 'foobar'); 1303 } catch (err) { 1304 threw = true; 1305 assert.match(inspect(err), /actual: \[Array],\n {2}expected: 'foobar',/); 1306 } 1307 assert(threw); 1308} 1309 1310assert.throws( 1311 () => a.equal(1), 1312 { code: 'ERR_MISSING_ARGS' } 1313); 1314 1315assert.throws( 1316 () => a.deepEqual(/a/), 1317 { code: 'ERR_MISSING_ARGS' } 1318); 1319 1320assert.throws( 1321 () => a.notEqual(null), 1322 { code: 'ERR_MISSING_ARGS' } 1323); 1324 1325assert.throws( 1326 () => a.notDeepEqual('test'), 1327 { code: 'ERR_MISSING_ARGS' } 1328); 1329 1330assert.throws( 1331 () => a.strictEqual({}), 1332 { code: 'ERR_MISSING_ARGS' } 1333); 1334 1335assert.throws( 1336 () => a.deepStrictEqual(Symbol()), 1337 { code: 'ERR_MISSING_ARGS' } 1338); 1339 1340assert.throws( 1341 () => a.notStrictEqual(5n), // eslint-disable-line no-restricted-syntax 1342 { code: 'ERR_MISSING_ARGS' } 1343); 1344 1345assert.throws( 1346 () => a.notDeepStrictEqual(undefined), 1347 { code: 'ERR_MISSING_ARGS' } 1348); 1349 1350assert.throws( 1351 () => a.strictEqual(), 1352 { code: 'ERR_MISSING_ARGS' } 1353); 1354 1355assert.throws( 1356 () => a.deepStrictEqual(), 1357 { code: 'ERR_MISSING_ARGS' } 1358); 1359 1360// Verify that `stackStartFunction` works as alternative to `stackStartFn`. 1361{ 1362 (function hidden() { 1363 const err = new assert.AssertionError({ 1364 actual: 'foo', 1365 operator: 'strictEqual', 1366 stackStartFunction: hidden 1367 }); 1368 const err2 = new assert.AssertionError({ 1369 actual: 'foo', 1370 operator: 'strictEqual', 1371 stackStartFn: hidden 1372 }); 1373 assert(!err.stack.includes('hidden')); 1374 assert(!err2.stack.includes('hidden')); 1375 })(); 1376} 1377 1378assert.throws( 1379 () => assert.throws(() => { throw Symbol('foo'); }, RangeError), 1380 { 1381 message: 'The error is expected to be an instance of "RangeError". ' + 1382 'Received "Symbol(foo)"' 1383 } 1384); 1385 1386assert.throws( 1387 // eslint-disable-next-line no-throw-literal 1388 () => assert.throws(() => { throw [1, 2]; }, RangeError), 1389 { 1390 message: 'The error is expected to be an instance of "RangeError". ' + 1391 'Received "[Array]"' 1392 } 1393); 1394 1395{ 1396 const err = new TypeError('foo'); 1397 const validate = (() => () => ({ a: true, b: [ 1, 2, 3 ] }))(); 1398 assert.throws( 1399 () => assert.throws(() => { throw err; }, validate), 1400 { 1401 message: 'The validation function is expected to ' + 1402 `return "true". Received ${inspect(validate())}\n\nCaught ` + 1403 `error:\n\n${err}`, 1404 code: 'ERR_ASSERTION', 1405 actual: err, 1406 expected: validate, 1407 name: 'AssertionError', 1408 operator: 'throws', 1409 } 1410 ); 1411} 1412 1413assert.throws( 1414 () => { 1415 const script = new vm.Script('new RangeError("foobar");'); 1416 const context = vm.createContext(); 1417 const err = script.runInContext(context); 1418 assert.throws(() => { throw err; }, RangeError); 1419 }, 1420 { 1421 message: 'The error is expected to be an instance of "RangeError". ' + 1422 'Received an error with identical name but a different ' + 1423 'prototype.\n\nError message:\n\nfoobar' 1424 } 1425); 1426 1427// Multiple assert.match() tests. 1428{ 1429 assert.throws( 1430 () => assert.match(/abc/, 'string'), 1431 { 1432 code: 'ERR_INVALID_ARG_TYPE', 1433 message: 'The "regexp" argument must be an instance of RegExp. ' + 1434 "Received type string ('string')" 1435 } 1436 ); 1437 assert.throws( 1438 () => assert.match('string', /abc/), 1439 { 1440 actual: 'string', 1441 expected: /abc/, 1442 operator: 'match', 1443 message: 'The input did not match the regular expression /abc/. ' + 1444 "Input:\n\n'string'\n", 1445 generatedMessage: true 1446 } 1447 ); 1448 assert.throws( 1449 () => assert.match('string', /abc/, 'foobar'), 1450 { 1451 actual: 'string', 1452 expected: /abc/, 1453 operator: 'match', 1454 message: 'foobar', 1455 generatedMessage: false 1456 } 1457 ); 1458 const errorMessage = new RangeError('foobar'); 1459 assert.throws( 1460 () => assert.match('string', /abc/, errorMessage), 1461 errorMessage 1462 ); 1463 assert.throws( 1464 () => assert.match({ abc: 123 }, /abc/), 1465 { 1466 actual: { abc: 123 }, 1467 expected: /abc/, 1468 operator: 'match', 1469 message: 'The "string" argument must be of type string. ' + 1470 'Received type object ({ abc: 123 })', 1471 generatedMessage: true 1472 } 1473 ); 1474 assert.match('I will pass', /pass$/); 1475} 1476 1477// Multiple assert.doesNotMatch() tests. 1478{ 1479 assert.throws( 1480 () => assert.doesNotMatch(/abc/, 'string'), 1481 { 1482 code: 'ERR_INVALID_ARG_TYPE', 1483 message: 'The "regexp" argument must be an instance of RegExp. ' + 1484 "Received type string ('string')" 1485 } 1486 ); 1487 assert.throws( 1488 () => assert.doesNotMatch('string', /string/), 1489 { 1490 actual: 'string', 1491 expected: /string/, 1492 operator: 'doesNotMatch', 1493 message: 'The input was expected to not match the regular expression ' + 1494 "/string/. Input:\n\n'string'\n", 1495 generatedMessage: true 1496 } 1497 ); 1498 assert.throws( 1499 () => assert.doesNotMatch('string', /string/, 'foobar'), 1500 { 1501 actual: 'string', 1502 expected: /string/, 1503 operator: 'doesNotMatch', 1504 message: 'foobar', 1505 generatedMessage: false 1506 } 1507 ); 1508 const errorMessage = new RangeError('foobar'); 1509 assert.throws( 1510 () => assert.doesNotMatch('string', /string/, errorMessage), 1511 errorMessage 1512 ); 1513 assert.throws( 1514 () => assert.doesNotMatch({ abc: 123 }, /abc/), 1515 { 1516 actual: { abc: 123 }, 1517 expected: /abc/, 1518 operator: 'doesNotMatch', 1519 message: 'The "string" argument must be of type string. ' + 1520 'Received type object ({ abc: 123 })', 1521 generatedMessage: true 1522 } 1523 ); 1524 assert.doesNotMatch('I will pass', /different$/); 1525} 1526 1527{ 1528 const tempColor = inspect.defaultOptions.colors; 1529 assert.throws(() => { 1530 inspect.defaultOptions.colors = true; 1531 // Guarantee the position indicator is placed correctly. 1532 assert.strictEqual(111554n, 11111115); 1533 }, (err) => { 1534 assert.strictEqual(inspect(err).split('\n')[5], ' ^'); 1535 inspect.defaultOptions.colors = tempColor; 1536 return true; 1537 }); 1538} 1539