From e5ceb9d233106a9a10d77ec9831bf7b775c54f52 Mon Sep 17 00:00:00 2001 From: Mark Fulton Date: Thu, 3 Jun 2021 09:56:58 -0500 Subject: [PATCH] fix(equal): account for Weak* objects - `WeakMap` and `WeakSet` cannot be deeply compared (no `size`, `Symbol.iterator`, etc.) - `WeakRef` can be dereferenced Refs #949 --- testing/asserts.ts | 12 ++++++++++++ testing/asserts_test.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/testing/asserts.ts b/testing/asserts.ts index edc91b89051a..d7007bf16952 100644 --- a/testing/asserts.ts +++ b/testing/asserts.ts @@ -122,6 +122,14 @@ export function equal(c: unknown, d: unknown): boolean { return true; } if (a && typeof a === "object" && b && typeof b === "object") { + if (a instanceof WeakMap || b instanceof WeakMap) { + if (!(a instanceof WeakMap && b instanceof WeakMap)) return false; + throw new TypeError("cannot compare WeakMap instances"); + } + if (a instanceof WeakSet || b instanceof WeakSet) { + if (!(a instanceof WeakSet && b instanceof WeakSet)) return false; + throw new TypeError("cannot compare WeakSet instances"); + } if (seen.get(a) === b) { return true; } @@ -166,6 +174,10 @@ export function equal(c: unknown, d: unknown): boolean { } } seen.set(a, b); + if (a instanceof WeakRef || b instanceof WeakRef) { + if (!(a instanceof WeakRef && b instanceof WeakRef)) return false; + return compare(a.deref(), b.deref()); + } return true; } return false; diff --git a/testing/asserts_test.ts b/testing/asserts_test.ts index b2c70caa144b..5d42d1409512 100644 --- a/testing/asserts_test.ts +++ b/testing/asserts_test.ts @@ -153,6 +153,32 @@ Deno.test("testingEqual", function (): void { assert( !equal({ a: undefined, b: undefined }, { a: undefined }), ); + assertThrows(() => equal(new WeakMap(), new WeakMap())); + assertThrows(() => equal(new WeakSet(), new WeakSet())); + assert(!equal(new WeakMap(), new WeakSet())); + assert( + equal(new WeakRef({ hello: "world" }), new WeakRef({ hello: "world" })), + ); + assert( + !equal(new WeakRef({ world: "hello" }), new WeakRef({ hello: "world" })), + ); + assert(!equal({ hello: "world" }, new WeakRef({ hello: "world" }))); + assert( + equal( + new WeakRef({ hello: "world" }), + // deno-lint-ignore ban-types + new (class extends WeakRef {})({ hello: "world" }), + ), + ); + assert( + !equal( + new WeakRef({ hello: "world" }), + // deno-lint-ignore ban-types + new (class extends WeakRef { + foo = "bar"; + })({ hello: "world" }), + ), + ); }); Deno.test("testingNotEquals", function (): void {