assert: improve partialDeepStrictEqual by BridgeAR · Pull Request #57509 · nodejs/node · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions benchmark/assert/deepequal-buffer.js
34 changes: 27 additions & 7 deletions benchmark/assert/partial-deep-equal.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ const common = require('../common.js');
const assert = require('assert');

const bench = common.createBenchmark(main, {
n: [25],
n: [125],
size: [500],
extraProps: [0],
extraProps: [0, 1],
datasetName: [
'objects',
'sets',
'setsWithObjects',
'maps',
'circularRefs',
'typedArrays',
Expand All @@ -31,17 +32,29 @@ function createObjects(length, extraProps, depth = 0) {
foo: 'yarp',
nope: {
bar: '123',
...extraProps ? { a: [1, 2, i] } : {},
...(extraProps ? { a: [1, 2, i] } : {}),
c: {},
b: !depth ? createObjects(2, extraProps, depth + 1) : [],
},
}));
}

function createSetsWithObjects(length, extraProps, depth = 0) {
return Array.from({ length }, (_, i) => new Set([
...(extraProps ? [{}] : []),
{
simple: 'object',
number: i,
},
['array', 'with', 'values'],
new Set([[], {}, { nested: i }]),
]));
}

function createSets(length, extraProps, depth = 0) {
return Array.from({ length }, (_, i) => new Set([
'yarp',
...extraProps ? ['123', 1, 2] : [],
...(extraProps ? ['123', 1, 2] : []),
i + 3,
null,
{
Expand All @@ -56,7 +69,7 @@ function createSets(length, extraProps, depth = 0) {

function createMaps(length, extraProps, depth = 0) {
return Array.from({ length }, (_, i) => new Map([
...extraProps ? [['primitiveKey', 'primitiveValue']] : [],
...(extraProps ? [['primitiveKey', 'primitiveValue']] : []),
[42, 'numberKey'],
['objectValue', { a: 1, b: i }],
['arrayValue', [1, 2, i]],
Expand Down Expand Up @@ -114,16 +127,23 @@ function createTypedArrays(length, extraParts) {
}

function createArrayBuffers(length, extra) {
return Array.from({ length }, (_, n) => new ArrayBuffer(n + extra ? 1 : 0));
return Array.from({ length }, (_, n) => {
const buffer = Buffer.alloc(n + (extra ? 1 : 0));
for (let i = 0; i < n; i++) {
buffer.writeInt8(i % 128, i);
}
return buffer.buffer;
});
}

function createDataViewArrayBuffers(length, extra) {
return Array.from({ length }, (_, n) => new DataView(new ArrayBuffer(n + extra ? 1 : 0)));
return createArrayBuffers(length, extra).map((buffer) => new DataView(buffer));
}

const datasetMappings = {
objects: createObjects,
sets: createSets,
setsWithObjects: createSetsWithObjects,
maps: createMaps,
circularRefs: createCircularRefs,
typedArrays: createTypedArrays,
Expand Down
20 changes: 10 additions & 10 deletions lib/internal/util/comparisons.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ function innerDeepEqual(val1, val2, mode, memos) {
TypedArrayPrototypeGetSymbolToStringTag(val2)) {
return false;
}
if (mode === kPartial) {
if (mode === kPartial && val1.byteLength !== val2.byteLength) {
if (!isPartialArrayBufferView(val1, val2)) {
return false;
}
Expand Down Expand Up @@ -280,7 +280,7 @@ function innerDeepEqual(val1, val2, mode, memos) {
if (!isAnyArrayBuffer(val2)) {
return false;
}
if (mode !== kPartial) {
if (mode !== kPartial || val1.byteLength === val2.byteLength) {
if (!areEqualArrayBuffers(val1, val2)) {
return false;
}
Expand Down Expand Up @@ -546,18 +546,18 @@ function partialObjectSetEquiv(a, b, mode, set, memo) {
}

function setObjectEquiv(a, b, mode, set, memo) {
if (mode === kPartial) {
return partialObjectSetEquiv(a, b, mode, set, memo);
}
// Fast path for objects only
if (mode === kStrict && set.size === a.size) {
if (mode !== kLoose && set.size === a.size) {
for (const val of a) {
if (!setHasEqualElement(set, val, mode, memo)) {
return false;
}
}
return true;
}
if (mode === kPartial) {
return partialObjectSetEquiv(a, b, mode, set, memo);
}

for (const val of a) {
// Primitive values have already been handled above.
Expand Down Expand Up @@ -639,18 +639,18 @@ function partialObjectMapEquiv(a, b, mode, set, memo) {
}

function mapObjectEquivalence(a, b, mode, set, memo) {
if (mode === kPartial) {
return partialObjectMapEquiv(a, b, mode, set, memo);
}
// Fast path for objects only
if (mode === kStrict && set.size === a.size) {
if (mode !== kLoose && set.size === a.size) {
for (const { 0: key1, 1: item1 } of a) {
if (!mapHasEqualEntry(set, b, key1, item1, mode, memo)) {
return false;
}
}
return true;
}
if (mode === kPartial) {
return partialObjectMapEquiv(a, b, mode, set, memo);
}
for (const { 0: key1, 1: item1 } of a) {
if (typeof key1 === 'object' && key1 !== null) {
if (!mapHasEqualEntry(set, b, key1, item1, mode, memo))
Expand Down
12 changes: 11 additions & 1 deletion test/parallel/test-assert-partial-deep-equal.js