diff --git a/index.js b/index.js
index 6d2afac..552f0d2 100644
--- a/index.js
+++ b/index.js
@@ -357,6 +357,20 @@ function getGeneratorEntries(generator) {
return accumulator;
}
+/*!
+ * Gets all own and inherited enumerable keys from a target.
+ *
+ * @param {Object} target
+ * @returns {Array} an array of own and inherited enumerable keys from the target.
+ */
+function getEnumerableKeys(target) {
+ var keys = [];
+ for (var key in target) {
+ keys.push(key);
+ }
+ return keys;
+}
+
/*!
* Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of
* 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) {
*/
function objectEqual(leftHandOperand, rightHandOperand, options) {
- if (Object.getPrototypeOf(leftHandOperand) !== Object.getPrototypeOf(rightHandOperand)) {
- return false;
- }
-
- var leftHandKeys = Object.keys(leftHandOperand);
- var rightHandKeys = Object.keys(rightHandOperand);
+ var leftHandKeys = getEnumerableKeys(leftHandOperand);
+ var rightHandKeys = getEnumerableKeys(rightHandOperand);
if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) {
leftHandKeys.sort();
rightHandKeys.sort();
diff --git a/test/index.js b/test/index.js
index 22c5de6..0fd8e8a 100644
--- a/test/index.js
+++ b/test/index.js
@@ -192,6 +192,15 @@ describe('Generic', function () {
assert(eql(new BaseA(1), new BaseA(1)), 'eql(new BaseA(1), new BaseA(1))');
});
+ it('returns true given two class instances with deeply equal bases', function () {
+ function BaseA() {}
+ function BaseB() {}
+ BaseA.prototype.foo = { a: 1 };
+ BaseB.prototype.foo = { a: 1 };
+ assert(eql(new BaseA(), new BaseB()) === true,
+ 'eql(new , new ) === true');
+ });
+
it('returns false given two class instances with different properties', function () {
function BaseA(prop) {
this.prop = prop;
@@ -199,10 +208,13 @@ describe('Generic', function () {
assert(eql(new BaseA(1), new BaseA(2)) === false, 'eql(new BaseA(1), new BaseA(2)) === false');
});
- it('returns false given two different empty class instances', function () {
+ it('returns false given two class instances with deeply unequal bases', function () {
function BaseA() {}
function BaseB() {}
- assert(eql(new BaseA(), new BaseB()) === false, 'eql(new BaseA(), new BaseB()) === false');
+ BaseA.prototype.foo = { a: 1 };
+ BaseB.prototype.foo = { a: 2 };
+ assert(eql(new BaseA(), new BaseB()) === false,
+ 'eql(new , new ) === false');
});
});
@@ -283,6 +295,13 @@ describe('Generic', function () {
'eql({ foo: 1, bar: objectC }, { foo: 1, bar: objectC }) === true');
});
+ it('returns true with objects with deeply equal prototypes', function () {
+ var objectA = Object.create({ foo: { a: 1 } });
+ var objectB = Object.create({ foo: { a: 1 } });
+ assert(eql(objectA, objectB) === true,
+ 'eql(Object.create({ foo: { a: 1 } }), Object.create({ foo: { a: 1 } })) === true');
+ });
+
it('returns false with objects containing different literals', function () {
assert(eql({ foo: 1, bar: 1 }, { foo: 1, bar: 2 }) === false,
'eql({ foo: 1, bar: 2 }, { foo: 1, bar: 2 }) === false');
@@ -306,6 +325,13 @@ describe('Generic', function () {
'eql({ foo: 1, bar: -> }, { foo: 1, bar: <- }) === true');
});
+ it('returns false with objects with deeply unequal prototypes', function () {
+ var objectA = Object.create({ foo: { a: 1 } });
+ var objectB = Object.create({ foo: { a: 2 } });
+ assert(eql(objectA, objectB) === false,
+ 'eql(Object.create({ foo: { a: 1 } }), Object.create({ foo: { a: 2 } })) === false');
+ });
+
});
describe('functions', function () {