From c316eef97add24ea1980da46bd6ad3b68990d23e Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 26 Aug 2024 21:05:07 -0700 Subject: [PATCH] test: update test-assert to use node:test PR-URL: https://github.com/nodejs/node/pull/54585 Reviewed-By: Yagiz Nizipli Reviewed-By: Colin Ihrig --- test/parallel/test-assert-strict-exists.js | 6 - test/parallel/test-assert.js | 1836 ++++++++++---------- 2 files changed, 912 insertions(+), 930 deletions(-) delete mode 100644 test/parallel/test-assert-strict-exists.js diff --git a/test/parallel/test-assert-strict-exists.js b/test/parallel/test-assert-strict-exists.js deleted file mode 100644 index 50cd8a49a70aa5..00000000000000 --- a/test/parallel/test-assert-strict-exists.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict'; - -require('../common'); -const assert = require('assert'); - -assert.strictEqual(require('assert/strict'), assert.strict); diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index 1679edb2941808..b5e5bb1c9b0a29 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -21,11 +21,11 @@ 'use strict'; -const common = require('../common'); +const { invalidArgTypeHelper } = require('../common'); const assert = require('assert'); const { inspect } = require('util'); +const { test } = require('node:test'); const vm = require('vm'); -const a = assert; // Disable colored output to prevent color codes from breaking assertion // message comparisons. This should only be an issue when process.stdout @@ -37,14 +37,31 @@ 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)'); +/* eslint-disable no-restricted-syntax */ +/* eslint-disable no-restricted-properties */ + +test('some basics', () => { + assert.ok(assert.AssertionError.prototype instanceof Error, + 'assert.AssertionError instanceof Error'); + + assert.throws(() => assert(false), assert.AssertionError, 'ok(false)'); + assert.throws(() => assert.ok(false), assert.AssertionError, 'ok(false)'); + assert(true); + assert('test', 'ok(\'test\')'); + assert.ok(true); + assert.ok('test'); + assert.throws(() => assert.equal(true, false), + assert.AssertionError, 'equal(true, false)'); + assert.equal(null, null); + assert.equal(undefined, undefined); + assert.equal(null, undefined); + assert.equal(true, true); + assert.equal(2, '2'); + assert.notEqual(true, false); + assert.notStrictEqual(2, '2'); +}); -// Throw message if the message is instanceof Error. -{ +test('Throw message if the message is instanceof Error', () => { let threw = false; try { assert.ok(false, new Error('ok(false)')); @@ -53,10 +70,9 @@ assert.throws(() => a.ok(false), a.AssertionError, 'ok(false)'); assert.ok(e instanceof Error); } assert.ok(threw, 'Error: ok(false)'); -} +}); -// Errors created in different contexts are handled as any other custom error -{ +test('Errors created in different contexts are handled as any other custom error', () => { const context = vm.createContext(); const error = vm.runInContext('new SyntaxError("custom error")', context); @@ -64,219 +80,213 @@ assert.throws(() => a.ok(false), a.AssertionError, 'ok(false)'); message: 'custom error', name: 'SyntaxError' }); -} +}); -a(true); -a('test', 'ok(\'test\')'); -a.ok(true); -a.ok('test'); +test('assert.throws()', () => { + assert.throws(() => assert.notEqual(true, true), + assert.AssertionError, 'notEqual(true, true)'); -assert.throws(() => a.equal(true, false), - a.AssertionError, 'equal(true, false)'); + assert.throws(() => assert.strictEqual(2, '2'), + assert.AssertionError, 'strictEqual(2, \'2\')'); -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(() => assert.strictEqual(null, undefined), + assert.AssertionError, 'strictEqual(null, undefined)'); -assert.throws(() => a.notEqual(true, true), - a.AssertionError, 'notEqual(true, true)'); + assert.throws( + () => assert.notStrictEqual(2, 2), + { + message: 'Expected "actual" to be strictly unequal to: 2', + name: 'AssertionError' + } + ); -assert.throws(() => a.strictEqual(2, '2'), - a.AssertionError, 'strictEqual(2, \'2\')'); + assert.throws( + () => assert.notStrictEqual('a '.repeat(30), 'a '.repeat(30)), + { + message: 'Expected "actual" to be strictly unequal to:\n\n' + + `'${'a '.repeat(30)}'`, + name: 'AssertionError' + } + ); -/* eslint-disable no-restricted-syntax */ -assert.throws(() => a.strictEqual(null, undefined), - a.AssertionError, 'strictEqual(null, undefined)'); + assert.throws( + () => assert.notEqual(1, 1), + { + message: '1 != 1', + operator: '!=' + } + ); -assert.throws( - () => a.notStrictEqual(2, 2), - { - message: 'Expected "actual" to be strictly unequal to: 2', - name: 'AssertionError' + // Testing the throwing. + function thrower(errorConstructor) { + throw new errorConstructor({}); } -); -assert.throws( - () => a.notStrictEqual('a '.repeat(30), 'a '.repeat(30)), + // The basic calls work. + assert.throws(() => thrower(assert.AssertionError), assert.AssertionError, 'message'); + assert.throws(() => thrower(assert.AssertionError), assert.AssertionError); + assert.throws(() => thrower(assert.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( + () => assert.throws(() => thrower(TypeError), assert.AssertionError), + { + generatedMessage: true, + actual: new TypeError({}), + expected: assert.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. { - message: 'Expected "actual" to be strictly unequal to:\n\n' + - `'${'a '.repeat(30)}'`, - name: 'AssertionError' + let threw = false; + try { + assert.doesNotThrow(() => thrower(TypeError), assert.AssertionError); + } catch (e) { + threw = true; + assert.ok(e instanceof TypeError); + } + assert(threw, 'assert.doesNotThrow with an explicit error is eating extra errors'); } -); -assert.throws( - () => a.notEqual(1, 1), + // Key difference is that throwing our correct error makes an assertion error. { - message: '1 != 1', - operator: '!=' + let threw = false; + try { + assert.doesNotThrow(() => thrower(TypeError), TypeError); + } catch (e) { + threw = true; + assert.ok(e instanceof assert.AssertionError); + assert.ok(!e.stack.includes('at Function.doesNotThrow')); + } + assert.ok(threw, 'assert.doesNotThrow is not catching type matching errors'); } -); -a.notStrictEqual(2, '2'); - -// Testing the throwing. -function thrower(errorConstructor) { - throw new errorConstructor({}); -} + assert.throws( + () => assert.doesNotThrow(() => thrower(Error), 'user message'), + { + name: 'AssertionError', + code: 'ERR_ASSERTION', + operator: 'doesNotThrow', + message: 'Got unwanted exception: user message\n' + + 'Actual message: "[object Object]"' + } + ); -// The basic calls work. -assert.throws(() => thrower(a.AssertionError), a.AssertionError, 'message'); -assert.throws(() => thrower(a.AssertionError), a.AssertionError); -assert.throws(() => thrower(a.AssertionError)); + assert.throws( + () => assert.doesNotThrow(() => thrower(Error)), + { + code: 'ERR_ASSERTION', + message: 'Got unwanted exception.\nActual message: "[object Object]"' + } + ); -// If not passing an error, catch all. -assert.throws(() => thrower(TypeError)); + assert.throws( + () => assert.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]"' + } + ); -// When passing a type, only catch errors of the appropriate type. -assert.throws( - () => a.throws(() => thrower(TypeError), a.AssertionError), + // Make sure that validating using constructor really works. { - 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]' + let threw = false; + try { + assert.throws( + () => { + throw ({}); // eslint-disable-line no-throw-literal + }, + Array + ); + } catch { + threw = true; + } + assert.ok(threw, 'wrong constructor validation'); } -); -// 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'); -} + // Use a RegExp to validate the error message. + { + assert.throws(() => thrower(TypeError), /\[object Object\]/); -// 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); - assert.ok(!e.stack.includes('at Function.doesNotThrow')); - } - assert.ok(threw, 'a.doesNotThrow is not catching type matching errors'); -} + const symbol = Symbol('foo'); + assert.throws(() => { + throw symbol; + }, /foo/); -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(() => { + assert.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/ + }); } -); -assert.throws( - () => a.doesNotThrow(() => thrower(Error)), - { - code: 'ERR_ASSERTION', - message: 'Got unwanted exception.\nActual message: "[object Object]"' - } -); + // Use a fn to validate the error object. + assert.throws(() => thrower(TypeError), (err) => { + if ((err instanceof TypeError) && /\[object Object\]/.test(err)) { + return true; + } + }); -assert.throws( - () => a.doesNotThrow(() => thrower(Error), /\[[a-z]{6}\s[A-z]{6}\]/g, 'user message'), + // https://github.com/nodejs/node/issues/3188 { - 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 { + let actual; assert.throws( () => { - throw ({}); // eslint-disable-line no-throw-literal + const ES6Error = class extends Error {}; + const AnotherErrorType = class extends Error {}; + + assert.throws(() => { + actual = new AnotherErrorType('foo'); + throw actual; + }, ES6Error); }, - Array + (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; + } ); - } 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; + () => assert.strictEqual(new Error('foo'), new Error('foobar')), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: 'Expected "actual" to be reference-equal to "expected":\n' + + '+ actual - expected\n\n' + + '+ [Error: foo]\n- [Error: foobar]' } ); -} +}); -// Check messages from assert.throws(). -{ +test('Check messages from assert.throws()', () => { const noop = () => {}; assert.throws( - () => { a.throws((noop)); }, + () => { assert.throws((noop)); }, { code: 'ERR_ASSERTION', message: 'Missing expected exception.', @@ -286,7 +296,7 @@ a.throws(() => thrower(TypeError), (err) => { }); assert.throws( - () => { a.throws(noop, TypeError); }, + () => { assert.throws(noop, TypeError); }, { code: 'ERR_ASSERTION', message: 'Missing expected exception (TypeError).', @@ -295,7 +305,7 @@ a.throws(() => thrower(TypeError), (err) => { }); assert.throws( - () => { a.throws(noop, 'fhqwhgads'); }, + () => { assert.throws(noop, 'fhqwhgads'); }, { code: 'ERR_ASSERTION', message: 'Missing expected exception: fhqwhgads', @@ -304,7 +314,7 @@ a.throws(() => thrower(TypeError), (err) => { }); assert.throws( - () => { a.throws(noop, TypeError, 'fhqwhgads'); }, + () => { assert.throws(noop, TypeError, 'fhqwhgads'); }, { code: 'ERR_ASSERTION', message: 'Missing expected exception (TypeError): fhqwhgads', @@ -314,78 +324,80 @@ a.throws(() => thrower(TypeError), (err) => { let threw = false; try { - a.throws(noop); + assert.throws(noop); } catch (e) { threw = true; - assert.ok(e instanceof a.AssertionError); + assert.ok(e instanceof assert.AssertionError); assert.ok(!e.stack.includes('at Function.throws')); } assert.ok(threw); -} +}); + +test('Test assertion messages', () => { + 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- ''` + } + ); + } -const circular = { y: 1 }; -circular.x = circular; + function testShortAssertionMessage(actual, expected) { + testAssertionMessage(actual, expected, strictEqualMessageStart + + `\n${inspect(actual)} !== ''\n`); + } -function testAssertionMessage(actual, expected, msg) { + 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(actual, ''), + () => assert.strictEqual(1, 2), { - generatedMessage: true, - message: msg || strictEqualMessageStart + - `+ actual - expected\n\n+ ${expected}\n- ''` + message: `${strictEqualMessageStart}\n1 !== 2\n`, + generatedMessage: true } ); -} - -function testShortAssertionMessage(actual, expected) { - testAssertionMessage(actual, expected, strictEqualMessageStart + - `\n${inspect(actual)} !== ''\n`); -} - -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), - { - message: `${strictEqualMessageStart}\n1 !== 2\n`, - generatedMessage: true - } -); -assert.throws( - () => assert.strictEqual(1, 2, 'oh no'), - { - message: 'oh no', - generatedMessage: false - } -); + assert.throws( + () => assert.strictEqual(1, 2, 'oh no'), + { + message: 'oh no', + generatedMessage: false + } + ); +}); -{ +test('Custom errors', () => { let threw = false; const rangeError = new RangeError('my range'); @@ -402,7 +414,7 @@ assert.throws( // Verify AssertionError is the result from doesNotThrow with custom Error. try { - a.doesNotThrow(() => { + assert.doesNotThrow(() => { throw new TypeError('wrong type'); }, TypeError, rangeError); } catch (e) { @@ -412,10 +424,9 @@ assert.throws( assert.ok(!e.stack.includes('doesNotThrow'), e); } assert.ok(threw); -} +}); -{ - // Verify that throws() and doesNotThrow() throw on non-functions. +test('Verify that throws() and doesNotThrow() throw on non-functions', () => { const testBlockTypeError = (method, fn) => { assert.throws( () => method(fn), @@ -423,7 +434,7 @@ assert.throws( code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', message: 'The "fn" argument must be of type function.' + - common.invalidArgTypeHelper(fn) + invalidArgTypeHelper(fn) } ); }; @@ -446,28 +457,29 @@ assert.throws( testBlockTypeError(assert.doesNotThrow, null); testBlockTypeError(assert.throws, undefined); testBlockTypeError(assert.doesNotThrow, undefined); -} - -// https://github.com/nodejs/node/issues/3275 -// eslint-disable-next-line no-throw-literal -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'); - assert.strictEqual(err.message, - `${strictEqualMessageStart}+ actual - expected\n\n` + - `+ '${'A'.repeat(1000)}'\n- ''`); - assert.strictEqual(err.actual.length, 1000); - assert.ok(inspect(err).includes(`actual: '${'A'.repeat(488)}...'`)); - return true; }); -// Output that extends beyond 10 lines should also be truncated for display. -{ +test('https://github.com/nodejs/node/issues/3275', () => { + // eslint-disable-next-line no-throw-literal + assert.throws(() => { throw 'error'; }, (err) => err === 'error'); + assert.throws(() => { throw new Error(); }, (err) => err instanceof Error); +}); + +test('Long values should be truncated for display', () => { + assert.throws(() => { + assert.strictEqual('A'.repeat(1000), ''); + }, (err) => { + assert.strictEqual(err.code, 'ERR_ASSERTION'); + assert.strictEqual(err.message, + `${strictEqualMessageStart}+ actual - expected\n\n` + + `+ '${'A'.repeat(1000)}'\n- ''`); + assert.strictEqual(err.actual.length, 1000); + assert.ok(inspect(err).includes(`actual: '${'A'.repeat(488)}...'`)); + return true; + }); +}); + +test('Output that extends beyond 10 lines should also be truncated for display', () => { const multilineString = 'fhqwhgads\n'.repeat(15); assert.throws(() => { assert.strictEqual(multilineString, ''); @@ -481,10 +493,9 @@ assert.throws(() => { " '...'")); return true; }); -} +}); -{ - // Bad args to AssertionError constructor should throw TypeError. +test('Bad args to AssertionError constructor should throw TypeError.', () => { const args = [1, true, false, '', null, Infinity, Symbol('test'), undefined]; for (const input of args) { assert.throws( @@ -493,54 +504,43 @@ assert.throws(() => { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', message: 'The "options" argument must be of type object.' + - common.invalidArgTypeHelper(input) + invalidArgTypeHelper(input) }); } -} +}); -assert.throws( - () => assert.strictEqual(new Error('foo'), new Error('foobar')), - { - code: 'ERR_ASSERTION', - name: 'AssertionError', - 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; - /* eslint-disable no-restricted-properties */ - 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); +test('NaN is handled correctly', () => { + assert.equal(NaN, NaN); assert.throws( - () => assert(...[]), + () => assert.notEqual(NaN, NaN), + assert.AssertionError + ); +}); + +test('Test strict assert', () => { + const { strict } = require('assert'); + + strict.throws(() => strict.equal(1, true), strict.AssertionError); + strict.notEqual(0, false); + strict.throws(() => strict.deepEqual(1, true), strict.AssertionError); + strict.notDeepEqual(0, false); + strict.equal(strict.strict, strict.strict.strict); + strict.equal(strict.equal, strict.strictEqual); + strict.equal(strict.deepEqual, strict.deepStrictEqual); + strict.equal(strict.notEqual, strict.notStrictEqual); + strict.equal(strict.notDeepEqual, strict.notDeepStrictEqual); + strict.equal(Object.keys(strict).length, Object.keys(assert).length); + strict(7); + strict.throws( + () => strict(...[]), { message: 'No value argument passed to `assert.ok()`', name: 'AssertionError', generatedMessage: true } ); - assert.throws( - () => a(), + strict.throws( + () => assert(), { message: 'No value argument passed to `assert.ok()`', name: 'AssertionError' @@ -550,17 +550,17 @@ a.throws( // Test setting the limit to zero and that assert.strict works properly. const tmpLimit = Error.stackTraceLimit; Error.stackTraceLimit = 0; - assert.throws( + strict.throws( () => { - assert.ok( + strict.ok( typeof 123 === 'string' ); }, { code: 'ERR_ASSERTION', - constructor: assert.AssertionError, + constructor: strict.AssertionError, message: 'The expression evaluated to a falsy value:\n\n ' + - "assert.ok(\n typeof 123 === 'string'\n )\n" + "strict.ok(\n typeof 123 === 'string'\n )\n" } ); Error.stackTraceLimit = tmpLimit; @@ -582,8 +582,8 @@ a.throws( ' 4,', ' 5', ' ]'].join('\n'); - assert.throws( - () => assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]), + strict.throws( + () => strict.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]), { message }); message = [ @@ -602,8 +602,8 @@ a.throws( ' 1', ' ]', ].join('\n'); - assert.throws( - () => assert.deepEqual( + strict.throws( + () => strict.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]), { message }); @@ -623,8 +623,8 @@ a.throws( ' 1', ' ]', ].join('\n'); - assert.throws( - () => assert.deepEqual( + strict.throws( + () => strict.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]), { message }); @@ -644,8 +644,8 @@ a.throws( ' 1', ' ]', ].join('\n'); - assert.throws( - () => assert.deepEqual( + strict.throws( + () => strict.deepEqual( [1, 2, 1, 1, 0, 1, 1], [1, 1, 1, 1, 0, 1]), { message }); @@ -661,8 +661,8 @@ a.throws( '+ ]', '- undefined', ].join('\n'); - assert.throws( - () => assert.deepEqual([1, 2, 1], undefined), + strict.throws( + () => strict.deepEqual([1, 2, 1], undefined), { message }); message = [ @@ -675,8 +675,8 @@ a.throws( ' 1', ' ]', ].join('\n'); - assert.throws( - () => assert.deepEqual([1, 2, 1], [2, 1]), + strict.throws( + () => strict.deepEqual([1, 2, 1], [2, 1]), { message }); message = `${start}\n` + @@ -687,15 +687,15 @@ a.throws( '...\n' + '- 2,\n'.repeat(25) + '...'; - assert.throws( - () => assert.deepEqual(Array(28).fill(1), Array(28).fill(2)), + strict.throws( + () => strict.deepEqual(Array(28).fill(1), Array(28).fill(2)), { message }); const obj1 = {}; const obj2 = { loop: 'forever' }; obj2[inspect.custom] = () => '{}'; // No infinite loop and no custom inspect. - assert.throws(() => assert.deepEqual(obj1, obj2), { + strict.throws(() => strict.deepEqual(obj1, obj2), { message: `${start}\n` + `${actExp}\n` + '\n' + @@ -707,8 +707,8 @@ a.throws( }); // notDeepEqual tests - assert.throws( - () => assert.notDeepEqual([1], [1]), + strict.throws( + () => strict.notDeepEqual([1], [1]), { message: 'Expected "actual" not to be strictly deep-equal to:\n\n' + '[\n 1\n]\n' @@ -718,278 +718,260 @@ a.throws( 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), + strict.throws( + () => strict.notDeepEqual(data, data), { message }); - /* eslint-enable no-restricted-properties */ -} -assert.throws( - () => assert.ok(null), - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - generatedMessage: true, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'assert.ok(null)\n' - } -); -assert.throws( - () => { - // This test case checks if `try` left brace without a line break - // before the assertion causes any wrong assertion message. - // Therefore, don't reformat the following code. - // Refs: https://github.com/nodejs/node/issues/30872 - try { assert.ok(0); // eslint-disable-line no-useless-catch, @stylistic/js/brace-style - } catch (err) { - throw err; +}); + +test('Additional asserts', () => { + assert.throws( + () => assert.ok(null), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + generatedMessage: true, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert.ok(null)\n' } - }, - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - generatedMessage: true, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'assert.ok(0)\n' - } -); -assert.throws( - () => { - try { - throw new Error(); - // This test case checks if `catch` left brace without a line break - // before the assertion causes any wrong assertion message. - // Therefore, don't reformat the following code. - // Refs: https://github.com/nodejs/node/issues/30872 - } catch (err) { assert.ok(0); } // eslint-disable-line no-unused-vars - }, - { + ); + assert.throws( + () => { + // This test case checks if `try` left brace without a line break + // before the assertion causes any wrong assertion message. + // Therefore, don't reformat the following code. + // Refs: https://github.com/nodejs/node/issues/30872 + try { assert.ok(0); // eslint-disable-line no-useless-catch, @stylistic/js/brace-style + } catch (err) { + throw err; + } + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + generatedMessage: true, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert.ok(0)\n' + } + ); + assert.throws( + () => { + try { + throw new Error(); + // This test case checks if `catch` left brace without a line break + // before the assertion causes any wrong assertion message. + // Therefore, don't reformat the following code. + // Refs: https://github.com/nodejs/node/issues/30872 + } catch (err) { assert.ok(0); } // eslint-disable-line no-unused-vars + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + generatedMessage: true, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert.ok(0)\n' + } + ); + assert.throws( + () => { + // This test case checks if `function` left brace without a line break + // before the assertion causes any wrong assertion message. + // Therefore, don't reformat the following code. + // Refs: https://github.com/nodejs/node/issues/30872 + function test() { assert.ok(0); // eslint-disable-line @stylistic/js/brace-style + } + test(); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + generatedMessage: true, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert.ok(0)\n' + } + ); + assert.throws( + () => assert(typeof 123n === 'string'), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + generatedMessage: true, + 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, + generatedMessage: false, + message: 'Symbol(foo)' + } + ); + + assert.throws( + () => { + assert.strictEqual((() => 'string')(), 123 instanceof + Buffer); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'Expected values to be strictly equal:\n' + + '+ actual - expected\n' + + '\n' + + "+ 'string'\n" + + '- false' + } + ); + + assert.throws( + () => { + assert.strictEqual((() => 'string')(), 123 instanceof + Buffer); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'Expected values to be strictly equal:\n' + + '+ actual - expected\n' + + '\n' + + "+ 'string'\n" + + '- false' + } + ); + + /* eslint-disable @stylistic/js/indent */ + assert.throws(() => { + assert.strictEqual(( + () => 'string')(), 123 instanceof + Buffer); + }, { code: 'ERR_ASSERTION', constructor: assert.AssertionError, - generatedMessage: true, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'assert.ok(0)\n' - } -); -assert.throws( - () => { - // This test case checks if `function` left brace without a line break - // before the assertion causes any wrong assertion message. - // Therefore, don't reformat the following code. - // Refs: https://github.com/nodejs/node/issues/30872 - function test() { assert.ok(0); // eslint-disable-line @stylistic/js/brace-style + message: 'Expected values to be strictly equal:\n' + + '+ actual - expected\n' + + '\n' + + "+ 'string'\n" + + '- false' } - test(); - }, - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - generatedMessage: true, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'assert.ok(0)\n' - } -); -assert.throws( - () => assert(typeof 123n === 'string'), - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - generatedMessage: true, - 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, - generatedMessage: false, - message: 'Symbol(foo)' - } -); - -assert.throws( - () => { - a( - (() => 'string')() - // eslint-disable-next-line @stylistic/js/operator-linebreak - === - 123 instanceof - Buffer - ); - }, - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n' + - ' a(\n' + - ' (() => \'string\')()\n' + - ' // eslint-disable-next-line @stylistic/js/operator-linebreak\n' + - ' ===\n' + - ' 123 instanceof\n' + - ' Buffer\n' + - ' )\n' - } -); - -assert.throws( - () => { - a( - (() => 'string')() - // eslint-disable-next-line @stylistic/js/operator-linebreak - === - 123 instanceof - Buffer - ); - }, - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n' + - ' a(\n' + - ' (() => \'string\')()\n' + - ' // eslint-disable-next-line @stylistic/js/operator-linebreak\n' + - ' ===\n' + - ' 123 instanceof\n' + - ' Buffer\n' + - ' )\n' - } -); - -/* eslint-disable @stylistic/js/indent */ -assert.throws(() => { -a(( - () => 'string')() === -123 instanceof -Buffer -); -}, { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n' + - ' a((\n' + - ' () => \'string\')() ===\n' + - ' 123 instanceof\n' + - ' Buffer\n' + - ' )\n' - } -); -/* eslint-enable @stylistic/js/indent */ - -assert.throws( - () => { - assert(true); assert(null, undefined); - }, - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'assert(null, undefined)\n' - } -); + ); + /* eslint-enable @stylistic/js/indent */ -assert.throws( - () => { - assert - .ok(null, undefined); - }, - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'ok(null, undefined)\n' - } -); + assert.throws( + () => { + assert(true); assert(null, undefined); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert(null, undefined)\n' + } + ); -assert.throws( - // eslint-disable-next-line dot-notation, @stylistic/js/quotes - () => assert['ok']["apply"](null, [0]), - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'assert[\'ok\']["apply"](null, [0])\n' - } -); + assert.throws( + () => { + assert + .ok(null, undefined); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'ok(null, undefined)\n' + } + ); -assert.throws( - () => { - const wrapper = (fn, value) => fn(value); - wrapper(assert, false); - }, - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n fn(value)\n' - } -); + assert.throws( + // eslint-disable-next-line dot-notation, @stylistic/js/quotes + () => assert['ok']["apply"](null, [0]), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert[\'ok\']["apply"](null, [0])\n' + } + ); -assert.throws( - () => assert.ok.call(null, 0), - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'assert.ok.call(null, 0)\n', - generatedMessage: true - } -); + assert.throws( + () => { + const wrapper = (fn, value) => fn(value); + wrapper(assert, false); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n fn(value)\n' + } + ); -assert.throws( - () => assert.ok.call(null, 0, 'test'), - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'test', - generatedMessage: false - } -); + assert.throws( + () => assert.ok.call(null, 0), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert.ok.call(null, 0)\n', + generatedMessage: true + } + ); -// Works in eval. -assert.throws( - () => new Function('assert', 'assert(1 === 2);')(assert), - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'false == true' - } -); -assert.throws( - () => eval('console.log("FOO");\nassert.ok(1 === 2);'), - { - code: 'ERR_ASSERTION', - message: 'false == true' - } -); + assert.throws( + () => assert.ok.call(null, 0, 'test'), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'test', + generatedMessage: false + } + ); -assert.throws( - () => assert.throws(() => {}, 'Error message', 'message'), - { - code: 'ERR_INVALID_ARG_TYPE', - name: 'TypeError', - message: 'The "error" argument must be of type function or ' + - 'an instance of Error, RegExp, or Object. Received type string ' + - "('Error message')" - } -); + // Works in eval. + assert.throws( + () => new Function('assert', 'assert(1 === 2);')(assert), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'false == true' + } + ); + assert.throws( + () => eval('console.log("FOO");\nassert.ok(1 === 2);'), + { + code: 'ERR_ASSERTION', + message: 'false == true' + } + ); -const inputs = [1, false, Symbol()]; -for (const input of inputs) { assert.throws( - () => assert.throws(() => {}, input), + () => assert.throws(() => {}, 'Error message', 'message'), { code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', message: 'The "error" argument must be of type function or ' + - 'an instance of Error, RegExp, or Object.' + - common.invalidArgTypeHelper(input) + 'an instance of Error, RegExp, or Object. Received type string ' + + "('Error message')" } ); -} -{ + const inputs = [1, false, Symbol()]; + for (const input of inputs) { + assert.throws( + () => assert.throws(() => {}, input), + { + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "error" argument must be of type function or ' + + 'an instance of Error, RegExp, or Object.' + + invalidArgTypeHelper(input) + } + ); + } +}); +test('Throws accepts objects', () => { assert.throws(() => { // eslint-disable-next-line no-constant-binary-expression assert.ok((() => Boolean('' === false))()); @@ -1058,7 +1040,7 @@ for (const input of inputs) { ); assert.throws( - () => a.doesNotThrow(() => { throw new Error(); }, { foo: 'bar' }), + () => assert.doesNotThrow(() => { throw new Error(); }, { foo: 'bar' }), { name: 'TypeError', code: 'ERR_INVALID_ARG_TYPE', @@ -1100,414 +1082,420 @@ for (const input of inputs) { assert.throws(() => { throw undefined; }, /undefined/); assert.throws( // eslint-disable-next-line no-throw-literal - () => a.doesNotThrow(() => { throw undefined; }), + () => assert.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( - // eslint-disable-next-line no-throw-literal - () => { 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.' - } -); -/* eslint-enable no-restricted-syntax */ - -// Should not throw. -// eslint-disable-next-line no-restricted-syntax, no-throw-literal -assert.throws(() => { throw null; }, 'foo'); - -assert.throws( - () => assert.strictEqual([], []), - { - message: 'Values have same structure but are not reference-equal:\n\n[]\n' - } -); +}); -{ - const args = (function() { return arguments; })('a'); +test('Additional assert', () => { assert.throws( - () => assert.strictEqual(args, { 0: 'a' }), + () => assert.throws(() => { throw new Error(); }, {}), { - message: 'Expected "actual" to be reference-equal to "expected":\n' + - '+ actual - expected\n\n' + - "+ [Arguments] {\n- {\n '0': 'a'\n }" + message: "The argument 'error' may not be an empty object. Received {}", + code: 'ERR_INVALID_ARG_VALUE' } ); -} - -assert.throws( - () => { throw new TypeError('foobar'); }, - { - message: /foo/, - name: /^TypeError$/ - } -); -assert.throws( - () => assert.throws( - () => { throw new TypeError('foobar'); }, + assert.throws( + () => assert.throws( + // eslint-disable-next-line no-throw-literal + () => { throw 'foo'; }, + 'foo' + ), { - message: /fooa/, - name: /^TypeError$/ + code: 'ERR_AMBIGUOUS_ARGUMENT', + message: 'The "error/message" argument is ambiguous. ' + + 'The error "foo" is identical to the message.' } - ), - { - 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 + () => { throw new TypeError('foo'); }, + 'foo' ), { - operator: 'throws', - actual, - expected, - generatedMessage: true, - message: `${start}\n${actExp}\n\n` + - '+ null\n' + - '- {\n' + - "- message: 'foo'\n" + - '- }' + code: 'ERR_AMBIGUOUS_ARGUMENT', + message: 'The "error/message" argument is ambiguous. ' + + 'The error message "foo" is identical to the message.' } ); - actual = 'foobar'; - const message = 'message'; + // Should not throw. + assert.throws(() => { throw null; }, 'foo'); // eslint-disable-line no-throw-literal + assert.throws( - () => assert.throws( - () => { throw actual; }, - { message: 'foobar' }, - message - ), + () => assert.strictEqual([], []), { - actual, - message, - operator: 'throws', - generatedMessage: false + message: 'Values have same structure but are not reference-equal:\n\n[]\n' } ); -} -// Indicate where the strings diverge. -assert.throws( - () => assert.strictEqual('test test', 'test foobar'), { - code: 'ERR_ASSERTION', - name: 'AssertionError', - 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', - message: 'Expected "actual" not to be reference-equal to "expected": {}' + const args = (function() { return arguments; })('a'); + assert.throws( + () => assert.strictEqual(args, { 0: 'a' }), + { + message: 'Expected "actual" to be reference-equal to "expected":\n' + + '+ actual - expected\n\n' + + "+ [Arguments] {\n- {\n '0': 'a'\n }" + } + ); } -); -assert.throws( - () => { - const obj = { a: true }; - assert.notStrictEqual(obj, obj); - }, - { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: 'Expected "actual" not to be reference-equal to "expected":\n\n' + - '{\n a: true\n}\n' - } -); + assert.throws( + () => { throw new TypeError('foobar'); }, + { + message: /foo/, + name: /^TypeError$/ + } + ); -{ - let threw = false; - try { - // eslint-disable-next-line no-restricted-syntax - assert.deepStrictEqual(Array(100).fill(1), 'foobar'); - } catch (err) { - threw = true; - assert.match(inspect(err), /actual: \[Array],\n {2}expected: 'foobar',/); - } - 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), // eslint-disable-line no-restricted-syntax - { 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 new TypeError('foobar'); }, + { + message: /fooa/, + name: /^TypeError$/ + } + ), + { + message: `${start}\n${actExp}\n\n` + + ' Comparison {\n' + + "+ message: 'foobar',\n" + + '- message: /fooa/,\n' + + " name: 'TypeError'\n" + + ' }' + } + ); -assert.throws( - () => assert.throws(() => { throw Symbol('foo'); }, RangeError), { - message: 'The error is expected to be an instance of "RangeError". ' + - 'Received "Symbol(foo)"' - } -); + let actual = null; + const expected = { message: 'foo' }; + assert.throws( + () => assert.throws( + () => { throw actual; }, + expected + ), + { + operator: 'throws', + actual, + expected, + generatedMessage: true, + message: `${start}\n${actExp}\n\n` + + '+ null\n' + + '- {\n' + + "- message: 'foo'\n" + + '- }' + } + ); -assert.throws( - // eslint-disable-next-line no-throw-literal - () => assert.throws(() => { throw [1, 2]; }, RangeError), - { - message: 'The error is expected to be an instance of "RangeError". ' + - 'Received "[Array]"' + actual = 'foobar'; + const message = 'message'; + assert.throws( + () => assert.throws( + () => { throw actual; }, + { message: 'foobar' }, + message + ), + { + actual, + message, + operator: 'throws', + generatedMessage: false + } + ); } -); -{ - const err = new TypeError('foo'); - const validate = (() => () => ({ a: true, b: [ 1, 2, 3 ] }))(); + // Indicate where the strings diverge. assert.throws( - () => assert.throws(() => { throw err; }, validate), + () => assert.strictEqual('test test', 'test foobar'), { - 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', + message: strictEqualMessageStart + + '+ actual - expected\n\n' + + "+ 'test test'\n" + + "- 'test foobar'\n" + + ' ^' } ); -} - -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. -{ + // Check for reference-equal objects in `notStrictEqual()` assert.throws( - () => assert.match(/abc/, 'string'), + () => { + const obj = {}; + assert.notStrictEqual(obj, obj); + }, { - code: 'ERR_INVALID_ARG_TYPE', - message: 'The "regexp" argument must be an instance of RegExp. ' + - "Received type string ('string')" + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: 'Expected "actual" not to be reference-equal to "expected": {}' } ); + assert.throws( - () => assert.match('string', /abc/), + () => { + const obj = { a: true }; + assert.notStrictEqual(obj, obj); + }, { - actual: 'string', - expected: /abc/, - operator: 'match', - message: 'The input did not match the regular expression /abc/. ' + - "Input:\n\n'string'\n", - generatedMessage: true + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: 'Expected "actual" not to be reference-equal to "expected":\n\n' + + '{\n a: true\n}\n' } ); - assert.throws( - () => assert.match('string', /abc/, 'foobar'), - { - actual: 'string', - expected: /abc/, - operator: 'match', - message: 'foobar', - generatedMessage: false + + { + let threw = false; + try { + assert.deepStrictEqual(Array(100).fill(1), 'foobar'); + } catch (err) { + threw = true; + assert.match(inspect(err), /actual: \[Array],\n {2}expected: 'foobar',/); } + assert(threw); + } + + assert.throws( + () => assert.equal(1), + { code: 'ERR_MISSING_ARGS' } + ); + + assert.throws( + () => assert.deepEqual(/a/), + { code: 'ERR_MISSING_ARGS' } ); - const errorMessage = new RangeError('foobar'); + assert.throws( - () => assert.match('string', /abc/, errorMessage), - errorMessage + () => assert.notEqual(null), + { code: 'ERR_MISSING_ARGS' } ); + assert.throws( - () => assert.match({ abc: 123 }, /abc/), - { - actual: { abc: 123 }, - expected: /abc/, - operator: 'match', - message: 'The "string" argument must be of type string. ' + - 'Received type object ({ abc: 123 })', - generatedMessage: true - } + () => assert.notDeepEqual('test'), + { code: 'ERR_MISSING_ARGS' } ); - assert.match('I will pass', /pass$/); -} -// Multiple assert.doesNotMatch() tests. -{ assert.throws( - () => assert.doesNotMatch(/abc/, 'string'), - { - code: 'ERR_INVALID_ARG_TYPE', - message: 'The "regexp" argument must be an instance of RegExp. ' + - "Received type string ('string')" - } + () => assert.strictEqual({}), + { code: 'ERR_MISSING_ARGS' } ); + assert.throws( - () => assert.doesNotMatch('string', /string/), - { - actual: 'string', - expected: /string/, - operator: 'doesNotMatch', - message: 'The input was expected to not match the regular expression ' + - "/string/. Input:\n\n'string'\n", - generatedMessage: true - } + () => assert.deepStrictEqual(Symbol()), + { code: 'ERR_MISSING_ARGS' } + ); + + assert.throws( + () => assert.notStrictEqual(5n), + { code: 'ERR_MISSING_ARGS' } ); + + assert.throws( + () => assert.notDeepStrictEqual(undefined), + { code: 'ERR_MISSING_ARGS' } + ); + assert.throws( - () => assert.doesNotMatch('string', /string/, 'foobar'), + () => assert.strictEqual(), + { code: 'ERR_MISSING_ARGS' } + ); + + assert.throws( + () => assert.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), { - actual: 'string', - expected: /string/, - operator: 'doesNotMatch', - message: 'foobar', - generatedMessage: false + message: 'The error is expected to be an instance of "RangeError". ' + + 'Received "Symbol(foo)"' } ); - const errorMessage = new RangeError('foobar'); + assert.throws( - () => assert.doesNotMatch('string', /string/, errorMessage), - errorMessage + // eslint-disable-next-line no-throw-literal + () => assert.throws(() => { throw [1, 2]; }, RangeError), + { + 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', + } + ); + } + assert.throws( - () => assert.doesNotMatch({ abc: 123 }, /abc/), + () => { + const script = new vm.Script('new RangeError("foobar");'); + const context = vm.createContext(); + const err = script.runInContext(context); + assert.throws(() => { throw err; }, RangeError); + }, { - actual: { abc: 123 }, - expected: /abc/, - operator: 'doesNotMatch', - message: 'The "string" argument must be of type string. ' + - 'Received type object ({ abc: 123 })', - generatedMessage: true + 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' } ); - 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) => { - assert.strictEqual(inspect(err).split('\n')[5], ' ^'); - inspect.defaultOptions.colors = tempColor; - return true; - }); -} + // Multiple assert.match() tests. + { + assert.throws( + () => assert.match(/abc/, 'string'), + { + code: 'ERR_INVALID_ARG_TYPE', + 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', + 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', + 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', + 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', + 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 })', + 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) => { + assert.strictEqual(inspect(err).split('\n')[5], ' ^'); + inspect.defaultOptions.colors = tempColor; + return true; + }); + } +}); + +test('assert/strict exists', () => { + assert.strictEqual(require('assert/strict'), assert.strict); +}); + +/* eslint-enable no-restricted-syntax */ +/* eslint-enable no-restricted-properties */