chain-able
Version:
interfaces that describe their intentions.
226 lines (214 loc) • 17.8 kB
JavaScript
/* 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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