Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 76c9ab5

Browse filesBrowse files
TrottFishrock123
authored andcommitted
assert: allow circular references
assert.deepEqual() and assert.deepStrictEqual() will no longer throw a RangeError if passed objects with circular references. PR-URL: #6432 Fixes: #6416 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent b3f75ec commit 76c9ab5
Copy full SHA for 76c9ab5

File tree

Expand file treeCollapse file tree

2 files changed

+37
-16
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+37
-16
lines changed
Open diff view settings
Collapse file

‎lib/assert.js‎

Copy file name to clipboardExpand all lines: lib/assert.js
+17-4Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
143143
}
144144
};
145145

146-
function _deepEqual(actual, expected, strict) {
146+
function _deepEqual(actual, expected, strict, memos) {
147147
// 7.1. All identical values are equivalent, as determined by ===.
148148
if (actual === expected) {
149149
return true;
@@ -191,15 +191,27 @@ function _deepEqual(actual, expected, strict) {
191191
// corresponding key, and an identical 'prototype' property. Note: this
192192
// accounts for both named and indexed properties on Arrays.
193193
} else {
194-
return objEquiv(actual, expected, strict);
194+
memos = memos || {actual: [], expected: []};
195+
196+
const actualIndex = memos.actual.indexOf(actual);
197+
if (actualIndex !== -1) {
198+
if (actualIndex === memos.expected.indexOf(expected)) {
199+
return true;
200+
}
201+
}
202+
203+
memos.actual.push(actual);
204+
memos.expected.push(expected);
205+
206+
return objEquiv(actual, expected, strict, memos);
195207
}
196208
}
197209

198210
function isArguments(object) {
199211
return Object.prototype.toString.call(object) == '[object Arguments]';
200212
}
201213

202-
function objEquiv(a, b, strict) {
214+
function objEquiv(a, b, strict, actualVisitedObjects) {
203215
if (a === null || a === undefined || b === null || b === undefined)
204216
return false;
205217
// if one is a primitive, the other must be same
@@ -235,7 +247,8 @@ function objEquiv(a, b, strict) {
235247
//~~~possibly expensive deep test
236248
for (i = ka.length - 1; i >= 0; i--) {
237249
key = ka[i];
238-
if (!_deepEqual(a[key], b[key], strict)) return false;
250+
if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
251+
return false;
239252
}
240253
return true;
241254
}
Collapse file

‎test/parallel/test-assert.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-assert.js
+20-12Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -381,25 +381,33 @@ try {
381381

382382
assert.ok(threw);
383383

384-
// GH-207. Make sure deepEqual doesn't loop forever on circular refs
385-
var b = {};
386-
b.b = b;
384+
// https://github.com/nodejs/node/issues/6416
385+
// Make sure circular refs don't throw.
386+
{
387+
const b = {};
388+
b.b = b;
387389

388-
var c = {};
389-
c.b = c;
390+
const c = {};
391+
c.b = c;
390392

391-
var gotError = false;
392-
try {
393-
assert.deepEqual(b, c);
394-
} catch (e) {
395-
gotError = true;
396-
}
393+
a.doesNotThrow(makeBlock(a.deepEqual, b, c));
394+
a.doesNotThrow(makeBlock(a.deepStrictEqual, b, c));
397395

396+
const d = {};
397+
d.a = 1;
398+
d.b = d;
399+
400+
const e = {};
401+
e.a = 1;
402+
e.b = e.a;
403+
404+
a.throws(makeBlock(a.deepEqual, d, e), /AssertionError/);
405+
a.throws(makeBlock(a.deepStrictEqual, d, e), /AssertionError/);
406+
}
398407
// GH-7178. Ensure reflexivity of deepEqual with `arguments` objects.
399408
var args = (function() { return arguments; })();
400409
a.throws(makeBlock(a.deepEqual, [], args));
401410
a.throws(makeBlock(a.deepEqual, args, []));
402-
assert.ok(gotError);
403411

404412

405413
var circular = {y: 1};

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.