From 907484f04d9d57be680d67a456bfa3a98d5372c6 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 2cda5fc0771b33..ef90a1a49f818f 100644 --- a/lib/internal/util/comparisons.js +++ b/lib/internal/util/comparisons.js @@ -28,6 +28,7 @@ const { const { compare } = internalBinding('buffer'); const assert = require('internal/assert'); const { isError } = require('internal/util'); +const { isURL } = require('internal/url'); const types = require('internal/util/types'); const { isAnyArrayBuffer, @@ -286,6 +287,10 @@ function innerDeepEqual(val1, val2, strict, memos) { ) { 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 13012c6fce273f..15367fd7213842 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 155996c283c5d6..251437f061e959 100644 --- a/test/parallel/test-assert-deep.js +++ b/test/parallel/test-assert-deep.js @@ -1345,3 +1345,47 @@ test('Crypto', { skip: !hasCrypto }, async () => { assertDeepAndStrictEqual(a, b); } }); + +// 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/ + } + ); +}