Skip to content

Commit

Permalink
Fixing bug regarding circular references in deepequal
Browse files Browse the repository at this point in the history
  • Loading branch information
DarrenPaulWright committed Apr 1, 2020
1 parent 1379ea4 commit 3a66c38
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 78 deletions.
80 changes: 42 additions & 38 deletions src/deepEqual.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,42 @@
import get from './get.js';
import isEqual from './isEqual.js';
import traverse from './traverse.js';

/**
* Deeply compares two items.
*
* @example
* ``` javascript
* import { deepEqual } from 'object-agent';
*
* deepEqual(null, undefined);
* // => false
*
* const item1 = {
* a: ['b']
* }
* const item2 = {
* a: ['c']
* }
*
* deepEqual(item1, item2);
* // => false
* ```
*
* @function deepEqual
* @category Comparison
*
* @arg {*} item1
* @arg {*} item2
*
* @returns {Boolean}
*/
export default (item1, item2) => {
return Object.is(item1, item2) || !traverse(item1, (path, value, isCircular) => {
return isCircular && Object.is(value, get(item2, path)) || !isEqual(value, get(item2, path));
});
};
import get from './get.js';
import isEqual from './isEqual.js';
import traverse from './traverse.js';

/**
* Deeply compares two items.
*
* @example
* ``` javascript
* import { deepEqual } from 'object-agent';
*
* deepEqual(null, undefined);
* // => false
*
* const item1 = {
* a: ['b']
* }
* const item2 = {
* a: ['c']
* }
*
* deepEqual(item1, item2);
* // => false
* ```
*
* @function deepEqual
* @category Comparison
*
* @arg {*} item1
* @arg {*} item2
*
* @returns {Boolean}
*/
export default (item1, item2) => {
return Object.is(item1, item2) || !traverse(item1, (path, value, isCircular) => {
if (isCircular && Object.is(value, get(item2, path))) {
return false;
}

return !isEqual(value, get(item2, path));
});
};
94 changes: 54 additions & 40 deletions tests/deepEqual.test.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,54 @@
import displayValue from 'display-value';
import { assert } from 'type-enforcer';
import { clone, deepEqual } from '../index.js';
import { testValues } from './testValues.js';

describe('deepEqual', () => {
testValues.forEach((value1, index1) => {
clone(testValues).forEach((value2, index2) => {
if (index1 !== index2) {
it(`should return false for ${displayValue(value1)} [${index1}] and ${displayValue(value2)} [${index2}]`, () => {
assert.is(deepEqual(value1, value2), false);
});
}
else {
it(`should return true for ${displayValue(value1)} [${index1}] and ${displayValue(value2)} [${index2}]`, () => {
assert.is(deepEqual(value1, value2), true);
});
}
});
});

it('should compare a circular reference', () => {
const object = {
key1: 'something',
key2: {
key3: 'another'
}
};
object.key2.key4 = [object.key2];
const object2 = {
key1: 'something',
key2: {
key3: 'another'
}
};
object2.key2.key4 = [object2.key2];

assert.equal(deepEqual(object, object2), true);
});
});
import displayValue from 'display-value';
import { assert } from 'type-enforcer';
import { clone, deepEqual } from '../index.js';
import { testValues } from './testValues.js';

describe('deepEqual', () => {
testValues.forEach((value1, index1) => {
clone(testValues).forEach((value2, index2) => {
if (index1 !== index2) {
it(`should return false for ${displayValue(value1)} [${index1}] and ${displayValue(value2)} [${index2}]`, () => {
assert.is(deepEqual(value1, value2), false);
});
}
else {
it(`should return true for ${displayValue(value1)} [${index1}] and ${displayValue(value2)} [${index2}]`, () => {
assert.is(deepEqual(value1, value2), true);
});
}
});
});

it('should compare the same item referenced multiple times', () => {
const item = {};

assert.equal(deepEqual([{
item
}, {
item
}], [{
item
}, {
item
}]), true);
});

it('should compare seperate circular references in different objects', () => {
const object = {
key1: 'something',
key2: {
key3: 'another'
}
};
object.key2.key4 = [object.key2];
const object2 = {
key1: 'something',
key2: {
key3: 'another'
}
};
object2.key2.key4 = [object2.key2];

assert.equal(deepEqual(object, object2), true);
});
});

0 comments on commit 3a66c38

Please sign in to comment.