diff --git a/index.js b/index.js index 1301ff0..1403f8e 100644 --- a/index.js +++ b/index.js @@ -18,8 +18,7 @@ function equal(a, b) { if (Array.isArray(a)) { length = a.length; if (length != b.length) return false; - for (i = length; i-- !== 0;) - if (!equal(a[i], b[i])) return false; + for (i = length; i-- !== 0; ) if (!equal(a[i], b[i])) return false; return true; } @@ -44,22 +43,19 @@ function equal(a, b) { // // **Note**: `i` access switches to `i.value`. var it; - if (hasMap && (a instanceof Map) && (b instanceof Map)) { + if (hasMap && a instanceof Map && b instanceof Map) { if (a.size !== b.size) return false; it = a.entries(); - while (!(i = it.next()).done) - if (!b.has(i.value[0])) return false; + while (!(i = it.next()).done) if (!b.has(i.value[0])) return false; it = a.entries(); - while (!(i = it.next()).done) - if (!equal(i.value[1], b.get(i.value[0]))) return false; + while (!(i = it.next()).done) if (!equal(i.value[1], b.get(i.value[0]))) return false; return true; } - if (hasSet && (a instanceof Set) && (b instanceof Set)) { + if (hasSet && a instanceof Set && b instanceof Set) { if (a.size !== b.size) return false; it = a.entries(); - while (!(i = it.next()).done) - if (!b.has(i.value[0])) return false; + while (!(i = it.next()).done) if (!b.has(i.value[0])) return false; return true; } // END: Modifications @@ -67,8 +63,7 @@ function equal(a, b) { if (hasArrayBuffer && ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { length = a.length; if (length != b.length) return false; - for (i = length; i-- !== 0;) - if (a[i] !== b[i]) return false; + for (i = length; i-- !== 0; ) if (a[i] !== b[i]) return false; return true; } @@ -80,8 +75,7 @@ function equal(a, b) { length = keys.length; if (length !== Object.keys(b).length) return false; - for (i = length; i-- !== 0;) - if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; + for (i = length; i-- !== 0; ) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; // END: fast-deep-equal // START: react-fast-compare @@ -89,7 +83,7 @@ function equal(a, b) { if (hasElementType && a instanceof Element) return false; // custom handling for React/Preact - for (i = length; i-- !== 0;) { + for (i = length; i-- !== 0; ) { if ((keys[i] === '_owner' || keys[i] === '__v' || keys[i] === '__o') && a.$$typeof) { // React-specific: avoid traversing React elements' _owner // Preact-specific: avoid traversing Preact elements' __v and __o @@ -111,6 +105,8 @@ function equal(a, b) { return true; } + if (typeof a === 'function' && typeof b === 'function') return a.toString() === b.toString(); + return a !== a && b !== b; } // end fast-deep-equal @@ -119,7 +115,7 @@ module.exports = function isEqual(a, b) { try { return equal(a, b); } catch (error) { - if (((error.message || '').match(/stack|recursion/i))) { + if ((error.message || '').match(/stack|recursion/i)) { // warn on circular references, don't crash // browsers give this different errors name and messages: // chrome/safari: "RangeError", "Maximum call stack size exceeded" diff --git a/test/node/tests.js b/test/node/tests.js index 02336e5..8ff7065 100644 --- a/test/node/tests.js +++ b/test/node/tests.js @@ -3,40 +3,39 @@ var generic = require('fast-deep-equal-git/spec/tests.js'); var es6 = require('fast-deep-equal-git/spec/es6tests.js'); const reactElementA = { - '$$typeof': 'react.element', + $$typeof: 'react.element', type: 'div', key: null, ref: null, props: { x: 1 }, _owner: {}, - _store: {} + _store: {}, }; // in reality the _owner object is much more complex (and contains over dozen circular references) reactElementA._owner.children = [reactElementA]; const reactElementA2 = { - '$$typeof': 'react.element', + $$typeof: 'react.element', type: 'div', key: null, ref: null, props: { x: 1 }, _owner: {}, - _store: {} + _store: {}, }; reactElementA2._owner.children = [reactElementA2]; const reactElementB = { - '$$typeof': 'react.element', + $$typeof: 'react.element', type: 'div', key: null, ref: null, props: { x: 2 }, _owner: {}, - _store: {} + _store: {}, }; reactElementB._owner.children = [reactElementB]; - const react = [ { description: 'React elements', @@ -46,27 +45,57 @@ const react = [ description: 'an element compared with itself', value1: reactElementA, value2: reactElementA, - equal: true + equal: true, }, { description: 'two elements equal by value', value1: reactElementA, value2: reactElementA2, - equal: true + equal: true, }, { description: 'two elements unequal by value', value1: reactElementA, value2: reactElementB, - equal: false - } - ] - } + equal: false, + }, + ], + }, +]; + +const exampleFn = () => 'foo'; + +const functions = [ + { + description: 'Functions', + reactSpecific: false, + tests: [ + { + description: 'a function compared with itself', + value1: exampleFn, + value2: exampleFn, + equal: true, + }, + { + description: 'two equal inline functions', + value1: () => 'foo', + value2: () => 'foo', + equal: true, + }, + { + description: 'two functions with different results', + value1: () => 'foo', + value2: () => 'bar', + equal: false, + }, + ], + }, ]; module.exports = { generic, es6, react, - all: [...generic, ...es6, ...react], + functions, + all: [...generic, ...es6, ...react, ...functions], };