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 () => assert(typeof 123n === 'string'), 731 { 732 code: 'ERR_ASSERTION', 733 constructor: assert.AssertionError, 734 generatedMessage: true, 735 message: 'The expression evaluated to a falsy value:\n\n ' + 736 "assert(typeof 123n === 'string')\n" 737 } 738); 739 740assert.throws( 741 () => assert(false, Symbol('foo')), 742 { 743 code: 'ERR_ASSERTION', 744 constructor: assert.AssertionError, 745 generatedMessage: false, 746 message: 'Symbol(foo)' 747 } 748); 749 750{ 751 // Test caching. 752 const fs = internalBinding('fs'); 753 const tmp = fs.close; 754 fs.close = common.mustCall(tmp, 1); 755 function throwErr() { 756 assert( 757 (Buffer.from('test') instanceof Error) 758 ); 759 } 760 assert.throws( 761 () => throwErr(), 762 { 763 code: 'ERR_ASSERTION', 764 constructor: assert.AssertionError, 765 message: 'The expression evaluated to a falsy value:\n\n ' + 766 "assert(\n (Buffer.from('test') instanceof Error)\n )\n" 767 } 768 ); 769 assert.throws( 770 () => throwErr(), 771 { 772 code: 'ERR_ASSERTION', 773 constructor: assert.AssertionError, 774 message: 'The expression evaluated to a falsy value:\n\n ' + 775 "assert(\n (Buffer.from('test') instanceof Error)\n )\n" 776 } 777 ); 778 fs.close = tmp; 779} 780 781assert.throws( 782 () => { 783 a( 784 (() => 'string')() 785 // eslint-disable-next-line operator-linebreak 786 === 787 123 instanceof 788 Buffer 789 ); 790 }, 791 { 792 code: 'ERR_ASSERTION', 793 constructor: assert.AssertionError, 794 message: 'The expression evaluated to a falsy value:\n\n' + 795 ' a(\n' + 796 ' (() => \'string\')()\n' + 797 ' // eslint-disable-next-line operator-linebreak\n' + 798 ' ===\n' + 799 ' 123 instanceof\n' + 800 ' Buffer\n' + 801 ' )\n' 802 } 803); 804 805assert.throws( 806 () => { 807 a( 808 (() => 'string')() 809 // eslint-disable-next-line operator-linebreak 810 === 811 123 instanceof 812 Buffer 813 ); 814 }, 815 { 816 code: 'ERR_ASSERTION', 817 constructor: assert.AssertionError, 818 message: 'The expression evaluated to a falsy value:\n\n' + 819 ' a(\n' + 820 ' (() => \'string\')()\n' + 821 ' // eslint-disable-next-line operator-linebreak\n' + 822 ' ===\n' + 823 ' 123 instanceof\n' + 824 ' Buffer\n' + 825 ' )\n' 826 } 827); 828 829/* eslint-disable indent */ 830assert.throws(() => { 831a(( 832 () => 'string')() === 833123 instanceof 834Buffer 835); 836}, { 837 code: 'ERR_ASSERTION', 838 constructor: assert.AssertionError, 839 message: 'The expression evaluated to a falsy value:\n\n' + 840 ' a((\n' + 841 ' () => \'string\')() ===\n' + 842 ' 123 instanceof\n' + 843 ' Buffer\n' + 844 ' )\n' 845 } 846); 847/* eslint-enable indent */ 848 849assert.throws( 850 () => { 851 assert(true); assert(null, undefined); 852 }, 853 { 854 code: 'ERR_ASSERTION', 855 constructor: assert.AssertionError, 856 message: 'The expression evaluated to a falsy value:\n\n ' + 857 'assert(null, undefined)\n' 858 } 859); 860 861assert.throws( 862 () => { 863 assert 864 .ok(null, undefined); 865 }, 866 { 867 code: 'ERR_ASSERTION', 868 constructor: assert.AssertionError, 869 message: 'The expression evaluated to a falsy value:\n\n ' + 870 'ok(null, undefined)\n' 871 } 872); 873 874assert.throws( 875 // eslint-disable-next-line dot-notation, quotes 876 () => assert['ok']["apply"](null, [0]), 877 { 878 code: 'ERR_ASSERTION', 879 constructor: assert.AssertionError, 880 message: 'The expression evaluated to a falsy value:\n\n ' + 881 'assert[\'ok\']["apply"](null, [0])\n' 882 } 883); 884 885assert.throws( 886 () => { 887 const wrapper = (fn, value) => fn(value); 888 wrapper(assert, false); 889 }, 890 { 891 code: 'ERR_ASSERTION', 892 constructor: assert.AssertionError, 893 message: 'The expression evaluated to a falsy value:\n\n fn(value)\n' 894 } 895); 896 897assert.throws( 898 () => assert.ok.call(null, 0), 899 { 900 code: 'ERR_ASSERTION', 901 constructor: assert.AssertionError, 902 message: 'The expression evaluated to a falsy value:\n\n ' + 903 'assert.ok.call(null, 0)\n', 904 generatedMessage: true 905 } 906); 907 908assert.throws( 909 () => assert.ok.call(null, 0, 'test'), 910 { 911 code: 'ERR_ASSERTION', 912 constructor: assert.AssertionError, 913 message: 'test', 914 generatedMessage: false 915 } 916); 917 918// Works in eval. 919assert.throws( 920 () => new Function('assert', 'assert(1 === 2);')(assert), 921 { 922 code: 'ERR_ASSERTION', 923 constructor: assert.AssertionError, 924 message: 'The expression evaluated to a falsy value:\n\n assert(1 === 2)\n' 925 } 926); 927assert.throws( 928 () => eval('console.log("FOO");\nassert.ok(1 === 2);'), 929 { 930 code: 'ERR_ASSERTION', 931 message: 'false == true' 932 } 933); 934 935assert.throws( 936 () => assert.throws(() => {}, 'Error message', 'message'), 937 { 938 code: 'ERR_INVALID_ARG_TYPE', 939 name: 'TypeError', 940 message: 'The "error" argument must be of type function or ' + 941 'an instance of Error, RegExp, or Object. Received type string ' + 942 "('Error message')" 943 } 944); 945 946[ 947 1, 948 false, 949 Symbol(), 950].forEach((input) => { 951 assert.throws( 952 () => assert.throws(() => {}, input), 953 { 954 code: 'ERR_INVALID_ARG_TYPE', 955 message: 'The "error" argument must be of type function or ' + 956 'an instance of Error, RegExp, or Object.' + 957 common.invalidArgTypeHelper(input) 958 } 959 ); 960}); 961 962{ 963 964 assert.throws(() => { 965 assert.ok((() => Boolean('' === false))()); 966 }, { 967 message: 'The expression evaluated to a falsy value:\n\n' + 968 " assert.ok((() => Boolean('\\u0001' === false))())\n" 969 }); 970 971 const errFn = () => { 972 const err = new TypeError('Wrong value'); 973 err.code = 404; 974 throw err; 975 }; 976 const errObj = { 977 name: 'TypeError', 978 message: 'Wrong value' 979 }; 980 assert.throws(errFn, errObj); 981 982 errObj.code = 404; 983 assert.throws(errFn, errObj); 984 985 // Fail in case a expected property is undefined and not existent on the 986 // error. 987 errObj.foo = undefined; 988 assert.throws( 989 () => assert.throws(errFn, errObj), 990 { 991 code: 'ERR_ASSERTION', 992 name: 'AssertionError', 993 message: `${start}\n${actExp}\n\n` + 994 ' Comparison {\n' + 995 ' code: 404,\n' + 996 '- foo: undefined,\n' + 997 " message: 'Wrong value',\n" + 998 " name: 'TypeError'\n" + 999 ' }' 1000 } 1001 ); 1002 1003 // Show multiple wrong properties at the same time. 1004 errObj.code = '404'; 1005 assert.throws( 1006 () => assert.throws(errFn, errObj), 1007 { 1008 code: 'ERR_ASSERTION', 1009 name: 'AssertionError', 1010 message: `${start}\n${actExp}\n\n` + 1011 ' Comparison {\n' + 1012 '+ code: 404,\n' + 1013 "- code: '404',\n" + 1014 '- foo: undefined,\n' + 1015 " message: 'Wrong value',\n" + 1016 " name: 'TypeError'\n" + 1017 ' }' 1018 } 1019 ); 1020 1021 assert.throws( 1022 () => assert.throws(() => { throw new Error(); }, { foo: 'bar' }, 'foobar'), 1023 { 1024 constructor: assert.AssertionError, 1025 code: 'ERR_ASSERTION', 1026 message: 'foobar' 1027 } 1028 ); 1029 1030 assert.throws( 1031 () => a.doesNotThrow(() => { throw new Error(); }, { foo: 'bar' }), 1032 { 1033 name: 'TypeError', 1034 code: 'ERR_INVALID_ARG_TYPE', 1035 message: 'The "expected" argument must be of type function or an ' + 1036 'instance of RegExp. Received an instance of Object' 1037 } 1038 ); 1039 1040 assert.throws(() => { throw new Error('e'); }, new Error('e')); 1041 assert.throws( 1042 () => assert.throws(() => { throw new TypeError('e'); }, new Error('e')), 1043 { 1044 name: 'AssertionError', 1045 code: 'ERR_ASSERTION', 1046 message: `${start}\n${actExp}\n\n` + 1047 ' Comparison {\n' + 1048 " message: 'e',\n" + 1049 "+ name: 'TypeError'\n" + 1050 "- name: 'Error'\n" + 1051 ' }' 1052 } 1053 ); 1054 assert.throws( 1055 () => assert.throws(() => { throw new Error('foo'); }, new Error('')), 1056 { 1057 name: 'AssertionError', 1058 code: 'ERR_ASSERTION', 1059 generatedMessage: true, 1060 message: `${start}\n${actExp}\n\n` + 1061 ' Comparison {\n' + 1062 "+ message: 'foo',\n" + 1063 "- message: '',\n" + 1064 " name: 'Error'\n" + 1065 ' }' 1066 } 1067 ); 1068 1069 // eslint-disable-next-line no-throw-literal 1070 assert.throws(() => { throw undefined; }, /undefined/); 1071 assert.throws( 1072 // eslint-disable-next-line no-throw-literal 1073 () => a.doesNotThrow(() => { throw undefined; }), 1074 { 1075 name: 'AssertionError', 1076 code: 'ERR_ASSERTION', 1077 message: 'Got unwanted exception.\nActual message: "undefined"' 1078 } 1079 ); 1080} 1081 1082assert.throws( 1083 () => assert.throws(() => { throw new Error(); }, {}), 1084 { 1085 message: "The argument 'error' may not be an empty object. Received {}", 1086 code: 'ERR_INVALID_ARG_VALUE' 1087 } 1088); 1089 1090assert.throws( 1091 () => a.throws( 1092 // eslint-disable-next-line no-throw-literal 1093 () => { throw 'foo'; }, 1094 'foo' 1095 ), 1096 { 1097 code: 'ERR_AMBIGUOUS_ARGUMENT', 1098 message: 'The "error/message" argument is ambiguous. ' + 1099 'The error "foo" is identical to the message.' 1100 } 1101); 1102 1103assert.throws( 1104 () => a.throws( 1105 () => { throw new TypeError('foo'); }, 1106 'foo' 1107 ), 1108 { 1109 code: 'ERR_AMBIGUOUS_ARGUMENT', 1110 message: 'The "error/message" argument is ambiguous. ' + 1111 'The error message "foo" is identical to the message.' 1112 } 1113); 1114/* eslint-enable no-restricted-syntax */ 1115 1116// Should not throw. 1117// eslint-disable-next-line no-restricted-syntax, no-throw-literal 1118assert.throws(() => { throw null; }, 'foo'); 1119 1120assert.throws( 1121 () => assert.strictEqual([], []), 1122 { 1123 message: 'Values have same structure but are not reference-equal:\n\n[]\n' 1124 } 1125); 1126 1127{ 1128 const args = (function() { return arguments; })('a'); 1129 assert.throws( 1130 () => assert.strictEqual(args, { 0: 'a' }), 1131 { 1132 message: 'Expected "actual" to be reference-equal to "expected":\n' + 1133 '+ actual - expected\n\n' + 1134 "+ [Arguments] {\n- {\n '0': 'a'\n }" 1135 } 1136 ); 1137} 1138 1139assert.throws( 1140 () => { throw new TypeError('foobar'); }, 1141 { 1142 message: /foo/, 1143 name: /^TypeError$/ 1144 } 1145); 1146 1147assert.throws( 1148 () => assert.throws( 1149 () => { throw new TypeError('foobar'); }, 1150 { 1151 message: /fooa/, 1152 name: /^TypeError$/ 1153 } 1154 ), 1155 { 1156 message: `${start}\n${actExp}\n\n` + 1157 ' Comparison {\n' + 1158 "+ message: 'foobar',\n" + 1159 '- message: /fooa/,\n' + 1160 " name: 'TypeError'\n" + 1161 ' }' 1162 } 1163); 1164 1165{ 1166 let actual = null; 1167 const expected = { message: 'foo' }; 1168 assert.throws( 1169 () => assert.throws( 1170 () => { throw actual; }, 1171 expected 1172 ), 1173 { 1174 operator: 'throws', 1175 actual, 1176 expected, 1177 generatedMessage: true, 1178 message: `${start}\n${actExp}\n\n` + 1179 '+ null\n' + 1180 '- {\n' + 1181 "- message: 'foo'\n" + 1182 '- }' 1183 } 1184 ); 1185 1186 actual = 'foobar'; 1187 const message = 'message'; 1188 assert.throws( 1189 () => assert.throws( 1190 () => { throw actual; }, 1191 { message: 'foobar' }, 1192 message 1193 ), 1194 { 1195 actual, 1196 message, 1197 operator: 'throws', 1198 generatedMessage: false 1199 } 1200 ); 1201} 1202 1203// Indicate where the strings diverge. 1204assert.throws( 1205 () => assert.strictEqual('test test', 'test foobar'), 1206 { 1207 code: 'ERR_ASSERTION', 1208 name: 'AssertionError', 1209 message: strictEqualMessageStart + 1210 '+ actual - expected\n\n' + 1211 "+ 'test test'\n" + 1212 "- 'test foobar'\n" + 1213 ' ^' 1214 } 1215); 1216 1217// Check for reference-equal objects in `notStrictEqual()` 1218assert.throws( 1219 () => { 1220 const obj = {}; 1221 assert.notStrictEqual(obj, obj); 1222 }, 1223 { 1224 code: 'ERR_ASSERTION', 1225 name: 'AssertionError', 1226 message: 'Expected "actual" not to be reference-equal to "expected": {}' 1227 } 1228); 1229 1230assert.throws( 1231 () => { 1232 const obj = { a: true }; 1233 assert.notStrictEqual(obj, obj); 1234 }, 1235 { 1236 code: 'ERR_ASSERTION', 1237 name: 'AssertionError', 1238 message: 'Expected "actual" not to be reference-equal to "expected":\n\n' + 1239 '{\n a: true\n}\n' 1240 } 1241); 1242 1243{ 1244 let threw = false; 1245 try { 1246 assert.deepStrictEqual(Array(100).fill(1), 'foobar'); 1247 } catch (err) { 1248 threw = true; 1249 assert(/actual: \[Array],\n expected: 'foobar',/.test(inspect(err))); 1250 } 1251 assert(threw); 1252} 1253 1254assert.throws( 1255 () => a.equal(1), 1256 { code: 'ERR_MISSING_ARGS' } 1257); 1258 1259assert.throws( 1260 () => a.deepEqual(/a/), 1261 { code: 'ERR_MISSING_ARGS' } 1262); 1263 1264assert.throws( 1265 () => a.notEqual(null), 1266 { code: 'ERR_MISSING_ARGS' } 1267); 1268 1269assert.throws( 1270 () => a.notDeepEqual('test'), 1271 { code: 'ERR_MISSING_ARGS' } 1272); 1273 1274assert.throws( 1275 () => a.strictEqual({}), 1276 { code: 'ERR_MISSING_ARGS' } 1277); 1278 1279assert.throws( 1280 () => a.deepStrictEqual(Symbol()), 1281 { code: 'ERR_MISSING_ARGS' } 1282); 1283 1284assert.throws( 1285 () => a.notStrictEqual(5n), // eslint-disable-line no-restricted-syntax 1286 { code: 'ERR_MISSING_ARGS' } 1287); 1288 1289assert.throws( 1290 () => a.notDeepStrictEqual(undefined), 1291 { code: 'ERR_MISSING_ARGS' } 1292); 1293 1294assert.throws( 1295 () => a.strictEqual(), 1296 { code: 'ERR_MISSING_ARGS' } 1297); 1298 1299assert.throws( 1300 () => a.deepStrictEqual(), 1301 { code: 'ERR_MISSING_ARGS' } 1302); 1303 1304// Verify that `stackStartFunction` works as alternative to `stackStartFn`. 1305{ 1306 (function hidden() { 1307 const err = new assert.AssertionError({ 1308 actual: 'foo', 1309 operator: 'strictEqual', 1310 stackStartFunction: hidden 1311 }); 1312 const err2 = new assert.AssertionError({ 1313 actual: 'foo', 1314 operator: 'strictEqual', 1315 stackStartFn: hidden 1316 }); 1317 assert(!err.stack.includes('hidden')); 1318 assert(!err2.stack.includes('hidden')); 1319 })(); 1320} 1321 1322assert.throws( 1323 () => assert.throws(() => { throw Symbol('foo'); }, RangeError), 1324 { 1325 message: 'The error is expected to be an instance of "RangeError". ' + 1326 'Received "Symbol(foo)"' 1327 } 1328); 1329 1330assert.throws( 1331 // eslint-disable-next-line no-throw-literal 1332 () => assert.throws(() => { throw [1, 2]; }, RangeError), 1333 { 1334 message: 'The error is expected to be an instance of "RangeError". ' + 1335 'Received "[Array]"' 1336 } 1337); 1338 1339{ 1340 const err = new TypeError('foo'); 1341 const validate = (() => () => ({ a: true, b: [ 1, 2, 3 ] }))(); 1342 assert.throws( 1343 () => assert.throws(() => { throw err; }, validate), 1344 { 1345 message: 'The validation function is expected to ' + 1346 `return "true". Received ${inspect(validate())}\n\nCaught ` + 1347 `error:\n\n${err}`, 1348 code: 'ERR_ASSERTION', 1349 actual: err, 1350 expected: validate, 1351 name: 'AssertionError', 1352 operator: 'throws', 1353 } 1354 ); 1355} 1356 1357assert.throws( 1358 () => { 1359 const script = new vm.Script('new RangeError("foobar");'); 1360 const context = vm.createContext(); 1361 const err = script.runInContext(context); 1362 assert.throws(() => { throw err; }, RangeError); 1363 }, 1364 { 1365 message: 'The error is expected to be an instance of "RangeError". ' + 1366 'Received an error with identical name but a different ' + 1367 'prototype.\n\nError message:\n\nfoobar' 1368 } 1369); 1370 1371// Multiple assert.match() tests. 1372{ 1373 assert.throws( 1374 () => assert.match(/abc/, 'string'), 1375 { 1376 code: 'ERR_INVALID_ARG_TYPE', 1377 message: 'The "regexp" argument must be an instance of RegExp. ' + 1378 "Received type string ('string')" 1379 } 1380 ); 1381 assert.throws( 1382 () => assert.match('string', /abc/), 1383 { 1384 actual: 'string', 1385 expected: /abc/, 1386 operator: 'match', 1387 message: 'The input did not match the regular expression /abc/. ' + 1388 "Input:\n\n'string'\n", 1389 generatedMessage: true 1390 } 1391 ); 1392 assert.throws( 1393 () => assert.match('string', /abc/, 'foobar'), 1394 { 1395 actual: 'string', 1396 expected: /abc/, 1397 operator: 'match', 1398 message: 'foobar', 1399 generatedMessage: false 1400 } 1401 ); 1402 const errorMessage = new RangeError('foobar'); 1403 assert.throws( 1404 () => assert.match('string', /abc/, errorMessage), 1405 errorMessage 1406 ); 1407 assert.throws( 1408 () => assert.match({ abc: 123 }, /abc/), 1409 { 1410 actual: { abc: 123 }, 1411 expected: /abc/, 1412 operator: 'match', 1413 message: 'The "string" argument must be of type string. ' + 1414 'Received type object ({ abc: 123 })', 1415 generatedMessage: true 1416 } 1417 ); 1418 assert.match('I will pass', /pass$/); 1419} 1420 1421// Multiple assert.doesNotMatch() tests. 1422{ 1423 assert.throws( 1424 () => assert.doesNotMatch(/abc/, 'string'), 1425 { 1426 code: 'ERR_INVALID_ARG_TYPE', 1427 message: 'The "regexp" argument must be an instance of RegExp. ' + 1428 "Received type string ('string')" 1429 } 1430 ); 1431 assert.throws( 1432 () => assert.doesNotMatch('string', /string/), 1433 { 1434 actual: 'string', 1435 expected: /string/, 1436 operator: 'doesNotMatch', 1437 message: 'The input was expected to not match the regular expression ' + 1438 "/string/. Input:\n\n'string'\n", 1439 generatedMessage: true 1440 } 1441 ); 1442 assert.throws( 1443 () => assert.doesNotMatch('string', /string/, 'foobar'), 1444 { 1445 actual: 'string', 1446 expected: /string/, 1447 operator: 'doesNotMatch', 1448 message: 'foobar', 1449 generatedMessage: false 1450 } 1451 ); 1452 const errorMessage = new RangeError('foobar'); 1453 assert.throws( 1454 () => assert.doesNotMatch('string', /string/, errorMessage), 1455 errorMessage 1456 ); 1457 assert.throws( 1458 () => assert.doesNotMatch({ abc: 123 }, /abc/), 1459 { 1460 actual: { abc: 123 }, 1461 expected: /abc/, 1462 operator: 'doesNotMatch', 1463 message: 'The "string" argument must be of type string. ' + 1464 'Received type object ({ abc: 123 })', 1465 generatedMessage: true 1466 } 1467 ); 1468 assert.doesNotMatch('I will pass', /different$/); 1469} 1470 1471{ 1472 const tempColor = inspect.defaultOptions.colors; 1473 assert.throws(() => { 1474 inspect.defaultOptions.colors = true; 1475 // Guarantee the position indicator is placed correctly. 1476 assert.strictEqual(111554n, 11111115); 1477 }, (err) => { 1478 assert.strictEqual(inspect(err).split('\n')[5], ' ^'); 1479 inspect.defaultOptions.colors = tempColor; 1480 return true; 1481 }); 1482} 1483