diff --git a/lib/assert.js b/lib/assert.js index f7a3350db10..1350f0abbbb 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -271,8 +271,15 @@ function innerDeepEqual(actual, expected, strict, memos) { position: 0 }; } else { - if (memos.actual.has(actual)) { - return memos.actual.get(actual) === memos.expected.get(expected); + // We prevent up to two map.has(x) calls by directly retrieving the value + // and checking for undefined. The map can only contain numbers, so it is + // safe to check for undefined only. + const expectedMemoA = memos.actual.get(actual); + if (expectedMemoA !== undefined) { + const expectedMemoB = memos.expected.get(expected); + if (expectedMemoB !== undefined) { + return expectedMemoA === expectedMemoB; + } } memos.position++; } diff --git a/test/parallel/test-assert-deep.js b/test/parallel/test-assert-deep.js index 51f07af09e0..b4f7fa47e39 100644 --- a/test/parallel/test-assert-deep.js +++ b/test/parallel/test-assert-deep.js @@ -303,6 +303,26 @@ assertOnlyDeepEqual( new Set([undefined]) ); +// Circular structures +{ + const a = {}; + const b = {}; + a.a = a; + b.a = {}; + b.a.a = a; + assertDeepAndStrictEqual(a, b); +} + +{ + const a = new Set(); + const b = new Set(); + const c = new Set(); + a.add(a); + b.add(b); + c.add(a); + assertDeepAndStrictEqual(b, c); +} + { const values = [ 123, diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index 65181996d5a..17adf33b8b3 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -578,8 +578,8 @@ a.throws(makeBlock(thrower, TypeError), function(err) { const h = { ref: g }; - a.throws(makeBlock(a.deepEqual, f, h), /AssertionError/); - a.throws(makeBlock(a.deepStrictEqual, f, h), /AssertionError/); + a.doesNotThrow(makeBlock(a.deepEqual, f, h)); + a.doesNotThrow(makeBlock(a.deepStrictEqual, f, h)); } // GH-7178. Ensure reflexivity of deepEqual with `arguments` objects. const args = (function() { return arguments; })();