diff --git a/expect/_equal.ts b/expect/_equal.ts index 1756af406..15b0351fa 100644 --- a/expect/_equal.ts +++ b/expect/_equal.ts @@ -185,9 +185,12 @@ export function equal(c: unknown, d: unknown, options?: EqualOptions): boolean { for (const [bKey, bValue] of b.entries()) { /* Given that Map keys can be references, we need * to ensure that they are also deeply equal */ + + if (!compare(aKey, bKey)) continue; + if ( - (aKey === aValue && bKey === bValue && compare(aKey, bKey)) || - (compare(aKey, bKey) && compare(aValue, bValue)) + (aKey === aValue && bKey === bValue) || + (compare(aValue, bValue)) ) { unmatchedEntries--; break; diff --git a/expect/_equal_test.ts b/expect/_equal_test.ts index 05a2fb0e4..347dc43db 100644 --- a/expect/_equal_test.ts +++ b/expect/_equal_test.ts @@ -290,3 +290,43 @@ Deno.test("equal() fast path for primitive keyed collections", () => { const map6 = new Map(arr.with(-1, -1).map((v, i) => [i, v])); assertFalse(equal(map5, map6)); }); + +Deno.test("equal() keyed collection edge cases", () => { + assert(equal(new Set([{ b: 2 }, { a: 1 }]), new Set([{ a: 1 }, { b: 2 }]))); + assertFalse( + equal(new Set([{ b: 2 }, { a: 1 }]), new Set([{ a: 1 }, { b: 3 }])), + ); + + const sym = Symbol(); + assert(equal(new Set([sym]), new Set([sym]))); + assert(equal(new Set([sym, "a"]), new Set(["a", sym]))); + assertFalse(equal(new Set([sym, "a"]), new Set(["b", sym]))); + assertFalse(equal(new Set([Symbol()]), new Set([Symbol()]))); + assert(equal(new Set([Symbol.for("x")]), new Set([Symbol.for("x")]))); + + assert(equal( + new Map([[{ b: 2 }, 2], [{ a: 1 }, 1]]), + new Map([[{ a: 1 }, 1], [{ b: 2 }, 2]]), + )); + assertFalse(equal( + new Map([[{ b: 2 }, 2], [{ a: 1 }, 1]]), + new Map([[{ a: 1 }, 1], [{ b: 2 }, 3]]), + )); + assertFalse(equal( + new Map([[{ b: 2 }, 2], [{ a: 1 }, 1]]), + new Map([[{ a: 1 }, 1], [{ b: 3 }, 2]]), + )); + + assert(equal( + new Map([[2, { b: 2 }], [1, { a: 1 }]]), + new Map([[1, { a: 1 }], [2, { b: 2 }]]), + )); + assertFalse(equal( + new Map([[2, { b: 2 }], [1, { a: 1 }]]), + new Map([[1, { a: 1 }], [3, { b: 2 }]]), + )); + assertFalse(equal( + new Map([[2, { b: 2 }], [1, { a: 1 }]]), + new Map([[1, { a: 1 }], [2, { b: 3 }]]), + )); +});