diff --git a/test/parallel/test-assert-checktag.js b/test/parallel/test-assert-checktag.js index a8b076049b61e9..7ea12b89d75127 100644 --- a/test/parallel/test-assert-checktag.js +++ b/test/parallel/test-assert-checktag.js @@ -1,70 +1,68 @@ 'use strict'; -const common = require('../common'); - -if (!common.hasCrypto) { - common.skip('missing crypto'); -} - +const { hasCrypto } = require('../common'); +const { test } = require('node:test'); const assert = require('assert'); +// Turn off no-restricted-properties because we are testing deepEqual! +/* eslint-disable no-restricted-properties */ + // Disable colored output to prevent color codes from breaking assertion // message comparisons. This should only be an issue when process.stdout // is a TTY. if (process.stdout.isTTY) process.env.NODE_DISABLE_COLORS = '1'; -// Turn off no-restricted-properties because we are testing deepEqual! -/* eslint-disable no-restricted-properties */ +test('', { skip: !hasCrypto }, () => { + // See https://github.com/nodejs/node/issues/10258 + { + const date = new Date('2016'); + function FakeDate() {} + FakeDate.prototype = Date.prototype; + const fake = new FakeDate(); -// See https://github.com/nodejs/node/issues/10258 -{ - const date = new Date('2016'); - function FakeDate() {} - FakeDate.prototype = Date.prototype; - const fake = new FakeDate(); + assert.notDeepEqual(date, fake); + assert.notDeepEqual(fake, date); - assert.notDeepEqual(date, fake); - assert.notDeepEqual(fake, date); + // For deepStrictEqual we check the runtime type, + // then reveal the fakeness of the fake date + assert.throws( + () => assert.deepStrictEqual(date, fake), + { + message: 'Expected values to be strictly deep-equal:\n' + + '+ actual - expected\n\n+ 2016-01-01T00:00:00.000Z\n- Date {}' + } + ); + assert.throws( + () => assert.deepStrictEqual(fake, date), + { + message: 'Expected values to be strictly deep-equal:\n' + + '+ actual - expected\n\n+ Date {}\n- 2016-01-01T00:00:00.000Z' + } + ); + } - // For deepStrictEqual we check the runtime type, - // then reveal the fakeness of the fake date - assert.throws( - () => assert.deepStrictEqual(date, fake), - { - message: 'Expected values to be strictly deep-equal:\n' + - '+ actual - expected\n\n+ 2016-01-01T00:00:00.000Z\n- Date {}' - } - ); - assert.throws( - () => assert.deepStrictEqual(fake, date), - { - message: 'Expected values to be strictly deep-equal:\n' + - '+ actual - expected\n\n+ Date {}\n- 2016-01-01T00:00:00.000Z' + { // At the moment global has its own type tag + const fakeGlobal = {}; + Object.setPrototypeOf(fakeGlobal, Object.getPrototypeOf(global)); + for (const prop of Object.keys(global)) { + fakeGlobal[prop] = global[prop]; } - ); -} - -{ // At the moment global has its own type tag - const fakeGlobal = {}; - Object.setPrototypeOf(fakeGlobal, Object.getPrototypeOf(global)); - for (const prop of Object.keys(global)) { - fakeGlobal[prop] = global[prop]; + assert.notDeepEqual(fakeGlobal, global); + // Message will be truncated anyway, don't validate + assert.throws(() => assert.deepStrictEqual(fakeGlobal, global), + assert.AssertionError); } - assert.notDeepEqual(fakeGlobal, global); - // Message will be truncated anyway, don't validate - assert.throws(() => assert.deepStrictEqual(fakeGlobal, global), - assert.AssertionError); -} -{ // At the moment process has its own type tag - const fakeProcess = {}; - Object.setPrototypeOf(fakeProcess, Object.getPrototypeOf(process)); - for (const prop of Object.keys(process)) { - fakeProcess[prop] = process[prop]; + { // At the moment process has its own type tag + const fakeProcess = {}; + Object.setPrototypeOf(fakeProcess, Object.getPrototypeOf(process)); + for (const prop of Object.keys(process)) { + fakeProcess[prop] = process[prop]; + } + assert.notDeepEqual(fakeProcess, process); + // Message will be truncated anyway, don't validate + assert.throws(() => assert.deepStrictEqual(fakeProcess, process), + assert.AssertionError); } - assert.notDeepEqual(fakeProcess, process); - // Message will be truncated anyway, don't validate - assert.throws(() => assert.deepStrictEqual(fakeProcess, process), - assert.AssertionError); -} +}); /* eslint-enable */ diff --git a/test/parallel/test-assert-deep.js b/test/parallel/test-assert-deep.js index 0711d4b7ea496c..a8bc5d3cf4e815 100644 --- a/test/parallel/test-assert-deep.js +++ b/test/parallel/test-assert-deep.js @@ -1,8 +1,9 @@ 'use strict'; -const common = require('../common'); +const { hasCrypto } = require('../common'); const assert = require('assert'); const util = require('util'); +const { test } = require('node:test'); const { AssertionError } = assert; const defaultMsgStart = 'Expected values to be strictly deep-equal:\n'; const defaultMsgStartFull = `${defaultMsgStart}+ actual - expected`; @@ -36,6 +37,24 @@ function re(literals, ...values) { }; } +const date = new Date('2016'); + +class MyDate extends Date { + constructor(...args) { + super(...args); + this[0] = '1'; + } +} + +const date2 = new MyDate('2016'); + +class MyRegExp extends RegExp { + constructor(...args) { + super(...args); + this[0] = '1'; + } +} + // The following deepEqual tests might seem very weird. // They just describe what it is now. // That is why we discourage using deepEqual in our own tests. @@ -43,115 +62,104 @@ function re(literals, ...values) { // Turn off no-restricted-properties because we are testing deepEqual! /* eslint-disable no-restricted-properties */ -const arr = new Uint8Array([120, 121, 122, 10]); -const buf = Buffer.from(arr); -// They have different [[Prototype]] -assert.throws( - () => assert.deepStrictEqual(arr, buf), +test('deepEqual', () => { + const arr = new Uint8Array([120, 121, 122, 10]); + const buf = Buffer.from(arr); + // They have different [[Prototype]] + assert.throws( + () => assert.deepStrictEqual(arr, buf), + { + code: 'ERR_ASSERTION', + message: `${defaultMsgStartFull} ... Lines skipped\n\n` + + '+ Uint8Array(4) [\n' + + '- Buffer(4) [Uint8Array] [\n 120,\n...\n 122,\n 10\n ]' + } + ); + assert.deepEqual(arr, buf); + { - code: 'ERR_ASSERTION', - message: `${defaultMsgStartFull} ... Lines skipped\n\n` + - '+ Uint8Array(4) [\n' + - '- Buffer(4) [Uint8Array] [\n 120,\n...\n 122,\n 10\n ]' + const buf2 = Buffer.from(arr); + buf2.prop = 1; + + assert.throws( + () => assert.deepStrictEqual(buf2, buf), + { + code: 'ERR_ASSERTION', + message: `${defaultMsgStartFull}\n\n` + + ' Buffer(4) [Uint8Array] [\n' + + ' 120,\n' + + ' 121,\n' + + ' 122,\n' + + ' 10,\n' + + '+ prop: 1\n' + + ' ]' + } + ); + assert.notDeepEqual(buf2, buf); } -); -assert.deepEqual(arr, buf); -{ - const buf2 = Buffer.from(arr); - buf2.prop = 1; + { + const arr2 = new Uint8Array([120, 121, 122, 10]); + arr2.prop = 5; + assert.throws( + () => assert.deepStrictEqual(arr, arr2), + { + code: 'ERR_ASSERTION', + message: `${defaultMsgStartFull}\n\n` + + ' Uint8Array(4) [\n' + + ' 120,\n' + + ' 121,\n' + + ' 122,\n' + + ' 10,\n' + + '- prop: 5\n' + + ' ]' + } + ); + assert.notDeepEqual(arr, arr2); + } +}); +test('date', () => { + assertNotDeepOrStrict(date, date2); assert.throws( - () => assert.deepStrictEqual(buf2, buf), + () => assert.deepStrictEqual(date, date2), { code: 'ERR_ASSERTION', message: `${defaultMsgStartFull}\n\n` + - ' Buffer(4) [Uint8Array] [\n' + - ' 120,\n' + - ' 121,\n' + - ' 122,\n' + - ' 10,\n' + - '+ prop: 1\n' + - ' ]' + '+ 2016-01-01T00:00:00.000Z\n- MyDate 2016-01-01T00:00:00.000Z' + + " {\n- '0': '1'\n- }" } ); - assert.notDeepEqual(buf2, buf); -} - -{ - const arr2 = new Uint8Array([120, 121, 122, 10]); - arr2.prop = 5; assert.throws( - () => assert.deepStrictEqual(arr, arr2), + () => assert.deepStrictEqual(date2, date), { code: 'ERR_ASSERTION', message: `${defaultMsgStartFull}\n\n` + - ' Uint8Array(4) [\n' + - ' 120,\n' + - ' 121,\n' + - ' 122,\n' + - ' 10,\n' + - '- prop: 5\n' + - ' ]' + '+ MyDate 2016-01-01T00:00:00.000Z {\n' + + "+ '0': '1'\n+ }\n- 2016-01-01T00:00:00.000Z" } ); - assert.notDeepEqual(arr, arr2); -} +}); -const date = new Date('2016'); +test('regexp', () => { + const re1 = new RegExp('test'); + const re2 = new MyRegExp('test'); -class MyDate extends Date { - constructor(...args) { - super(...args); - this[0] = '1'; - } -} - -const date2 = new MyDate('2016'); - -assertNotDeepOrStrict(date, date2); -assert.throws( - () => assert.deepStrictEqual(date, date2), - { - code: 'ERR_ASSERTION', - message: `${defaultMsgStartFull}\n\n` + - '+ 2016-01-01T00:00:00.000Z\n- MyDate 2016-01-01T00:00:00.000Z' + - " {\n- '0': '1'\n- }" - } -); -assert.throws( - () => assert.deepStrictEqual(date2, date), - { - code: 'ERR_ASSERTION', - message: `${defaultMsgStartFull}\n\n` + - '+ MyDate 2016-01-01T00:00:00.000Z {\n' + - "+ '0': '1'\n+ }\n- 2016-01-01T00:00:00.000Z" - } -); - -class MyRegExp extends RegExp { - constructor(...args) { - super(...args); - this[0] = '1'; - } -} - -const re1 = new RegExp('test'); -const re2 = new MyRegExp('test'); - -assertNotDeepOrStrict(re1, re2); -assert.throws( - () => assert.deepStrictEqual(re1, re2), - { - code: 'ERR_ASSERTION', - message: `${defaultMsgStartFull}\n\n` + - "+ /test/\n- MyRegExp /test/ {\n- '0': '1'\n- }" - } -); + assertNotDeepOrStrict(re1, re2); + assert.throws( + () => assert.deepStrictEqual(re1, re2), + { + code: 'ERR_ASSERTION', + message: `${defaultMsgStartFull}\n\n` + + "+ /test/\n- MyRegExp /test/ {\n- '0': '1'\n- }" + } + ); +}); // For these weird cases, deepEqual should pass (at least for now), // but deepStrictEqual should throw. -{ +test('deepEqual should pass for these weird cases', () => { + const re2 = new MyRegExp('test'); const similar = new Set([ { 0: 1 }, // Object new String('1'), // Object @@ -178,7 +186,7 @@ assert.throws( } } } -} +}); function assertDeepAndStrictEqual(a, b) { assert.deepEqual(a, b); @@ -222,187 +230,293 @@ function assertOnlyDeepEqual(a, b, err) { ); } -// es6 Maps and Sets -assertDeepAndStrictEqual(new Set(), new Set()); -assertDeepAndStrictEqual(new Map(), new Map()); +test('es6 Maps and Sets', () => { + assertDeepAndStrictEqual(new Set(), new Set()); + assertDeepAndStrictEqual(new Map(), new Map()); + + assertDeepAndStrictEqual(new Set([1, 2, 3]), new Set([1, 2, 3])); + assertNotDeepOrStrict(new Set([1, 2, 3]), new Set([1, 2, 3, 4])); + assertNotDeepOrStrict(new Set([1, 2, 3, 4]), new Set([1, 2, 3])); + assertDeepAndStrictEqual(new Set(['1', '2', '3']), new Set(['1', '2', '3'])); + assertDeepAndStrictEqual(new Set([[1, 2], [3, 4]]), new Set([[3, 4], [1, 2]])); + assertNotDeepOrStrict(new Set([{ a: 0 }]), new Set([{ a: 1 }])); + assertNotDeepOrStrict(new Set([Symbol()]), new Set([Symbol()])); + + { + const a = [ 1, 2 ]; + const b = [ 3, 4 ]; + const c = [ 1, 2 ]; + const d = [ 3, 4 ]; + + assertDeepAndStrictEqual( + { a: a, b: b, s: new Set([a, b]) }, + { a: c, b: d, s: new Set([d, c]) } + ); + } + + assertDeepAndStrictEqual(new Map([[1, 1], [2, 2]]), new Map([[1, 1], [2, 2]])); + assertDeepAndStrictEqual(new Map([[1, 1], [2, 2]]), new Map([[2, 2], [1, 1]])); + assertNotDeepOrStrict(new Map([[1, 1], [2, 2]]), new Map([[1, 2], [2, 1]])); + assertNotDeepOrStrict( + new Map([[[1], 1], [{}, 2]]), + new Map([[[1], 2], [{}, 1]]) + ); + + assertNotDeepOrStrict(new Set([1]), [1]); + assertNotDeepOrStrict(new Set(), []); + assertNotDeepOrStrict(new Set(), {}); + + assertNotDeepOrStrict(new Map([['a', 1]]), { a: 1 }); + assertNotDeepOrStrict(new Map(), []); + assertNotDeepOrStrict(new Map(), {}); -assertDeepAndStrictEqual(new Set([1, 2, 3]), new Set([1, 2, 3])); -assertNotDeepOrStrict(new Set([1, 2, 3]), new Set([1, 2, 3, 4])); -assertNotDeepOrStrict(new Set([1, 2, 3, 4]), new Set([1, 2, 3])); -assertDeepAndStrictEqual(new Set(['1', '2', '3']), new Set(['1', '2', '3'])); -assertDeepAndStrictEqual(new Set([[1, 2], [3, 4]]), new Set([[3, 4], [1, 2]])); -assertNotDeepOrStrict(new Set([{ a: 0 }]), new Set([{ a: 1 }])); -assertNotDeepOrStrict(new Set([Symbol()]), new Set([Symbol()])); + assertOnlyDeepEqual(new Set(['1']), new Set([1])); -{ - const a = [ 1, 2 ]; - const b = [ 3, 4 ]; - const c = [ 1, 2 ]; - const d = [ 3, 4 ]; + assertOnlyDeepEqual(new Map([['1', 'a']]), new Map([[1, 'a']])); + assertOnlyDeepEqual(new Map([['a', '1']]), new Map([['a', 1]])); + assertNotDeepOrStrict(new Map([['a', '1']]), new Map([['a', 2]])); + assertDeepAndStrictEqual(new Set([{}]), new Set([{}])); + + // Ref: https://github.com/nodejs/node/issues/13347 + assertNotDeepOrStrict( + new Set([{ a: 1 }, { a: 1 }]), + new Set([{ a: 1 }, { a: 2 }]) + ); + assertNotDeepOrStrict( + new Set([{ a: 1 }, { a: 1 }, { a: 2 }]), + new Set([{ a: 1 }, { a: 2 }, { a: 2 }]) + ); + assertNotDeepOrStrict( + new Map([[{ x: 1 }, 5], [{ x: 1 }, 5]]), + new Map([[{ x: 1 }, 5], [{ x: 2 }, 5]]) + ); + + assertNotDeepOrStrict(new Set([3, '3']), new Set([3, 4])); + assertNotDeepOrStrict(new Map([[3, 0], ['3', 0]]), new Map([[3, 0], [4, 0]])); + + assertNotDeepOrStrict( + new Set([{ a: 1 }, { a: 1 }, { a: 2 }]), + new Set([{ a: 1 }, { a: 2 }, { a: 2 }]) + ); + + // Mixed primitive and object keys assertDeepAndStrictEqual( - { a: a, b: b, s: new Set([a, b]) }, - { a: c, b: d, s: new Set([d, c]) } + new Map([[1, 'a'], [{}, 'a']]), + new Map([[1, 'a'], [{}, 'a']]) + ); + assertDeepAndStrictEqual( + new Set([1, 'a', [{}, 'a']]), + new Set([1, 'a', [{}, 'a']]) ); -} -assertDeepAndStrictEqual(new Map([[1, 1], [2, 2]]), new Map([[1, 1], [2, 2]])); -assertDeepAndStrictEqual(new Map([[1, 1], [2, 2]]), new Map([[2, 2], [1, 1]])); -assertNotDeepOrStrict(new Map([[1, 1], [2, 2]]), new Map([[1, 2], [2, 1]])); -assertNotDeepOrStrict( - new Map([[[1], 1], [{}, 2]]), - new Map([[[1], 2], [{}, 1]]) -); - -assertNotDeepOrStrict(new Set([1]), [1]); -assertNotDeepOrStrict(new Set(), []); -assertNotDeepOrStrict(new Set(), {}); - -assertNotDeepOrStrict(new Map([['a', 1]]), { a: 1 }); -assertNotDeepOrStrict(new Map(), []); -assertNotDeepOrStrict(new Map(), {}); - -assertOnlyDeepEqual(new Set(['1']), new Set([1])); - -assertOnlyDeepEqual(new Map([['1', 'a']]), new Map([[1, 'a']])); -assertOnlyDeepEqual(new Map([['a', '1']]), new Map([['a', 1]])); -assertNotDeepOrStrict(new Map([['a', '1']]), new Map([['a', 2]])); - -assertDeepAndStrictEqual(new Set([{}]), new Set([{}])); - -// Ref: https://github.com/nodejs/node/issues/13347 -assertNotDeepOrStrict( - new Set([{ a: 1 }, { a: 1 }]), - new Set([{ a: 1 }, { a: 2 }]) -); -assertNotDeepOrStrict( - new Set([{ a: 1 }, { a: 1 }, { a: 2 }]), - new Set([{ a: 1 }, { a: 2 }, { a: 2 }]) -); -assertNotDeepOrStrict( - new Map([[{ x: 1 }, 5], [{ x: 1 }, 5]]), - new Map([[{ x: 1 }, 5], [{ x: 2 }, 5]]) -); - -assertNotDeepOrStrict(new Set([3, '3']), new Set([3, 4])); -assertNotDeepOrStrict(new Map([[3, 0], ['3', 0]]), new Map([[3, 0], [4, 0]])); - -assertNotDeepOrStrict( - new Set([{ a: 1 }, { a: 1 }, { a: 2 }]), - new Set([{ a: 1 }, { a: 2 }, { a: 2 }]) -); - -// Mixed primitive and object keys -assertDeepAndStrictEqual( - new Map([[1, 'a'], [{}, 'a']]), - new Map([[1, 'a'], [{}, 'a']]) -); -assertDeepAndStrictEqual( - new Set([1, 'a', [{}, 'a']]), - new Set([1, 'a', [{}, 'a']]) -); - -// This is an awful case, where a map contains multiple equivalent keys: -assertOnlyDeepEqual( - new Map([[1, 'a'], ['1', 'b']]), - new Map([['1', 'a'], [true, 'b']]) -); -assertNotDeepOrStrict( - new Set(['a']), - new Set(['b']) -); -assertDeepAndStrictEqual( - new Map([[{}, 'a'], [{}, 'b']]), - new Map([[{}, 'b'], [{}, 'a']]) -); -assertOnlyDeepEqual( - new Map([[true, 'a'], ['1', 'b'], [1, 'a']]), - new Map([['1', 'a'], [1, 'b'], [true, 'a']]) -); -assertNotDeepOrStrict( - new Map([[true, 'a'], ['1', 'b'], [1, 'c']]), - new Map([['1', 'a'], [1, 'b'], [true, 'a']]) -); - -// Similar object keys -assertNotDeepOrStrict( - new Set([{}, {}]), - new Set([{}, 1]) -); -assertNotDeepOrStrict( - new Set([[{}, 1], [{}, 1]]), - new Set([[{}, 1], [1, 1]]) -); -assertNotDeepOrStrict( - new Map([[{}, 1], [{}, 1]]), - new Map([[{}, 1], [1, 1]]) -); -assertOnlyDeepEqual( - new Map([[{}, 1], [true, 1]]), - new Map([[{}, 1], [1, 1]]) -); - -// Similar primitive key / values -assertNotDeepOrStrict( - new Set([1, true, false]), - new Set(['1', 0, '0']) -); -assertNotDeepOrStrict( - new Map([[1, 5], [true, 5], [false, 5]]), - new Map([['1', 5], [0, 5], ['0', 5]]) -); - -// Undefined value in Map -assertDeepAndStrictEqual( - new Map([[1, undefined]]), - new Map([[1, undefined]]) -); -assertOnlyDeepEqual( - new Map([[1, null], ['', '0']]), - new Map([['1', undefined], [false, 0]]) -); -assertNotDeepOrStrict( - new Map([[1, undefined]]), - new Map([[2, undefined]]) -); - -// null as key -assertDeepAndStrictEqual( - new Map([[null, 3]]), - new Map([[null, 3]]) -); -assertOnlyDeepEqual( - new Map([[undefined, null], ['+000', 2n]]), - new Map([[null, undefined], [false, '2']]), -); -const xarray = ['x']; -assertDeepAndStrictEqual( - new Set([xarray, ['y']]), - new Set([xarray, ['y']]) -); -assertOnlyDeepEqual( - new Set([null, '', 1n, 5, 2n, false]), - new Set([undefined, 0, 5n, true, '2', '-000']) -); -assertNotDeepOrStrict( - new Set(['']), - new Set(['0']) -); -assertOnlyDeepEqual( - new Map([[1, {}]]), - new Map([[true, {}]]) -); -assertOnlyDeepEqual( - new Map([[undefined, true]]), - new Map([[null, true]]) -); -assertNotDeepOrStrict( - new Map([[undefined, true]]), - new Map([[true, true]]) -); - -// GH-6416. Make sure circular refs don't throw. -{ + // This is an awful case, where a map contains multiple equivalent keys: + assertOnlyDeepEqual( + new Map([[1, 'a'], ['1', 'b']]), + new Map([['1', 'a'], [true, 'b']]) + ); + assertNotDeepOrStrict( + new Set(['a']), + new Set(['b']) + ); + assertDeepAndStrictEqual( + new Map([[{}, 'a'], [{}, 'b']]), + new Map([[{}, 'b'], [{}, 'a']]) + ); + assertOnlyDeepEqual( + new Map([[true, 'a'], ['1', 'b'], [1, 'a']]), + new Map([['1', 'a'], [1, 'b'], [true, 'a']]) + ); + assertNotDeepOrStrict( + new Map([[true, 'a'], ['1', 'b'], [1, 'c']]), + new Map([['1', 'a'], [1, 'b'], [true, 'a']]) + ); + + // Similar object keys + assertNotDeepOrStrict( + new Set([{}, {}]), + new Set([{}, 1]) + ); + assertNotDeepOrStrict( + new Set([[{}, 1], [{}, 1]]), + new Set([[{}, 1], [1, 1]]) + ); + assertNotDeepOrStrict( + new Map([[{}, 1], [{}, 1]]), + new Map([[{}, 1], [1, 1]]) + ); + assertOnlyDeepEqual( + new Map([[{}, 1], [true, 1]]), + new Map([[{}, 1], [1, 1]]) + ); + + // Similar primitive key / values + assertNotDeepOrStrict( + new Set([1, true, false]), + new Set(['1', 0, '0']) + ); + assertNotDeepOrStrict( + new Map([[1, 5], [true, 5], [false, 5]]), + new Map([['1', 5], [0, 5], ['0', 5]]) + ); + + // Undefined value in Map + assertDeepAndStrictEqual( + new Map([[1, undefined]]), + new Map([[1, undefined]]) + ); + assertOnlyDeepEqual( + new Map([[1, null], ['', '0']]), + new Map([['1', undefined], [false, 0]]) + ); + assertNotDeepOrStrict( + new Map([[1, undefined]]), + new Map([[2, undefined]]) + ); + + // null as key + assertDeepAndStrictEqual( + new Map([[null, 3]]), + new Map([[null, 3]]) + ); + assertOnlyDeepEqual( + new Map([[undefined, null], ['+000', 2n]]), + new Map([[null, undefined], [false, '2']]), + ); + const xarray = ['x']; + assertDeepAndStrictEqual( + new Set([xarray, ['y']]), + new Set([xarray, ['y']]) + ); + assertOnlyDeepEqual( + new Set([null, '', 1n, 5, 2n, false]), + new Set([undefined, 0, 5n, true, '2', '-000']) + ); + assertNotDeepOrStrict( + new Set(['']), + new Set(['0']) + ); + assertOnlyDeepEqual( + new Map([[1, {}]]), + new Map([[true, {}]]) + ); + assertOnlyDeepEqual( + new Map([[undefined, true]]), + new Map([[null, true]]) + ); + assertNotDeepOrStrict( + new Map([[undefined, true]]), + new Map([[true, true]]) + ); + { + const values = [ + 123, + Infinity, + 0, + null, + undefined, + false, + true, + {}, + [], + () => {}, + ]; + assertDeepAndStrictEqual(new Set(values), new Set(values)); + assertDeepAndStrictEqual(new Set(values), new Set(values.reverse())); + + const mapValues = values.map((v) => [v, { a: 5 }]); + assertDeepAndStrictEqual(new Map(mapValues), new Map(mapValues)); + assertDeepAndStrictEqual(new Map(mapValues), new Map(mapValues.reverse())); + } + + { + const s1 = new Set(); + const s2 = new Set(); + s1.add(1); + s1.add(2); + s2.add(2); + s2.add(1); + assertDeepAndStrictEqual(s1, s2); + } + + { + const m1 = new Map(); + const m2 = new Map(); + const obj = { a: 5, b: 6 }; + m1.set(1, obj); + m1.set(2, 'hi'); + m1.set(3, [1, 2, 3]); + + m2.set(2, 'hi'); // different order + m2.set(1, obj); + m2.set(3, [1, 2, 3]); // Deep equal, but not reference equal. + + assertDeepAndStrictEqual(m1, m2); + } + + { + const m1 = new Map(); + const m2 = new Map(); + + // m1 contains itself. + m1.set(1, m1); + m2.set(1, new Map()); + + assertNotDeepOrStrict(m1, m2); + } + + { + const map1 = new Map([[1, 1]]); + const map2 = new Map([[1, '1']]); + assert.deepEqual(map1, map2); + assert.throws( + () => assert.deepStrictEqual(map1, map2), + { + code: 'ERR_ASSERTION', + message: `${defaultMsgStartFull}\n\n` + + " Map(1) {\n+ 1 => 1\n- 1 => '1'\n }" + } + ); + } + + { + // Two equivalent sets / maps with different key/values applied shouldn't be + // the same. This is a terrible idea to do in practice, but deepEqual should + // still check for it. + const s1 = new Set(); + const s2 = new Set(); + s1.x = 5; + assertNotDeepOrStrict(s1, s2); + + const m1 = new Map(); + const m2 = new Map(); + m1.x = 5; + assertNotDeepOrStrict(m1, m2); + } + + { + // Circular references. + const s1 = new Set(); + s1.add(s1); + const s2 = new Set(); + s2.add(s2); + assertDeepAndStrictEqual(s1, s2); + + const m1 = new Map(); + m1.set(2, m1); + const m2 = new Map(); + m2.set(2, m2); + assertDeepAndStrictEqual(m1, m2); + + const m3 = new Map(); + m3.set(m3, 2); + const m4 = new Map(); + m4.set(m4, 2); + assertDeepAndStrictEqual(m3, m4); + } +}); + +test('GH-6416. Make sure circular refs do not throw', () => { const b = {}; b.b = b; const c = {}; @@ -418,49 +532,48 @@ assertNotDeepOrStrict( e.b = {}; assertNotDeepOrStrict(d, e); -} +}); -// GH-14441. Circular structures should be consistent -{ - const a = {}; - a.a = a; +test('GH-14441. Circular structures should be consistent', () => { + { + const a = {}; + a.a = a; - const b = {}; - b.a = {}; - b.a.a = a; + const b = {}; + b.a = {}; + b.a.a = a; - assertDeepAndStrictEqual(a, b); -} + assertDeepAndStrictEqual(a, b); + } -{ - const a = {}; - a.a = a; - const b = {}; - b.a = b; - const c = {}; - c.a = a; - assertDeepAndStrictEqual(b, c); -} + { + const a = {}; + a.a = a; + const b = {}; + b.a = b; + const c = {}; + c.a = a; + assertDeepAndStrictEqual(b, c); + } -{ - const a = new Set(); - a.add(a); - const b = new Set(); - b.add(b); - const c = new Set(); - c.add(a); - assertDeepAndStrictEqual(b, c); -} + { + const a = new Set(); + a.add(a); + const b = new Set(); + b.add(b); + const c = new Set(); + c.add(a); + assertDeepAndStrictEqual(b, c); + } +}); // https://github.com/nodejs/node-v0.x-archive/pull/7178 -// Ensure reflexivity of deepEqual with `arguments` objects. -{ +test('Ensure reflexivity of deepEqual with `arguments` objects.', () => { const args = (function() { return arguments; })(); assertNotDeepOrStrict([], args); -} +}); -// More checking that arguments objects are handled correctly -{ +test('More checking that arguments objects are handled correctly', () => { // eslint-disable-next-line func-style const returnArguments = function() { return arguments; }; @@ -472,117 +585,9 @@ assertNotDeepOrStrict( assertNotDeepOrStrict(someArgs, { '0': 'a' }); assertNotDeepOrStrict(someArgs, diffArgs); assertDeepAndStrictEqual(someArgs, sameArgs); -} - -{ - const values = [ - 123, - Infinity, - 0, - null, - undefined, - false, - true, - {}, - [], - () => {}, - ]; - assertDeepAndStrictEqual(new Set(values), new Set(values)); - assertDeepAndStrictEqual(new Set(values), new Set(values.reverse())); - - const mapValues = values.map((v) => [v, { a: 5 }]); - assertDeepAndStrictEqual(new Map(mapValues), new Map(mapValues)); - assertDeepAndStrictEqual(new Map(mapValues), new Map(mapValues.reverse())); -} - -{ - const s1 = new Set(); - const s2 = new Set(); - s1.add(1); - s1.add(2); - s2.add(2); - s2.add(1); - assertDeepAndStrictEqual(s1, s2); -} - -{ - const m1 = new Map(); - const m2 = new Map(); - const obj = { a: 5, b: 6 }; - m1.set(1, obj); - m1.set(2, 'hi'); - m1.set(3, [1, 2, 3]); - - m2.set(2, 'hi'); // different order - m2.set(1, obj); - m2.set(3, [1, 2, 3]); // Deep equal, but not reference equal. - - assertDeepAndStrictEqual(m1, m2); -} - -{ - const m1 = new Map(); - const m2 = new Map(); - - // m1 contains itself. - m1.set(1, m1); - m2.set(1, new Map()); - - assertNotDeepOrStrict(m1, m2); -} - -{ - const map1 = new Map([[1, 1]]); - const map2 = new Map([[1, '1']]); - assert.deepEqual(map1, map2); - assert.throws( - () => assert.deepStrictEqual(map1, map2), - { - code: 'ERR_ASSERTION', - message: `${defaultMsgStartFull}\n\n` + - " Map(1) {\n+ 1 => 1\n- 1 => '1'\n }" - } - ); -} - -{ - // Two equivalent sets / maps with different key/values applied shouldn't be - // the same. This is a terrible idea to do in practice, but deepEqual should - // still check for it. - const s1 = new Set(); - const s2 = new Set(); - s1.x = 5; - assertNotDeepOrStrict(s1, s2); - - const m1 = new Map(); - const m2 = new Map(); - m1.x = 5; - assertNotDeepOrStrict(m1, m2); -} +}); -{ - // Circular references. - const s1 = new Set(); - s1.add(s1); - const s2 = new Set(); - s2.add(s2); - assertDeepAndStrictEqual(s1, s2); - - const m1 = new Map(); - m1.set(2, m1); - const m2 = new Map(); - m2.set(2, m2); - assertDeepAndStrictEqual(m1, m2); - - const m3 = new Map(); - m3.set(m3, 2); - const m4 = new Map(); - m4.set(m4, 2); - assertDeepAndStrictEqual(m3, m4); -} - -// Handle sparse arrays. -{ +test('Handle sparse arrays', () => { /* eslint-disable no-sparse-arrays */ assertDeepAndStrictEqual([1, , , 3], [1, , , 3]); assertNotDeepOrStrict([1, , , 3], [1, , , 3, , , ]); @@ -596,24 +601,23 @@ assertNotDeepOrStrict( assertNotDeepOrStrict(a, b); a[0] = true; assertNotDeepOrStrict(a, b); -} +}); -// Handle different error messages -{ +test('Handle different error messages', () => { const err1 = new Error('foo1'); assertNotDeepOrStrict(err1, new Error('foo2'), assert.AssertionError); assertNotDeepOrStrict(err1, new TypeError('foo1'), assert.AssertionError); assertDeepAndStrictEqual(err1, new Error('foo1')); assertNotDeepOrStrict(err1, {}, AssertionError); -} +}); -// Handle NaN -assertDeepAndStrictEqual(NaN, NaN); -assertDeepAndStrictEqual({ a: NaN }, { a: NaN }); -assertDeepAndStrictEqual([ 1, 2, NaN, 4 ], [ 1, 2, NaN, 4 ]); +test('Handle NaN', () => { + assertDeepAndStrictEqual(NaN, NaN); + assertDeepAndStrictEqual({ a: NaN }, { a: NaN }); + assertDeepAndStrictEqual([ 1, 2, NaN, 4 ], [ 1, 2, NaN, 4 ]); +}); -// Handle boxed primitives -{ +test('Handle boxed primitives', () => { const boxedString = new String('test'); const boxedSymbol = Object(Symbol()); @@ -640,14 +644,14 @@ assertDeepAndStrictEqual([ 1, 2, NaN, 4 ], [ 1, 2, NaN, 4 ]); boxedSymbol.slow = true; assertNotDeepOrStrict(boxedSymbol, {}); assertNotDeepOrStrict(boxedSymbol, fakeBoxedSymbol); -} +}); -// Minus zero -assertOnlyDeepEqual(0, -0); -assertDeepAndStrictEqual(-0, -0); +test('Minus zero', () => { + assertOnlyDeepEqual(0, -0); + assertDeepAndStrictEqual(-0, -0); +}); -// Handle symbols (enumerable only) -{ +test('Handle symbols (enumerable only)', () => { const symbol1 = Symbol(); const obj1 = { [symbol1]: 1 }; const obj2 = { [symbol1]: 1 }; @@ -680,268 +684,276 @@ assertDeepAndStrictEqual(-0, -0); assertOnlyDeepEqual(arr, arr2); arr2[symbol1] = false; assertOnlyDeepEqual(arr, arr2); -} +}); + +test('Additional tests', () => { + assert.throws( + () => assert.notDeepEqual(1, true), + { + message: /1\n\nshould not loosely deep-equal\n\ntrue/ + } + ); + + assert.throws( + () => assert.notDeepEqual(1, 1), + { + message: /Expected "actual" not to be loosely deep-equal to:\n\n1/ + } + ); + + assertDeepAndStrictEqual(new Date(2000, 3, 14), new Date(2000, 3, 14)); + + assert.throws(() => { assert.deepEqual(new Date(), new Date(2000, 3, 14)); }, + AssertionError, + 'deepEqual(new Date(), new Date(2000, 3, 14))'); + + assert.throws( + () => { assert.notDeepEqual(new Date(2000, 3, 14), new Date(2000, 3, 14)); }, + AssertionError, + 'notDeepEqual(new Date(2000, 3, 14), new Date(2000, 3, 14))' + ); + + assert.throws( + () => { assert.notDeepEqual('a'.repeat(1024), 'a'.repeat(1024)); }, + AssertionError, + 'notDeepEqual("a".repeat(1024), "a".repeat(1024))' + ); + + assertNotDeepOrStrict(new Date(), new Date(2000, 3, 14)); + + assertDeepAndStrictEqual(/a/, /a/); + assertDeepAndStrictEqual(/a/g, /a/g); + assertDeepAndStrictEqual(/a/i, /a/i); + assertDeepAndStrictEqual(/a/m, /a/m); + assertDeepAndStrictEqual(/a/igm, /a/igm); + assertNotDeepOrStrict(/ab/, /a/); + assertNotDeepOrStrict(/a/g, /a/); + assertNotDeepOrStrict(/a/i, /a/); + assertNotDeepOrStrict(/a/m, /a/); + assertNotDeepOrStrict(/a/igm, /a/im); -assert.throws( - () => assert.notDeepEqual(1, true), { - message: /1\n\nshould not loosely deep-equal\n\ntrue/ + const re1 = /a/g; + re1.lastIndex = 3; + assert.notDeepEqual(re1, /a/g); } -); -assert.throws( - () => assert.notDeepEqual(1, 1), - { - message: /Expected "actual" not to be loosely deep-equal to:\n\n1/ + assert.deepEqual(4, '4'); + assert.deepEqual(true, 1); + assert.throws(() => assert.deepEqual(4, '5'), + AssertionError, + 'deepEqual( 4, \'5\')'); +}); + +test('Having the same number of owned properties && the same set of keys', () => { + assert.deepEqual({ a: 4 }, { a: 4 }); + assert.deepEqual({ a: 4, b: '2' }, { a: 4, b: '2' }); + assert.deepEqual([4], ['4']); + assert.throws( + () => assert.deepEqual({ a: 4 }, { a: 4, b: true }), AssertionError); + assert.notDeepEqual(['a'], { 0: 'a' }); + assert.deepEqual({ a: 4, b: '1' }, { b: '1', a: 4 }); + const a1 = [1, 2, 3]; + const a2 = [1, 2, 3]; + a1.a = 'test'; + a1.b = true; + a2.b = true; + a2.a = 'test'; + assert.throws(() => assert.deepEqual(Object.keys(a1), Object.keys(a2)), + AssertionError); + assertDeepAndStrictEqual(a1, a2); +}); + +test('Having an identical prototype property', () => { + const nbRoot = { + toString() { return `${this.first} ${this.last}`; } + }; + + function nameBuilder(first, last) { + this.first = first; + this.last = last; + return this; } -); - -assertDeepAndStrictEqual(new Date(2000, 3, 14), new Date(2000, 3, 14)); - -assert.throws(() => { assert.deepEqual(new Date(), new Date(2000, 3, 14)); }, - AssertionError, - 'deepEqual(new Date(), new Date(2000, 3, 14))'); - -assert.throws( - () => { assert.notDeepEqual(new Date(2000, 3, 14), new Date(2000, 3, 14)); }, - AssertionError, - 'notDeepEqual(new Date(2000, 3, 14), new Date(2000, 3, 14))' -); - -assert.throws( - () => { assert.notDeepEqual('a'.repeat(1024), 'a'.repeat(1024)); }, - AssertionError, - 'notDeepEqual("a".repeat(1024), "a".repeat(1024))' -); - -assertNotDeepOrStrict(new Date(), new Date(2000, 3, 14)); - -assertDeepAndStrictEqual(/a/, /a/); -assertDeepAndStrictEqual(/a/g, /a/g); -assertDeepAndStrictEqual(/a/i, /a/i); -assertDeepAndStrictEqual(/a/m, /a/m); -assertDeepAndStrictEqual(/a/igm, /a/igm); -assertNotDeepOrStrict(/ab/, /a/); -assertNotDeepOrStrict(/a/g, /a/); -assertNotDeepOrStrict(/a/i, /a/); -assertNotDeepOrStrict(/a/m, /a/); -assertNotDeepOrStrict(/a/igm, /a/im); - -{ - const re1 = /a/g; - re1.lastIndex = 3; - assert.notDeepEqual(re1, /a/g); -} + nameBuilder.prototype = nbRoot; -assert.deepEqual(4, '4'); -assert.deepEqual(true, 1); -assert.throws(() => assert.deepEqual(4, '5'), - AssertionError, - 'deepEqual( 4, \'5\')'); - -// Having the same number of owned properties && the same set of keys. -assert.deepEqual({ a: 4 }, { a: 4 }); -assert.deepEqual({ a: 4, b: '2' }, { a: 4, b: '2' }); -assert.deepEqual([4], ['4']); -assert.throws( - () => assert.deepEqual({ a: 4 }, { a: 4, b: true }), AssertionError); -assert.notDeepEqual(['a'], { 0: 'a' }); -assert.deepEqual({ a: 4, b: '1' }, { b: '1', a: 4 }); -const a1 = [1, 2, 3]; -const a2 = [1, 2, 3]; -a1.a = 'test'; -a1.b = true; -a2.b = true; -a2.a = 'test'; -assert.throws(() => assert.deepEqual(Object.keys(a1), Object.keys(a2)), - AssertionError); -assertDeepAndStrictEqual(a1, a2); - -// Having an identical prototype property. -const nbRoot = { - toString() { return `${this.first} ${this.last}`; } -}; - -function nameBuilder(first, last) { - this.first = first; - this.last = last; - return this; -} -nameBuilder.prototype = nbRoot; + function nameBuilder2(first, last) { + this.first = first; + this.last = last; + return this; + } + nameBuilder2.prototype = nbRoot; -function nameBuilder2(first, last) { - this.first = first; - this.last = last; - return this; -} -nameBuilder2.prototype = nbRoot; + const nb1 = new nameBuilder('Ryan', 'Dahl'); + let nb2 = new nameBuilder2('Ryan', 'Dahl'); -const nb1 = new nameBuilder('Ryan', 'Dahl'); -let nb2 = new nameBuilder2('Ryan', 'Dahl'); + assert.deepEqual(nb1, nb2); -assert.deepEqual(nb1, nb2); + nameBuilder2.prototype = Object; + nb2 = new nameBuilder2('Ryan', 'Dahl'); + assert.deepEqual(nb1, nb2); +}); -nameBuilder2.prototype = Object; -nb2 = new nameBuilder2('Ryan', 'Dahl'); -assert.deepEqual(nb1, nb2); +test('Primitives', () => { + assertNotDeepOrStrict(null, {}); + assertNotDeepOrStrict(undefined, {}); + assertNotDeepOrStrict('a', ['a']); + assertNotDeepOrStrict('a', { 0: 'a' }); + assertNotDeepOrStrict(1, {}); + assertNotDeepOrStrict(true, {}); + assertNotDeepOrStrict(Symbol(), {}); + assertNotDeepOrStrict(Symbol(), Symbol()); -// Primitives -assertNotDeepOrStrict(null, {}); -assertNotDeepOrStrict(undefined, {}); -assertNotDeepOrStrict('a', ['a']); -assertNotDeepOrStrict('a', { 0: 'a' }); -assertNotDeepOrStrict(1, {}); -assertNotDeepOrStrict(true, {}); -assertNotDeepOrStrict(Symbol(), {}); -assertNotDeepOrStrict(Symbol(), Symbol()); + assertOnlyDeepEqual(4, '4'); + assertOnlyDeepEqual(true, 1); -assertOnlyDeepEqual(4, '4'); -assertOnlyDeepEqual(true, 1); + { + const s = Symbol(); + assertDeepAndStrictEqual(s, s); + } -{ - const s = Symbol(); - assertDeepAndStrictEqual(s, s); -} + // Primitive wrappers and object. + assertNotDeepOrStrict(new String('a'), ['a']); + assertNotDeepOrStrict(new String('a'), { 0: 'a' }); + assertNotDeepOrStrict(new Number(1), {}); + assertNotDeepOrStrict(new Boolean(true), {}); +}); -// Primitive wrappers and object. -assertNotDeepOrStrict(new String('a'), ['a']); -assertNotDeepOrStrict(new String('a'), { 0: 'a' }); -assertNotDeepOrStrict(new Number(1), {}); -assertNotDeepOrStrict(new Boolean(true), {}); +test('Additional tests', () => { + // Same number of keys but different key names. + assertNotDeepOrStrict({ a: 1 }, { b: 1 }); -// Same number of keys but different key names. -assertNotDeepOrStrict({ a: 1 }, { b: 1 }); + assert.deepStrictEqual(new Date(2000, 3, 14), new Date(2000, 3, 14)); -assert.deepStrictEqual(new Date(2000, 3, 14), new Date(2000, 3, 14)); + assert.throws( + () => assert.deepStrictEqual(new Date(), new Date(2000, 3, 14)), + AssertionError, + 'deepStrictEqual(new Date(), new Date(2000, 3, 14))' + ); -assert.throws( - () => assert.deepStrictEqual(new Date(), new Date(2000, 3, 14)), - AssertionError, - 'deepStrictEqual(new Date(), new Date(2000, 3, 14))' -); + assert.throws( + () => assert.notDeepStrictEqual(new Date(2000, 3, 14), new Date(2000, 3, 14)), + { + name: 'AssertionError', + message: 'Expected "actual" not to be strictly deep-equal to:\n\n' + + util.inspect(new Date(2000, 3, 14)) + } + ); -assert.throws( - () => assert.notDeepStrictEqual(new Date(2000, 3, 14), new Date(2000, 3, 14)), - { - name: 'AssertionError', - message: 'Expected "actual" not to be strictly deep-equal to:\n\n' + - util.inspect(new Date(2000, 3, 14)) - } -); + assert.notDeepStrictEqual(new Date(), new Date(2000, 3, 14)); -assert.notDeepStrictEqual(new Date(), new Date(2000, 3, 14)); + assert.throws( + () => assert.deepStrictEqual(/ab/, /a/), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: `${defaultMsgStartFull}\n\n+ /ab/\n- /a/` + }); + assert.throws( + () => assert.deepStrictEqual(/a/g, /a/), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: `${defaultMsgStartFull}\n\n+ /a/g\n- /a/` + }); + assert.throws( + () => assert.deepStrictEqual(/a/i, /a/), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: `${defaultMsgStartFull}\n\n+ /a/i\n- /a/` + }); + assert.throws( + () => assert.deepStrictEqual(/a/m, /a/), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: `${defaultMsgStartFull}\n\n+ /a/m\n- /a/` + }); + assert.throws( + () => assert.deepStrictEqual(/aa/igm, /aa/im), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: `${defaultMsgStartFull}\n\n+ /aa/gim\n- /aa/im\n ^` + }); -assert.throws( - () => assert.deepStrictEqual(/ab/, /a/), { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: `${defaultMsgStartFull}\n\n+ /ab/\n- /a/` - }); -assert.throws( - () => assert.deepStrictEqual(/a/g, /a/), - { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: `${defaultMsgStartFull}\n\n+ /a/g\n- /a/` - }); -assert.throws( - () => assert.deepStrictEqual(/a/i, /a/), - { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: `${defaultMsgStartFull}\n\n+ /a/i\n- /a/` - }); -assert.throws( - () => assert.deepStrictEqual(/a/m, /a/), - { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: `${defaultMsgStartFull}\n\n+ /a/m\n- /a/` - }); -assert.throws( - () => assert.deepStrictEqual(/aa/igm, /aa/im), - { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: `${defaultMsgStartFull}\n\n+ /aa/gim\n- /aa/im\n ^` - }); + const re1 = /a/; + re1.lastIndex = 3; + assert.notDeepStrictEqual(re1, /a/); + } -{ - const re1 = /a/; - re1.lastIndex = 3; - assert.notDeepStrictEqual(re1, /a/); -} + assert.throws( + // eslint-disable-next-line no-restricted-syntax + () => assert.deepStrictEqual(4, '4'), + { message: `${defaultMsgStart}\n4 !== '4'\n` } + ); -assert.throws( - // eslint-disable-next-line no-restricted-syntax - () => assert.deepStrictEqual(4, '4'), - { message: `${defaultMsgStart}\n4 !== '4'\n` } -); - -assert.throws( - // eslint-disable-next-line no-restricted-syntax - () => assert.deepStrictEqual(true, 1), - { message: `${defaultMsgStart}\ntrue !== 1\n` } -); - -// Having the same number of owned properties && the same set of keys. -assert.deepStrictEqual({ a: 4 }, { a: 4 }); -assert.deepStrictEqual({ a: 4, b: '2' }, { a: 4, b: '2' }); -assert.throws(() => assert.deepStrictEqual([4], ['4']), - { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: `${defaultMsgStartFull}\n\n [\n+ 4\n- '4'\n ]` - }); -assert.throws( - () => assert.deepStrictEqual({ a: 4 }, { a: 4, b: true }), - { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: `${defaultMsgStartFull}\n\n ` + - '{\n a: 4,\n- b: true\n }' - }); -assert.throws( - () => assert.deepStrictEqual(['a'], { 0: 'a' }), - { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: `${defaultMsgStartFull}\n\n` + - "+ [\n+ 'a'\n+ ]\n- {\n- '0': 'a'\n- }" - }); + assert.throws( + // eslint-disable-next-line no-restricted-syntax + () => assert.deepStrictEqual(true, 1), + { message: `${defaultMsgStart}\ntrue !== 1\n` } + ); -/* eslint-enable */ + assertDeepAndStrictEqual({ a: 4, b: '1' }, { b: '1', a: 4 }); -assertDeepAndStrictEqual({ a: 4, b: '1' }, { b: '1', a: 4 }); + assert.throws( + () => assert.deepStrictEqual([0, 1, 2, 'a', 'b'], [0, 1, 2, 'b', 'a']), + AssertionError); +}); + +test('Having the same number of owned properties && the same set of keys', () => { + assert.deepStrictEqual({ a: 4 }, { a: 4 }); + assert.deepStrictEqual({ a: 4, b: '2' }, { a: 4, b: '2' }); + assert.throws(() => assert.deepStrictEqual([4], ['4']), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: `${defaultMsgStartFull}\n\n [\n+ 4\n- '4'\n ]` + }); + assert.throws( + () => assert.deepStrictEqual({ a: 4 }, { a: 4, b: true }), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: `${defaultMsgStartFull}\n\n ` + + '{\n a: 4,\n- b: true\n }' + }); + assert.throws( + () => assert.deepStrictEqual(['a'], { 0: 'a' }), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: `${defaultMsgStartFull}\n\n` + + "+ [\n+ 'a'\n+ ]\n- {\n- '0': 'a'\n- }" + }); +}); -assert.throws( - () => assert.deepStrictEqual([0, 1, 2, 'a', 'b'], [0, 1, 2, 'b', 'a']), - AssertionError); +/* eslint-enable */ -// Prototype check. -function Constructor1(first, last) { - this.first = first; - this.last = last; -} +test('Prototype check', () => { + function Constructor1(first, last) { + this.first = first; + this.last = last; + } -function Constructor2(first, last) { - this.first = first; - this.last = last; -} + function Constructor2(first, last) { + this.first = first; + this.last = last; + } -const obj1 = new Constructor1('Ryan', 'Dahl'); -let obj2 = new Constructor2('Ryan', 'Dahl'); + const obj1 = new Constructor1('Ryan', 'Dahl'); + let obj2 = new Constructor2('Ryan', 'Dahl'); -assert.throws(() => assert.deepStrictEqual(obj1, obj2), AssertionError); + assert.throws(() => assert.deepStrictEqual(obj1, obj2), AssertionError); -Constructor2.prototype = Constructor1.prototype; -obj2 = new Constructor2('Ryan', 'Dahl'); + Constructor2.prototype = Constructor1.prototype; + obj2 = new Constructor2('Ryan', 'Dahl'); -assertDeepAndStrictEqual(obj1, obj2); + assertDeepAndStrictEqual(obj1, obj2); +}); -// Check extra properties on errors. -{ +test('Check extra properties on errors', () => { const a = new TypeError('foo'); const b = new TypeError('foo'); a.foo = 'bar'; @@ -973,10 +985,9 @@ assertDeepAndStrictEqual(obj1, obj2); ' }' } ); -} +}); -// Check proxies. -{ +test('Check proxies', () => { const arrProxy = new Proxy([1, 2], {}); assert.deepStrictEqual(arrProxy, [1, 2]); const tmp = util.inspect.defaultOptions; @@ -998,12 +1009,11 @@ assertDeepAndStrictEqual(obj1, obj2); message: "'ownKeys' on proxy: trap result did not include 'length'" } ); -} +}); -// Strict equal with identical objects that are not identical -// by reference and longer than 50 elements -// E.g., assert.deepStrictEqual({ a: Symbol() }, { a: Symbol() }) -{ +test('Strict equal with identical objects that are not identical ' + + 'by reference and longer than 50 elements', () => { + // E.g., assert.deepStrictEqual({ a: Symbol() }, { a: Symbol() }) const a = {}; const b = {}; for (let i = 0; i < 55; i++) { @@ -1019,50 +1029,46 @@ assertDeepAndStrictEqual(obj1, obj2); message: /\.\.\./g } ); -} +}); -// Basic valueOf check. -{ +test('Basic valueOf check', () => { const a = new String(1); a.valueOf = undefined; assertNotDeepOrStrict(a, new String(1)); -} +}); -// Basic array out of bounds check. -{ +test('Basic array out of bounds check', () => { const arr = [1, 2, 3]; arr[2 ** 32] = true; assertNotDeepOrStrict(arr, [1, 2, 3]); -} -assert.throws( - () => assert.deepStrictEqual([1, 2, 3], [1, 2]), - { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: `${defaultMsgStartFull}\n\n` + - ' [\n' + - ' 1,\n' + - ' 2,\n' + - '+ 3\n' + - ' ]' - } -); + assert.throws( + () => assert.deepStrictEqual([1, 2, 3], [1, 2]), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: `${defaultMsgStartFull}\n\n` + + ' [\n' + + ' 1,\n' + + ' 2,\n' + + '+ 3\n' + + ' ]' + } + ); +}); -// Verify that manipulating the `getTime()` function has no impact on the time -// verification. -{ +test('Verify that manipulating the `getTime()` function has no impact on the time ' + + 'verification.', () => { const a = new Date('2000'); const b = new Date('2000'); Object.defineProperty(a, 'getTime', { value: () => 5 }); assertDeepAndStrictEqual(a, b); -} +}); -// Verify that an array and the equivalent fake array object -// are correctly compared -{ +test('Verify that an array and the equivalent fake array object ' + + 'are correctly compared', () => { const a = [1, 2, 3]; const o = { __proto__: Array.prototype, @@ -1073,10 +1079,9 @@ assert.throws( }; Object.defineProperty(o, 'length', { enumerable: false }); assertNotDeepOrStrict(o, a); -} +}); -// Verify that extra keys will be tested for when using fake arrays. -{ +test('Verify that extra keys will be tested for when using fake arrays', () => { const a = { 0: 1, 1: 1, @@ -1090,19 +1095,17 @@ assert.throws( value: 2 }); assertNotDeepOrStrict(a, [1, 1]); -} +}); -// Verify that changed tags will still check for the error message. -{ +test('Verify that changed tags will still check for the error message', () => { const err = new Error('foo'); err[Symbol.toStringTag] = 'Foobar'; const err2 = new Error('bar'); err2[Symbol.toStringTag] = 'Foobar'; assertNotDeepOrStrict(err, err2, AssertionError); -} +}); -// Check for non-native errors. -{ +test('Check for non-native errors', () => { const source = new Error('abc'); const err = Object.create( Object.getPrototypeOf(source), Object.getOwnPropertyDescriptors(source)); @@ -1113,19 +1116,17 @@ assert.throws( err[Symbol.toStringTag] = 'Foo'; err2[Symbol.toStringTag] = 'Foo'; assert.notDeepStrictEqual(err, err2); -} +}); -// Check for Errors with cause property -{ +test('Check for Errors with cause property', () => { const e1 = new Error('err', { cause: new Error('cause e1') }); const e2 = new Error('err', { cause: new Error('cause e2') }); assertNotDeepOrStrict(e1, e2, AssertionError); assertNotDeepOrStrict(e1, new Error('err'), AssertionError); assertDeepAndStrictEqual(e1, new Error('err', { cause: new Error('cause e1') })); -} +}); -// Check for AggregateError -{ +test('Check for AggregateError', () => { const e1 = new Error('e1'); const e1duplicate = new Error('e1'); const e2 = new Error('e2'); @@ -1136,10 +1137,9 @@ assert.throws( assertNotDeepOrStrict(e1, e3, AssertionError); assertNotDeepOrStrict(e3, e4, AssertionError); assertDeepAndStrictEqual(e3, e3duplicate); -} +}); -// Verify that `valueOf` is not called for boxed primitives. -{ +test('Verify that `valueOf` is not called for boxed primitives', () => { const a = new Number(5); const b = new Number(5); Object.defineProperty(a, 'valueOf', { @@ -1149,10 +1149,9 @@ assert.throws( value: () => { throw new Error('failed'); } }); assertDeepAndStrictEqual(a, b); -} +}); -// Check getters. -{ +test('Check getters', () => { const a = { get a() { return 5; } }; @@ -1170,10 +1169,9 @@ assert.throws( // The descriptor is not compared. assertDeepAndStrictEqual(a, { a: 5 }); -} +}); -// Verify object types being identical on both sides. -{ +test('Verify object types being identical on both sides', () => { let a = Buffer.from('test'); let b = Object.create( Object.getPrototypeOf(a), @@ -1236,21 +1234,19 @@ assert.throws( }); Object.setPrototypeOf(b, null); assertNotDeepOrStrict(a, b, assert.AssertionError); -} +}); -{ - // Verify commutativity +test('Verify commutativity', () => { // Regression test for https://github.com/nodejs/node/issues/37710 const a = { x: 1 }; const b = { y: 1 }; Object.defineProperty(b, 'x', { value: 1 }); assertNotDeepOrStrict(a, b); -} +}); -// eslint-disable-next-line node-core/crypto-check -if (common.hasCrypto) { - const crypto = require('crypto'); +test('Crypto', { skip: !hasCrypto }, async () => { + const crypto = require('crypto'); // eslint-disable-line node-core/crypto-check const { subtle } = globalThis.crypto; { @@ -1267,52 +1263,68 @@ if (common.hasCrypto) { assertDeepAndStrictEqual(a, b); } - (async () => { - { - const a = await subtle.importKey('raw', Buffer.alloc(1, 0), { name: 'HMAC', hash: 'SHA-256' }, true, ['sign']); - const b = await subtle.importKey('raw', Buffer.alloc(1, 1), { name: 'HMAC', hash: 'SHA-256' }, true, ['sign']); + { + const a = await subtle.importKey('raw', Buffer.alloc(1, 0), + { name: 'HMAC', hash: 'SHA-256' }, + true, ['sign']); + const b = await subtle.importKey('raw', Buffer.alloc(1, 1), + { name: 'HMAC', hash: 'SHA-256' }, + true, ['sign']); - assertNotDeepOrStrict(a, b); - } + assertNotDeepOrStrict(a, b); + } - { - const a = await subtle.importKey('raw', Buffer.alloc(1), { name: 'HMAC', hash: 'SHA-256' }, true, ['sign']); - const b = await subtle.importKey('raw', Buffer.alloc(1), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']); + { + const a = await subtle.importKey('raw', Buffer.alloc(1), + { name: 'HMAC', hash: 'SHA-256' }, + true, ['sign']); + const b = await subtle.importKey('raw', Buffer.alloc(1), + { name: 'HMAC', hash: 'SHA-256' }, + false, ['sign']); - assertNotDeepOrStrict(a, b); - } + assertNotDeepOrStrict(a, b); + } - { - const a = await subtle.importKey('raw', Buffer.alloc(1), { name: 'HMAC', hash: 'SHA-256' }, true, ['sign']); - const b = await subtle.importKey('raw', Buffer.alloc(1), { name: 'HMAC', hash: 'SHA-384' }, true, ['sign']); + { + const a = await subtle.importKey('raw', Buffer.alloc(1), + { name: 'HMAC', hash: 'SHA-256' }, + true, ['sign']); + const b = await subtle.importKey('raw', Buffer.alloc(1), + { name: 'HMAC', hash: 'SHA-384' }, + true, ['sign']); - assertNotDeepOrStrict(a, b); - } + assertNotDeepOrStrict(a, b); + } - { - const a = await subtle.importKey('raw', Buffer.alloc(1), { name: 'HMAC', hash: 'SHA-256' }, true, ['sign']); - const b = await subtle.importKey('raw', Buffer.alloc(1), { name: 'HMAC', hash: 'SHA-256' }, true, ['verify']); + { + const a = await subtle.importKey('raw', Buffer.alloc(1), + { name: 'HMAC', hash: 'SHA-256' }, + true, ['sign']); + const b = await subtle.importKey('raw', Buffer.alloc(1), + { name: 'HMAC', hash: 'SHA-256' }, + true, ['verify']); - assertNotDeepOrStrict(a, b); - } + assertNotDeepOrStrict(a, b); + } - { - const a = await subtle.importKey('raw', Buffer.alloc(1), { name: 'HMAC', hash: 'SHA-256' }, true, ['sign']); - const b = await subtle.importKey('raw', Buffer.alloc(1), { name: 'HMAC', hash: 'SHA-256' }, true, ['sign']); + { + const a = await subtle.importKey('raw', Buffer.alloc(1), + { name: 'HMAC', hash: 'SHA-256' }, + true, ['sign']); + const b = await subtle.importKey('raw', Buffer.alloc(1), + { name: 'HMAC', hash: 'SHA-256' }, + true, ['sign']); - assertDeepAndStrictEqual(a, b); - } - })().then(common.mustCall()); -} + assertDeepAndStrictEqual(a, b); + } +}); -// Comparing two identical WeakMap instances -{ +test('Comparing two identical WeakMap instances', () => { const weakMap = new WeakMap(); assertDeepAndStrictEqual(weakMap, weakMap); -} +}); -// Comparing two different WeakMap instances -{ +test('Comparing two different WeakMap instances', () => { const weakMap1 = new WeakMap(); const objA = {}; weakMap1.set(objA, 'ok'); @@ -1322,17 +1334,15 @@ if (common.hasCrypto) { weakMap2.set(objB, 'ok'); assertNotDeepOrStrict(weakMap1, weakMap2); -} +}); -// Comparing two identical WeakSet instances -{ +test('Comparing two identical WeakSet instances', () => { const weakSet = new WeakSet(); assertDeepAndStrictEqual(weakSet, weakSet); -} +}); -// Comparing two different WeakSet instances -{ +test('Comparing two different WeakSet instances', () => { const weakSet1 = new WeakSet(); const weakSet2 = new WeakSet(); assertNotDeepOrStrict(weakSet1, weakSet2); -} +}); diff --git a/test/parallel/test-assert-fail-deprecation.js b/test/parallel/test-assert-fail-deprecation.js index 5f51d27e3cfc0f..ab31b08f953fff 100644 --- a/test/parallel/test-assert-fail-deprecation.js +++ b/test/parallel/test-assert-fail-deprecation.js @@ -1,63 +1,70 @@ +// Flags: --no-warnings 'use strict'; -const common = require('../common'); +const { expectWarning } = require('../common'); const assert = require('assert'); +const { test } = require('node:test'); -common.expectWarning( +expectWarning( 'DeprecationWarning', 'assert.fail() with more than one argument is deprecated. ' + 'Please use assert.strictEqual() instead or only pass a message.', 'DEP0094' ); -// Two args only, operator defaults to '!=' -assert.throws(() => { - assert.fail('first', 'second'); -}, { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: '\'first\' != \'second\'', - operator: '!=', - actual: 'first', - expected: 'second', - generatedMessage: true +test('Two args only, operator defaults to "!="', () => { + assert.throws(() => { + assert.fail('first', 'second'); + }, { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: '\'first\' != \'second\'', + operator: '!=', + actual: 'first', + expected: 'second', + generatedMessage: true + }); }); -// Three args -assert.throws(() => { - assert.fail('ignored', 'ignored', 'another custom message'); -}, { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: 'another custom message', - operator: 'fail', - actual: 'ignored', - expected: 'ignored', - generatedMessage: false +test('Three args', () => { + assert.throws(() => { + assert.fail('ignored', 'ignored', 'another custom message'); + }, { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: 'another custom message', + operator: 'fail', + actual: 'ignored', + expected: 'ignored', + generatedMessage: false + }); }); -// Three args with custom Error -assert.throws(() => { - assert.fail(typeof 1, 'object', new TypeError('another custom message')); -}, { - name: 'TypeError', - message: 'another custom message' +test('Three args with custom Error', () => { + assert.throws(() => { + assert.fail(typeof 1, 'object', new TypeError('another custom message')); + }, { + name: 'TypeError', + message: 'another custom message' + }); }); -// No third arg (but a fourth arg) -assert.throws(() => { - assert.fail('first', 'second', undefined, 'operator'); -}, { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: '\'first\' operator \'second\'', - operator: 'operator', - actual: 'first', - expected: 'second' +test('No third arg (but a fourth arg)', () => { + assert.throws(() => { + assert.fail('first', 'second', undefined, 'operator'); + }, { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: '\'first\' operator \'second\'', + operator: 'operator', + actual: 'first', + expected: 'second' + }); }); -// The stackFrameFunction should exclude the foo frame -assert.throws( - function foo() { assert.fail('first', 'second', 'message', '!==', foo); }, - (err) => !/^\s*at\sfoo\b/m.test(err.stack) -); +test('The stackFrameFunction should exclude the foo frame', () => { + assert.throws( + function foo() { assert.fail('first', 'second', 'message', '!==', foo); }, + (err) => !/^\s*at\sfoo\b/m.test(err.stack) + ); +}); diff --git a/test/parallel/test-assert-fail.js b/test/parallel/test-assert-fail.js index 37e2087a2fdc72..3211e438a3a533 100644 --- a/test/parallel/test-assert-fail.js +++ b/test/parallel/test-assert-fail.js @@ -1,44 +1,50 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); +const { test } = require('node:test'); -// No args -assert.throws( - () => { assert.fail(); }, - { +test('No args', () => { + assert.throws( + () => { assert.fail(); }, + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: 'Failed', + operator: 'fail', + actual: undefined, + expected: undefined, + generatedMessage: true, + stack: /Failed/ + } + ); +}); + +test('One arg = message', () => { + assert.throws(() => { + assert.fail('custom message'); + }, { code: 'ERR_ASSERTION', name: 'AssertionError', - message: 'Failed', + message: 'custom message', operator: 'fail', actual: undefined, expected: undefined, - generatedMessage: true, - stack: /Failed/ - } -); - -// One arg = message -assert.throws(() => { - assert.fail('custom message'); -}, { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: 'custom message', - operator: 'fail', - actual: undefined, - expected: undefined, - generatedMessage: false + generatedMessage: false + }); }); -// One arg = Error -assert.throws(() => { - assert.fail(new TypeError('custom message')); -}, { - name: 'TypeError', - message: 'custom message' +test('One arg = Error', () => { + assert.throws(() => { + assert.fail(new TypeError('custom message')); + }, { + name: 'TypeError', + message: 'custom message' + }); }); -Object.prototype.get = common.mustNotCall(); -assert.throws(() => assert.fail(''), { code: 'ERR_ASSERTION' }); -delete Object.prototype.get; +test('Object prototype get', () => { + Object.prototype.get = () => { throw new Error('failed'); }; + assert.throws(() => assert.fail(''), { code: 'ERR_ASSERTION' }); + delete Object.prototype.get; +}); diff --git a/test/parallel/test-assert-first-line.js b/test/parallel/test-assert-first-line.js index f9d4a8b06cbea0..c5620284d7c63a 100644 --- a/test/parallel/test-assert-first-line.js +++ b/test/parallel/test-assert-first-line.js @@ -4,20 +4,23 @@ require('../common'); const assert = require('assert'); +const { test } = require('node:test'); const { path } = require('../common/fixtures'); -assert.throws( - () => require(path('assert-first-line')), - { - name: 'AssertionError', - message: "The expression evaluated to a falsy value:\n\n ässört.ok('')\n" - } -); +test('Verify that asserting in the very first line produces the expected result', () => { + assert.throws( + () => require(path('assert-first-line')), + { + name: 'AssertionError', + message: "The expression evaluated to a falsy value:\n\n ässört.ok('')\n" + } + ); -assert.throws( - () => require(path('assert-long-line')), - { - name: 'AssertionError', - message: "The expression evaluated to a falsy value:\n\n assert.ok('')\n" - } -); + assert.throws( + () => require(path('assert-long-line')), + { + name: 'AssertionError', + message: "The expression evaluated to a falsy value:\n\n assert.ok('')\n" + } + ); +}); diff --git a/test/parallel/test-assert-if-error.js b/test/parallel/test-assert-if-error.js index 9bc58cd73825a6..e5b11c9b90ca94 100644 --- a/test/parallel/test-assert-if-error.js +++ b/test/parallel/test-assert-if-error.js @@ -2,90 +2,93 @@ require('../common'); const assert = require('assert'); +const { test } = require('node:test'); -// Test that assert.ifError has the correct stack trace of both stacks. - -let err; -// Create some random error frames. -(function a() { - (function b() { - (function c() { - err = new Error('test error'); +test('Test that assert.ifError has the correct stack trace of both stacks', () => { + let err; + // Create some random error frames. + (function a() { + (function b() { + (function c() { + err = new Error('test error'); + })(); })(); })(); -})(); -const msg = err.message; -const stack = err.stack; + const msg = err.message; + const stack = err.stack; -(function x() { - (function y() { - (function z() { - let threw = false; - try { - assert.ifError(err); - } catch (e) { - assert.strictEqual(e.message, - 'ifError got unwanted exception: test error'); - assert.strictEqual(err.message, msg); - assert.strictEqual(e.actual, err); - assert.strictEqual(e.actual.stack, stack); - assert.strictEqual(e.expected, null); - assert.strictEqual(e.operator, 'ifError'); - threw = true; - } - assert(threw); + (function x() { + (function y() { + (function z() { + let threw = false; + try { + assert.ifError(err); + } catch (e) { + assert.strictEqual(e.message, + 'ifError got unwanted exception: test error'); + assert.strictEqual(err.message, msg); + assert.strictEqual(e.actual, err); + assert.strictEqual(e.actual.stack, stack); + assert.strictEqual(e.expected, null); + assert.strictEqual(e.operator, 'ifError'); + threw = true; + } + assert(threw); + })(); })(); })(); -})(); +}); -assert.throws( - () => { - const error = new Error(); - error.stack = 'Error: containing weird stack\nYes!\nI am part of a stack.'; - assert.ifError(error); - }, - (error) => { - assert(!error.stack.includes('Yes!')); - return true; - } -); +test('General ifError tests', () => { + assert.throws( + () => { + const error = new Error(); + error.stack = 'Error: containing weird stack\nYes!\nI am part of a stack.'; + assert.ifError(error); + }, + (error) => { + assert(!error.stack.includes('Yes!')); + return true; + } + ); -assert.throws( - () => assert.ifError(new TypeError()), - { - message: 'ifError got unwanted exception: TypeError' - } -); + assert.throws( + () => assert.ifError(new TypeError()), + { + message: 'ifError got unwanted exception: TypeError' + } + ); -assert.throws( - () => assert.ifError({ stack: false }), - { - message: 'ifError got unwanted exception: { stack: false }' - } -); + assert.throws( + () => assert.ifError({ stack: false }), + { + message: 'ifError got unwanted exception: { stack: false }' + } + ); -assert.throws( - () => assert.ifError({ constructor: null, message: '' }), - { - message: 'ifError got unwanted exception: ' - } -); + assert.throws( + () => assert.ifError({ constructor: null, message: '' }), + { + message: 'ifError got unwanted exception: ' + } + ); -assert.throws( - () => { assert.ifError(false); }, - { - message: 'ifError got unwanted exception: false' - } -); + assert.throws( + () => { assert.ifError(false); }, + { + message: 'ifError got unwanted exception: false' + } + ); +}); -// Should not throw. -assert.ifError(null); -assert.ifError(); -assert.ifError(undefined); +test('Should not throw', () => { + assert.ifError(null); + assert.ifError(); + assert.ifError(undefined); +}); -// https://github.com/nodejs/node-v0.x-archive/issues/2893 -{ +test('https://github.com/nodejs/node-v0.x-archive/issues/2893', () => { let threw = false; try { // eslint-disable-next-line no-restricted-syntax @@ -98,4 +101,4 @@ assert.ifError(undefined); assert(!e.stack.includes('throws'), e); } assert(threw); -} +});