UNPKG

foop

Version:

interfaces that describe their intentions.

161 lines (139 loc) 4.83 kB
// conditionals /* eslint complexity: "OFF" */ // not iterating on empty root /* eslint consistent-return: "OFF" */ // const traverse = require('../traverse') // const get = require('../dot/get') const isObjNotNull = require('../is/objNotNull') const isNull = require('../is/null') const isEmpty = require('../is/empty') const ENV_DEBUG = require('../env/debug') const eqValue = require('./eqValue') /* prettier-ignore */ /** * @name eq * @alias equals * @since 3.0.0 * @version 5.0.0 * @memberOf Traverse * * {@link https://github.com/andrewplummer/Sugar/blob/master/lib/common.js#L668 sugar-equal} * {@link https://github.com/the-grid/finitedomain/blob/master/src/propagator.js#L160 eq-qfox} * {@link https://github.com/jasmine/jasmine.github.io/blob/master/lib/jasmine-1.3.1/jasmine.js#L940 jasmine-equals} * {@link https://github.com/mobxjs/mobx/blob/master/src/utils/utils.ts#L145 mobx-deepequal} * {@link https://github.com/js-data/js-data/blob/v2/src/utils.js#L571 js-data-circular} * {@link https://github.com/js-data/js-data/blob/v2/src/utils.js#L300 js-data-equals} * {@link http://dorey.github.io/JavaScript-Equality-Table/ js-equality-table} * {@link https://github.com/facebook/react/blob/master/src/__mocks__/deepDiffer.js react-deep-differ} * {@link https://github.com/substack/js-traverse/blob/master/test/lib/deep_equal.js traverse-deep-equal} * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L1183 underscore-equal} * {@link https://github.com/angular/angular.js/blob/master/src/Angular.js angular-is-equal} * {@link https://lodash.com/docs/4.17.4#isEqual lodash-is-equal} * {@link http://ramdajs.com/docs/#equals ramda-equals} * {@link https://github.com/substack/node-deep-equal node-deep-equal} * {@link https://github.com/facebook/immutable-js/blob/master/src/utils/deepEqual.js immutable-js-deep-equal} * @see {@link mobx-deepequal} * @see {@link js-equality-table} * @see {@link immutable-js-deep-equal} * @see {@link node-deep-equal} * @see {@link ramda-equals} * @see {@link lodash-is-equal} * @see {@link angular-is-equal} * @see {@link underscore-equal} * @see {@link traverse-deep-equal} * @see {@link react-deep-differ} * @see {@link js-data-equals} * @see {@link jasmine-equals} * @see {@link eq-qfox} * @see {@link sugar-equal} * * @param {Traverse} traverse traversejs (scoped, @FIXME @HACK) * @param {*} a compare to b * @param {*} b compare to a * @param {boolean} [loose] compare loosely * @return {boolean} isEqual: a === b * * @extends eqValue * * @example * * eq(1, 1) //=> true * eq(1, '1') //=> false * eq(1, '1', true) //=> true * eq([1], [1]) //=> true * */ module.exports = traverse => function eq(a, b, loose) { /* istanbul ignore next: dev */ if (ENV_DEBUG) { console.log('\n') } let equal = true let node = b let nodes = [node] const instance = traverse(a) const notEqual = () => { equal = false instance.stop() } /* istanbul ignore next: dev */ if (ENV_DEBUG) { console.log('eq?') } instance.forEach(function(key, y, traverser) { // @NOTE do base comparisons on values that are not actually iteratable // aka, .isRoot if (isNull(key)) { // always-valid state opionion vs always-invalid // so it only returns false when it is !== fosho if (eqValue(node, y, loose) === false) return notEqual() else return } /* istanbul ignore next: dev */ if (ENV_DEBUG) { console.log('eq: iterating:') } // could use it as a fallback if undefined && y !== undefined // const xyz = get(b, traverser.path.join('.'), b) let x = node // isNotLeafAndIsObj if (isObjNotNull(node) && !isEmpty(node)) { /* istanbul ignore next: dev */ if (ENV_DEBUG) { console.log('is leaf, is not empty node, going deeper') } // so x is our current one, // if node is not empty, use the key, push the value // and when it is empty, and it is not a leaf but has nodes, pop back up x = node[key] nodes.push(x) } // ENV_DEBUG // console.log({[key]: {x, xyz, y, nodes, path: traverser.path.join('.')}}) // for next loop!!! if (!traverser.isLeaf && !isEmpty(nodes)) { /* istanbul ignore next: dev */ if (ENV_DEBUG) { console.log('is not leaf, has nodes stack, pop') } node = nodes.pop() } /* istanbul ignore next: dev */ if (ENV_DEBUG) { console.log({key, y, x, a, b}) } const eqv = eqValue(x, y, loose) /* istanbul ignore next: dev */ if (ENV_DEBUG) { console.log({eqv}) } if (eqv === false) { // equal notEqual() } }) // cleanup nodes = undefined node = undefined return equal }