UNPKG

chain-able

Version:

interfaces that describe their intentions.

226 lines (214 loc) 17.8 kB
/* eslint complexity: "off" */ /* eslint func-style: "off" */ /* eslint no-proto: "off" */ /* eslint consistent-return: "off" */ /* eslint eqeqeq: "off" */ var traverse = require('../traverse') var ObjectKeys = require('../util/keys') var hasOwnProperty = require('../util/hasOwnProperty') var isNullOrUndefined = require('../is/nullOrUndefined') var isTrue = require('../is/true') var isRegExp = require('../is/regexp') var isDate = require('../is/date') var isObjStrict = require('../is/objStrict') var isObjLoose = require('../is/objLoose') var isEqEq = require('../is/eqeq') var toS = require('../is/toS') var ENV_DEBUG = require('../env/debug') // const isFunction = require('../is/function') // const isString = require('../is/string') // const isNumber = require('../is/number') // const isBoolean = require('../is/boolean') // const isPrimitive = x => isString(x) || isBoolean(x) || isNumber(x) // const isArguments = x => toS(x) === '[object Arguments]' // const sameKeysLength = (x, y) => Object.keys(x).length === Object.keys(y).length /* prettier-ignore */ /** * @desc deep traversal of nodes to compare any data types * does not check reference, only value equality * * @since 3.0.0 * @symb ⚖️ * @memberOf traverse * @types traverse * @tests traverse/equals * * @param {any} a compare a with b * @param {any} b compare b with a * @param {boolean} [loose=false] whether to do looser equals check * @return {boolean} isEqual * * @see traverse * * @example * * eq(1, 1) * //=> true * * eq(true, false) * //=> false * * eq({}, {}) * //=> true * * @example * * eq( * {d: new Date(0, 0, 0, 0), x: [1, 2, 3]}, * {d: new Date(0, 0, 0, 0), x: [1, 2, 3]} * ) * //=> true * * eq([new RegExp('x')], [/x/]) * //=> true * * eq([new String('x')], ['x']) * //=> true * * eq([new Boolean(false)], [false]) * //=> true * * eq([undefined], [null]) || eq(undefined, null) * //=> false * * @example * * var xs = [1, 2, 3, 4] * delete xs[2] * * var ys = Object.create(Array.prototype) * ys[0] = 1 * ys[1] = 2 * ys[3] = 4 * * eq(xs, ys) * //=> true * * eq(xs, [1, 2, undefined, 4]) * //=> false * */ module.exports = function(a, b, loose) { var equal = true var node = b traverse(a).forEach(function(y) { var notEqual = function() { equal = false // this.stop(); // return undefined; } // if (node === undefined || node === null) return notEqual(); if (!this.isRoot) { // if (!Object.hasOwnProperty.call(node, this.key)) return notEqual() if (!isObjLoose(node)) { return notEqual() } node = node[this.key] } var x = node this.post(function() { node = x }) // @@debugger /* istanbul ignore next: dev */ if (ENV_DEBUG) { console.log('types: ', {x: toS(x), y: toS(y)}) } if (this.circular) { /* istanbul ignore next: dev */ if (ENV_DEBUG) { console.log('circular', this) } if (traverse(b).get(this.circular.path) !== x) { notEqual() } } else if (isNullOrUndefined(x) || isNullOrUndefined(y)) { if (x !== y) { notEqual() } } else if (typeof x !== typeof y) { /* istanbul ignore next: dev */ if (ENV_DEBUG) { console.log('diff types', typeof x, typeof y) } if (isTrue(loose) && isEqEq(x, y)) { // ignore } else { notEqual() } } else if (x.__proto__ !== y.__proto__) { notEqual() } else if (x === y) { // nop } // @NOTE: .toString will be covered for functions and regexes in objStrict // else if (isRegExp(x)) { // // both regexps on account of the __proto__ check // if (x.toString() != y.toString()) { // notEqual() // } // } // else if (isFunction(x)) { // if (x !== y) { // notEqual() // } // } else if (isObjStrict(x)) { // @NOTE: this is never called // if (toS(y) === '[object Arguments]' || toS(x) === '[object Arguments]') { // if (toS(x) !== toS(y)) { // notEqual() // } // } if (isRegExp(x) || isRegExp(y)) { if (!x || !y || x.toString() !== y.toString()) { notEqual() } } else if (isDate(x) || isDate(y)) { if ( !(isDate(x)) || !(isDate(y)) || x.getTime() !== y.getTime() ) { notEqual() } } else { // @NOTE: it will traverse through values if they are == here var xKeys = ObjectKeys(x) var yKeys = ObjectKeys(y).length if (xKeys.length !== yKeys) { return notEqual() } for (var k = 0; k < xKeys.length; k++) { if (!hasOwnProperty(y, xKeys[k])) { notEqual() } } } } // isString(x) || isBoolean(x) || isNumber(x) || isIterator(x) else if (toS(x) === toS(y) && x !== y) { /* istanbul ignore next: dev */ if (ENV_DEBUG) { console.log('same str types - diff values', {s: toS(x), x: x, y: y}) } notEqual() } else if (toS(x) !== toS(y)) { /* istanbul ignore next: dev */ if (ENV_DEBUG) { console.log('diff str types', {x: toS(x), y: toS(y)}) } notEqual() } }) return equal } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXEuanMiLCJzb3VyY2VzIjpbImVxLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludCBjb21wbGV4aXR5OiBcIm9mZlwiICovXG4vKiBlc2xpbnQgZnVuYy1zdHlsZTogXCJvZmZcIiAqL1xuLyogZXNsaW50IG5vLXByb3RvOiBcIm9mZlwiICovXG4vKiBlc2xpbnQgY29uc2lzdGVudC1yZXR1cm46IFwib2ZmXCIgKi9cbi8qIGVzbGludCBlcWVxZXE6IFwib2ZmXCIgKi9cblxuY29uc3QgdHJhdmVyc2UgPSByZXF1aXJlKCcuLi90cmF2ZXJzZScpXG5jb25zdCBPYmplY3RLZXlzID0gcmVxdWlyZSgnLi4vdXRpbC9rZXlzJylcbmNvbnN0IGhhc093blByb3BlcnR5ID0gcmVxdWlyZSgnLi4vdXRpbC9oYXNPd25Qcm9wZXJ0eScpXG5jb25zdCBpc051bGxPclVuZGVmaW5lZCA9IHJlcXVpcmUoJy4uL2lzL251bGxPclVuZGVmaW5lZCcpXG5jb25zdCBpc1RydWUgPSByZXF1aXJlKCcuLi9pcy90cnVlJylcbmNvbnN0IGlzUmVnRXhwID0gcmVxdWlyZSgnLi4vaXMvcmVnZXhwJylcbmNvbnN0IGlzRGF0ZSA9IHJlcXVpcmUoJy4uL2lzL2RhdGUnKVxuY29uc3QgaXNPYmpTdHJpY3QgPSByZXF1aXJlKCcuLi9pcy9vYmpTdHJpY3QnKVxuY29uc3QgaXNPYmpMb29zZSA9IHJlcXVpcmUoJy4uL2lzL29iakxvb3NlJylcbmNvbnN0IGlzRXFFcSA9IHJlcXVpcmUoJy4uL2lzL2VxZXEnKVxuY29uc3QgdG9TID0gcmVxdWlyZSgnLi4vaXMvdG9TJylcbmNvbnN0IEVOVl9ERUJVRyA9IHJlcXVpcmUoJy4uL2Vudi9kZWJ1ZycpXG5cbi8vIGNvbnN0IGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuLi9pcy9mdW5jdGlvbicpXG4vLyBjb25zdCBpc1N0cmluZyA9IHJlcXVpcmUoJy4uL2lzL3N0cmluZycpXG4vLyBjb25zdCBpc051bWJlciA9IHJlcXVpcmUoJy4uL2lzL251bWJlcicpXG4vLyBjb25zdCBpc0Jvb2xlYW4gPSByZXF1aXJlKCcuLi9pcy9ib29sZWFuJylcbi8vIGNvbnN0IGlzUHJpbWl0aXZlID0geCA9PiBpc1N0cmluZyh4KSB8fCBpc0Jvb2xlYW4oeCkgfHwgaXNOdW1iZXIoeClcbi8vIGNvbnN0IGlzQXJndW1lbnRzID0geCA9PiB0b1MoeCkgPT09ICdbb2JqZWN0IEFyZ3VtZW50c10nXG4vLyBjb25zdCBzYW1lS2V5c0xlbmd0aCA9ICh4LCB5KSA9PiBPYmplY3Qua2V5cyh4KS5sZW5ndGggPT09IE9iamVjdC5rZXlzKHkpLmxlbmd0aFxuXG4vKiBwcmV0dGllci1pZ25vcmUgKi9cbi8qKlxuICogQGRlc2MgZGVlcCB0cmF2ZXJzYWwgb2Ygbm9kZXMgdG8gY29tcGFyZSBhbnkgZGF0YSB0eXBlc1xuICogICAgICAgZG9lcyBub3QgY2hlY2sgcmVmZXJlbmNlLCBvbmx5IHZhbHVlIGVxdWFsaXR5XG4gKlxuICogQHNpbmNlIDMuMC4wXG4gKiBAc3ltYiDimpbvuI9cbiAqIEBtZW1iZXJPZiB0cmF2ZXJzZVxuICogQHR5cGVzIHRyYXZlcnNlXG4gKiBAdGVzdHMgdHJhdmVyc2UvZXF1YWxzXG4gKlxuICogQHBhcmFtICB7YW55fSBhIGNvbXBhcmUgYSB3aXRoIGJcbiAqIEBwYXJhbSAge2FueX0gYiBjb21wYXJlIGIgd2l0aCBhXG4gKiBAcGFyYW0gIHtib29sZWFufSBbbG9vc2U9ZmFsc2VdIHdoZXRoZXIgdG8gZG8gbG9vc2VyIGVxdWFscyBjaGVja1xuICogQHJldHVybiB7Ym9vbGVhbn0gaXNFcXVhbFxuICpcbiAqIEBzZWUgdHJhdmVyc2VcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqICAgIGVxKDEsIDEpXG4gKiAgICAvLz0+IHRydWVcbiAqXG4gKiAgICBlcSh0cnVlLCBmYWxzZSlcbiAqICAgIC8vPT4gZmFsc2VcbiAqXG4gKiAgICBlcSh7fSwge30pXG4gKiAgICAvLz0+IHRydWVcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqICAgIGVxKFxuICogICAgICB7ZDogbmV3IERhdGUoMCwgMCwgMCwgMCksIHg6IFsxLCAyLCAzXX0sXG4gKiAgICAgIHtkOiBuZXcgRGF0ZSgwLCAwLCAwLCAwKSwgeDogWzEsIDIsIDNdfVxuICogICAgKVxuICogICAgLy89PiB0cnVlXG4gKlxuICogICAgZXEoW25ldyBSZWdFeHAoJ3gnKV0sIFsveC9dKVxuICogICAgLy89PiB0cnVlXG4gKlxuICogICAgZXEoW25ldyBTdHJpbmcoJ3gnKV0sIFsneCddKVxuICogICAgLy89PiB0cnVlXG4gKlxuICogICAgZXEoW25ldyBCb29sZWFuKGZhbHNlKV0sIFtmYWxzZV0pXG4gKiAgICAvLz0+IHRydWVcbiAqXG4gKiAgICBlcShbdW5kZWZpbmVkXSwgW251bGxdKSB8fCBlcSh1bmRlZmluZWQsIG51bGwpXG4gKiAgICAvLz0+IGZhbHNlXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAgICAgdmFyIHhzID0gWzEsIDIsIDMsIDRdXG4gKiAgICAgZGVsZXRlIHhzWzJdXG4gKlxuICogICAgIHZhciB5cyA9IE9iamVjdC5jcmVhdGUoQXJyYXkucHJvdG90eXBlKVxuICogICAgIHlzWzBdID0gMVxuICogICAgIHlzWzFdID0gMlxuICogICAgIHlzWzNdID0gNFxuICpcbiAqICAgICBlcSh4cywgeXMpXG4gKiAgICAgLy89PiB0cnVlXG4gKlxuICogICAgIGVxKHhzLCBbMSwgMiwgdW5kZWZpbmVkLCA0XSlcbiAqICAgICAvLz0+IGZhbHNlXG4gKlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGEsIGIsIGxvb3NlKSB7XG4gIGxldCBlcXVhbCA9IHRydWVcbiAgbGV0IG5vZGUgPSBiXG5cbiAgdHJhdmVyc2UoYSkuZm9yRWFjaChmdW5jdGlvbih5KSB7XG4gICAgY29uc3Qgbm90RXF1YWwgPSBmdW5jdGlvbigpIHtcbiAgICAgIGVxdWFsID0gZmFsc2VcbiAgICAgIC8vIHRoaXMuc3RvcCgpO1xuICAgICAgLy8gcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvLyBpZiAobm9kZSA9PT0gdW5kZWZpbmVkIHx8IG5vZGUgPT09IG51bGwpIHJldHVybiBub3RFcXVhbCgpO1xuICAgIGlmICghdGhpcy5pc1Jvb3QpIHtcbiAgICAgIC8vIGlmICghT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobm9kZSwgdGhpcy5rZXkpKSByZXR1cm4gbm90RXF1YWwoKVxuICAgICAgaWYgKCFpc09iakxvb3NlKG5vZGUpKSB7XG4gICAgICAgIHJldHVybiBub3RFcXVhbCgpXG4gICAgICB9XG4gICAgICBub2RlID0gbm9kZVt0aGlzLmtleV1cbiAgICB9XG5cbiAgICBsZXQgeCA9IG5vZGVcblxuICAgIHRoaXMucG9zdChmdW5jdGlvbigpIHtcbiAgICAgIG5vZGUgPSB4XG4gICAgfSlcblxuICAgIC8vIEBAZGVidWdnZXJcblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBkZXYgKi9cbiAgICBpZiAoRU5WX0RFQlVHKSB7XG4gICAgICBjb25zb2xlLmxvZygndHlwZXM6ICcsIHt4OiB0b1MoeCksIHk6IHRvUyh5KX0pXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY2lyY3VsYXIpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBkZXYgKi9cbiAgICAgIGlmIChFTlZfREVCVUcpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ2NpcmN1bGFyJywgdGhpcylcbiAgICAgIH1cbiAgICAgIGlmICh0cmF2ZXJzZShiKS5nZXQodGhpcy5jaXJjdWxhci5wYXRoKSAhPT0geCkge1xuICAgICAgICBub3RFcXVhbCgpXG4gICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKGlzTnVsbE9yVW5kZWZpbmVkKHgpIHx8IGlzTnVsbE9yVW5kZWZpbmVkKHkpKSB7XG4gICAgICBpZiAoeCAhPT0geSkge1xuICAgICAgICBub3RFcXVhbCgpXG4gICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiB4ICE9PSB0eXBlb2YgeSkge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGRldiAqL1xuICAgICAgaWYgKEVOVl9ERUJVRykge1xuICAgICAgICBjb25zb2xlLmxvZygnZGlmZiB0eXBlcycsIHR5cGVvZiB4LCB0eXBlb2YgeSlcbiAgICAgIH1cbiAgICAgIGlmIChpc1RydWUobG9vc2UpICYmIGlzRXFFcSh4LCB5KSkge1xuICAgICAgICAvLyBpZ25vcmVcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBub3RFcXVhbCgpXG4gICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKHguX19wcm90b19fICE9PSB5Ll9fcHJvdG9fXykge1xuICAgICAgbm90RXF1YWwoKVxuICAgIH1cbiAgICBlbHNlIGlmICh4ID09PSB5KSB7XG4gICAgICAvLyBub3BcbiAgICB9XG4gICAgLy8gQE5PVEU6IC50b1N0cmluZyB3aWxsIGJlIGNvdmVyZWQgZm9yIGZ1bmN0aW9ucyBhbmQgcmVnZXhlcyBpbiBvYmpTdHJpY3RcbiAgICAvLyBlbHNlIGlmIChpc1JlZ0V4cCh4KSkge1xuICAgIC8vICAgLy8gYm90aCByZWdleHBzIG9uIGFjY291bnQgb2YgdGhlIF9fcHJvdG9fXyBjaGVja1xuICAgIC8vICAgaWYgKHgudG9TdHJpbmcoKSAhPSB5LnRvU3RyaW5nKCkpIHtcbiAgICAvLyAgICAgbm90RXF1YWwoKVxuICAgIC8vICAgfVxuICAgIC8vIH1cbiAgICAvLyBlbHNlIGlmIChpc0Z1bmN0aW9uKHgpKSB7XG4gICAgLy8gICBpZiAoeCAhPT0geSkge1xuICAgIC8vICAgICBub3RFcXVhbCgpXG4gICAgLy8gICB9XG4gICAgLy8gfVxuICAgIGVsc2UgaWYgKGlzT2JqU3RyaWN0KHgpKSB7XG4gICAgICAvLyBATk9URTogdGhpcyBpcyBuZXZlciBjYWxsZWRcbiAgICAgIC8vIGlmICh0b1MoeSkgPT09ICdbb2JqZWN0IEFyZ3VtZW50c10nIHx8IHRvUyh4KSA9PT0gJ1tvYmplY3QgQXJndW1lbnRzXScpIHtcbiAgICAgIC8vICAgaWYgKHRvUyh4KSAhPT0gdG9TKHkpKSB7XG4gICAgICAvLyAgICAgbm90RXF1YWwoKVxuICAgICAgLy8gICB9XG4gICAgICAvLyB9XG4gICAgICBpZiAoaXNSZWdFeHAoeCkgfHwgaXNSZWdFeHAoeSkpIHtcbiAgICAgICAgaWYgKCF4IHx8ICF5IHx8IHgudG9TdHJpbmcoKSAhPT0geS50b1N0cmluZygpKSB7XG4gICAgICAgICAgbm90RXF1YWwoKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChpc0RhdGUoeCkgfHwgaXNEYXRlKHkpKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhKGlzRGF0ZSh4KSkgfHxcbiAgICAgICAgICAhKGlzRGF0ZSh5KSkgfHxcbiAgICAgICAgICB4LmdldFRpbWUoKSAhPT0geS5nZXRUaW1lKClcbiAgICAgICAgKSB7XG4gICAgICAgICAgbm90RXF1YWwoKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy8gQE5PVEU6IGl0IHdpbGwgdHJhdmVyc2UgdGhyb3VnaCB2YWx1ZXMgaWYgdGhleSBhcmUgPT0gaGVyZVxuICAgICAgICBjb25zdCB4S2V5cyA9IE9iamVjdEtleXMoeClcbiAgICAgICAgY29uc3QgeUtleXMgPSBPYmplY3RLZXlzKHkpLmxlbmd0aFxuICAgICAgICBpZiAoeEtleXMubGVuZ3RoICE9PSB5S2V5cykge1xuICAgICAgICAgIHJldHVybiBub3RFcXVhbCgpXG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCB4S2V5cy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgIGlmICghaGFzT3duUHJvcGVydHkoeSwgeEtleXNba10pKSB7XG4gICAgICAgICAgICBub3RFcXVhbCgpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIC8vIGlzU3RyaW5nKHgpIHx8IGlzQm9vbGVhbih4KSB8fCBpc051bWJlcih4KSB8fCBpc0l0ZXJhdG9yKHgpXG4gICAgZWxzZSBpZiAodG9TKHgpID09PSB0b1MoeSkgJiYgeCAhPT0geSkge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGRldiAqL1xuICAgICAgaWYgKEVOVl9ERUJVRykge1xuICAgICAgICBjb25zb2xlLmxvZygnc2FtZSBzdHIgdHlwZXMgLSBkaWZmIHZhbHVlcycsIHtzOiB0b1MoeCksIHgsIHl9KVxuICAgICAgfVxuICAgICAgbm90RXF1YWwoKVxuICAgIH1cbiAgICBlbHNlIGlmICh0b1MoeCkgIT09IHRvUyh5KSkge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGRldiAqL1xuICAgICAgaWYgKEVOVl9ERUJVRykge1xuICAgICAgICBjb25zb2xlLmxvZygnZGlmZiBzdHIgdHlwZXMnLCB7eDogdG9TKHgpLCB5OiB0b1MoeSl9KVxuICAgICAgfVxuICAgICAgbm90RXF1YWwoKVxuICAgIH1cbiAgfSlcblxuICByZXR1cm4gZXF1YWxcbn1cbiJdLCJuYW1lcyI6WyJjb25zdCIsImxldCJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztBQU1BQSxHQUFLLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUM7QUFDdkNBLEdBQUssQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQztBQUMxQ0EsR0FBSyxDQUFDLGNBQWMsR0FBRyxPQUFPLENBQUMsd0JBQXdCLENBQUM7QUFDeERBLEdBQUssQ0FBQyxpQkFBaUIsR0FBRyxPQUFPLENBQUMsdUJBQXVCLENBQUM7QUFDMURBLEdBQUssQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQztBQUNwQ0EsR0FBSyxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDO0FBQ3hDQSxHQUFLLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUM7QUFDcENBLEdBQUssQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDO0FBQzlDQSxHQUFLLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztBQUM1Q0EsR0FB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