assert: make partialDeepStrictEqual throw when comparing [0] with [-0]

Fixes: https://github.com/nodejs/node/issues/56230
PR-URL: https://github.com/nodejs/node/pull/56237
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
Reviewed-By: Xuguang Mei <meixuguang@gmail.com>
Reviewed-By: Jordan Harband <ljharb@gmail.com>
This commit is contained in:
Giovanni authored and LiviaMedeiros committed 2024-12-28 16:50:20 +08:00
1 parent 7d7e2cec25
commit 91c6b8a38e
2 files changed
+100 -19

No files matched your search

+50 -19
View File
@@ -56,6 +56,7 @@ const {
StringPrototypeIndexOf,
StringPrototypeSlice,
StringPrototypeSplit,
Symbol,
SymbolIterator,
TypedArrayPrototypeGetLength,
Uint8Array,
@@ -497,6 +498,17 @@ function partiallyCompareSets(actual, expected, comparedObjects) {
return true;
}
const minusZeroSymbol = Symbol('-0');
const zeroSymbol = Symbol('0');
// Helper function to get a unique key for 0, -0 to avoid collisions
function getZeroKey(item) {
if (item === 0) {
return ObjectIs(item, -0) ? minusZeroSymbol : zeroSymbol;
}
return item;
}
function partiallyCompareArrays(actual, expected, comparedObjects) {
if (expected.length > actual.length) {
return false;
@@ -506,39 +518,58 @@ function partiallyCompareArrays(actual, expected, comparedObjects) {
// Create a map to count occurrences of each element in the expected array
const expectedCounts = new SafeMap();
for (const expectedItem of expected) {
let found = false;
for (const { 0: key, 1: count } of expectedCounts) {
if (isDeepStrictEqual(key, expectedItem)) {
expectedCounts.set(key, count + 1);
found = true;
break;
const safeExpected = new SafeArrayIterator(expected);
for (const expectedItem of safeExpected) {
// Check if the item is a zero or a -0, as these need to be handled separately
if (expectedItem === 0) {
const zeroKey = getZeroKey(expectedItem);
expectedCounts.set(zeroKey, (expectedCounts.get(zeroKey)?.count || 0) + 1);
} else {
let found = false;
for (const { 0: key, 1: count } of expectedCounts) {
if (isDeepStrictEqual(key, expectedItem)) {
expectedCounts.set(key, count + 1);
found = true;
break;
}
}
if (!found) {
expectedCounts.set(expectedItem, 1);
}
}
if (!found) {
expectedCounts.set(expectedItem, 1);
}
}
const safeActual = new SafeArrayIterator(actual);
// Create a map to count occurrences of relevant elements in the actual array
for (const actualItem of safeActual) {
for (const { 0: key, 1: count } of expectedCounts) {
if (isDeepStrictEqual(key, actualItem)) {
// Check if the item is a zero or a -0, as these need to be handled separately
if (actualItem === 0) {
const zeroKey = getZeroKey(actualItem);
if (expectedCounts.has(zeroKey)) {
const count = expectedCounts.get(zeroKey);
if (count === 1) {
expectedCounts.delete(key);
expectedCounts.delete(zeroKey);
} else {
expectedCounts.set(key, count - 1);
expectedCounts.set(zeroKey, count - 1);
}
}
} else {
for (const { 0: expectedItem, 1: count } of expectedCounts) {
if (isDeepStrictEqual(expectedItem, actualItem)) {
if (count === 1) {
expectedCounts.delete(expectedItem);
} else {
expectedCounts.set(expectedItem, count - 1);
}
break;
}
break;
}
}
}
const { size } = expectedCounts;
expectedCounts.clear();
return size === 0;
return expectedCounts.size === 0;
}
/**