Skip to content

Commit 248a5b3

Browse files
authored
Merge pull request #22 from meeber/fix-deep-algo
fix: compare inherited properties not prototypes
2 parents 841f6f5 + 3f9265c commit 248a5b3

2 files changed

Lines changed: 44 additions & 8 deletions

File tree

index.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,20 @@ function getGeneratorEntries(generator) {
357357
return accumulator;
358358
}
359359

360+
/*!
361+
* Gets all own and inherited enumerable keys from a target.
362+
*
363+
* @param {Object} target
364+
* @returns {Array} an array of own and inherited enumerable keys from the target.
365+
*/
366+
function getEnumerableKeys(target) {
367+
var keys = [];
368+
for (var key in target) {
369+
keys.push(key);
370+
}
371+
return keys;
372+
}
373+
360374
/*!
361375
* Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of
362376
* each key. If any value of the given key is not equal, the function will return false (early).
@@ -391,12 +405,8 @@ function keysEqual(leftHandOperand, rightHandOperand, keys, options) {
391405
*/
392406

393407
function objectEqual(leftHandOperand, rightHandOperand, options) {
394-
if (Object.getPrototypeOf(leftHandOperand) !== Object.getPrototypeOf(rightHandOperand)) {
395-
return false;
396-
}
397-
398-
var leftHandKeys = Object.keys(leftHandOperand);
399-
var rightHandKeys = Object.keys(rightHandOperand);
408+
var leftHandKeys = getEnumerableKeys(leftHandOperand);
409+
var rightHandKeys = getEnumerableKeys(rightHandOperand);
400410
if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) {
401411
leftHandKeys.sort();
402412
rightHandKeys.sort();

test/index.js

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,17 +192,29 @@ describe('Generic', function () {
192192
assert(eql(new BaseA(1), new BaseA(1)), 'eql(new BaseA(1), new BaseA(1))');
193193
});
194194

195+
it('returns true given two class instances with deeply equal bases', function () {
196+
function BaseA() {}
197+
function BaseB() {}
198+
BaseA.prototype.foo = { a: 1 };
199+
BaseB.prototype.foo = { a: 1 };
200+
assert(eql(new BaseA(), new BaseB()) === true,
201+
'eql(new <base with .prototype.foo = { a: 1 }>, new <base with .prototype.foo = { a: 1 }>) === true');
202+
});
203+
195204
it('returns false given two class instances with different properties', function () {
196205
function BaseA(prop) {
197206
this.prop = prop;
198207
}
199208
assert(eql(new BaseA(1), new BaseA(2)) === false, 'eql(new BaseA(1), new BaseA(2)) === false');
200209
});
201210

202-
it('returns false given two different empty class instances', function () {
211+
it('returns false given two class instances with deeply unequal bases', function () {
203212
function BaseA() {}
204213
function BaseB() {}
205-
assert(eql(new BaseA(), new BaseB()) === false, 'eql(new BaseA(), new BaseB()) === false');
214+
BaseA.prototype.foo = { a: 1 };
215+
BaseB.prototype.foo = { a: 2 };
216+
assert(eql(new BaseA(), new BaseB()) === false,
217+
'eql(new <base with .prototype.foo = { a: 1 }>, new <base with .prototype.foo = { a: 2 }>) === false');
206218
});
207219

208220
});
@@ -283,6 +295,13 @@ describe('Generic', function () {
283295
'eql({ foo: 1, bar: objectC }, { foo: 1, bar: objectC }) === true');
284296
});
285297

298+
it('returns true with objects with deeply equal prototypes', function () {
299+
var objectA = Object.create({ foo: { a: 1 } });
300+
var objectB = Object.create({ foo: { a: 1 } });
301+
assert(eql(objectA, objectB) === true,
302+
'eql(Object.create({ foo: { a: 1 } }), Object.create({ foo: { a: 1 } })) === true');
303+
});
304+
286305
it('returns false with objects containing different literals', function () {
287306
assert(eql({ foo: 1, bar: 1 }, { foo: 1, bar: 2 }) === false,
288307
'eql({ foo: 1, bar: 2 }, { foo: 1, bar: 2 }) === false');
@@ -306,6 +325,13 @@ describe('Generic', function () {
306325
'eql({ foo: 1, bar: -> }, { foo: 1, bar: <- }) === true');
307326
});
308327

328+
it('returns false with objects with deeply unequal prototypes', function () {
329+
var objectA = Object.create({ foo: { a: 1 } });
330+
var objectB = Object.create({ foo: { a: 2 } });
331+
assert(eql(objectA, objectB) === false,
332+
'eql(Object.create({ foo: { a: 1 } }), Object.create({ foo: { a: 2 } })) === false');
333+
});
334+
309335
});
310336

311337
describe('functions', function () {

0 commit comments

Comments
 (0)