From ac49b20c75696d893149a4b6ca675d591fb4e57a Mon Sep 17 00:00:00 2001 From: Xuguang Mei Date: Sun, 13 Oct 2024 22:01:47 +0800 Subject: [PATCH] assert: fix deepEqual always return true on URL PR-URL: https://github.com/nodejs/node/pull/50853 Fixes: https://github.com/nodejs/node/issues/50836 Reviewed-By: Yagiz Nizipli Reviewed-By: Marco Ippolito Reviewed-By: Ruben Bridgewater --- lib/internal/util/comparisons.js | 5 ++++ lib/internal/util/inspect.js | 10 +++++++ test/parallel/test-assert-deep.js | 44 +++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/lib/internal/util/comparisons.js b/lib/internal/util/comparisons.js index c98199f7c376a6..b28860e9000ce8 100644 --- a/lib/internal/util/comparisons.js +++ b/lib/internal/util/comparisons.js @@ -27,6 +27,7 @@ const { const { compare } = internalBinding('buffer'); const assert = require('internal/assert'); +const { isURL } = require('internal/url'); const types = require('internal/util/types'); const { isAnyArrayBuffer, @@ -287,6 +288,10 @@ function innerDeepEqual(val1, val2, strict, memos) { } } else if (isWeakMap(val1) || isWeakSet(val1)) { return false; + } else if (isURL(val1)) { + if (!isURL(val2) || val1.href !== val2.href) { + return false; + } } return keyCheck(val1, val2, strict, memos, kNoIterator); diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index df90ed34d51d73..ade91b3c5a6711 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -166,6 +166,11 @@ function pathToFileUrlHref(filepath) { return internalUrl.pathToFileURL(filepath).href; } +function isURL(value) { + internalUrl ??= require('internal/url'); + return typeof value.href === 'string' && value instanceof internalUrl.URL; +} + const builtInObjects = new SafeSet( ArrayPrototypeFilter( ObjectGetOwnPropertyNames(globalThis), @@ -1026,6 +1031,11 @@ function formatRaw(ctx, value, recurseTimes, typedArray) { if (keys.length === 0 && protoProps === undefined) { return base; } + } else if (isURL(value) && !(recurseTimes > ctx.depth && ctx.depth !== null)) { + base = value.href; + if (keys.length === 0 && protoProps === undefined) { + return base; + } } else { if (keys.length === 0 && protoProps === undefined) { if (isExternal(value)) { diff --git a/test/parallel/test-assert-deep.js b/test/parallel/test-assert-deep.js index a8bc5d3cf4e815..a83a9e3329e5e4 100644 --- a/test/parallel/test-assert-deep.js +++ b/test/parallel/test-assert-deep.js @@ -1346,3 +1346,47 @@ test('Comparing two different WeakSet instances', () => { const weakSet2 = new WeakSet(); assertNotDeepOrStrict(weakSet1, weakSet2); }); + +// check URL +{ + const a = new URL('http://foo'); + const b = new URL('http://bar'); + + assertNotDeepOrStrict(a, b); +} + +{ + const a = new URL('http://foo'); + const b = new URL('http://foo'); + + assertDeepAndStrictEqual(a, b); +} + +{ + const a = new URL('http://foo'); + const b = new URL('http://foo'); + a.bar = 1; + b.bar = 2; + assertNotDeepOrStrict(a, b); +} + +{ + const a = new URL('http://foo'); + const b = new URL('http://foo'); + a.bar = 1; + b.bar = 1; + assertDeepAndStrictEqual(a, b); +} + +{ + const a = new URL('http://foo'); + const b = new URL('http://bar'); + assert.throws( + () => assert.deepStrictEqual(a, b), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: /http:\/\/bar/ + } + ); +}