| 'use strict'; |
|
|
| Object.defineProperty(exports, '__esModule', { |
| value: true |
| }); |
| exports.equals = void 0; |
| exports.isA = isA; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| const equals = (a, b, customTesters, strictCheck) => { |
| customTesters = customTesters || []; |
| return eq(a, b, [], [], customTesters, strictCheck); |
| }; |
| exports.equals = equals; |
| function isAsymmetric(obj) { |
| return !!obj && isA('Function', obj.asymmetricMatch); |
| } |
| function asymmetricMatch(a, b) { |
| const asymmetricA = isAsymmetric(a); |
| const asymmetricB = isAsymmetric(b); |
| if (asymmetricA && asymmetricB) { |
| return undefined; |
| } |
| if (asymmetricA) { |
| return a.asymmetricMatch(b); |
| } |
| if (asymmetricB) { |
| return b.asymmetricMatch(a); |
| } |
| } |
|
|
| |
| |
| function eq(a, b, aStack, bStack, customTesters, strictCheck) { |
| let result = true; |
| const asymmetricResult = asymmetricMatch(a, b); |
| if (asymmetricResult !== undefined) { |
| return asymmetricResult; |
| } |
| const testerContext = { |
| equals |
| }; |
| for (let i = 0; i < customTesters.length; i++) { |
| const customTesterResult = customTesters[i].call( |
| testerContext, |
| a, |
| b, |
| customTesters |
| ); |
| if (customTesterResult !== undefined) { |
| return customTesterResult; |
| } |
| } |
| if (a instanceof Error && b instanceof Error) { |
| return a.message == b.message; |
| } |
| if (Object.is(a, b)) { |
| return true; |
| } |
| |
| if (a === null || b === null) { |
| return a === b; |
| } |
| const className = Object.prototype.toString.call(a); |
| if (className != Object.prototype.toString.call(b)) { |
| return false; |
| } |
| switch (className) { |
| case '[object Boolean]': |
| case '[object String]': |
| case '[object Number]': |
| if (typeof a !== typeof b) { |
| |
| return false; |
| } else if (typeof a !== 'object' && typeof b !== 'object') { |
| |
| return Object.is(a, b); |
| } else { |
| |
| return Object.is(a.valueOf(), b.valueOf()); |
| } |
| case '[object Date]': |
| |
| |
| |
| return +a == +b; |
| |
| case '[object RegExp]': |
| return a.source === b.source && a.flags === b.flags; |
| } |
| if (typeof a !== 'object' || typeof b !== 'object') { |
| return false; |
| } |
|
|
| |
| if (isDomNode(a) && isDomNode(b)) { |
| return a.isEqualNode(b); |
| } |
|
|
| |
| let length = aStack.length; |
| while (length--) { |
| |
| |
| |
| |
| if (aStack[length] === a) { |
| return bStack[length] === b; |
| } else if (bStack[length] === b) { |
| return false; |
| } |
| } |
| |
| aStack.push(a); |
| bStack.push(b); |
| |
| |
| if (strictCheck && className == '[object Array]' && a.length !== b.length) { |
| return false; |
| } |
|
|
| |
| const aKeys = keys(a, hasKey); |
| let key; |
| const bKeys = keys(b, hasKey); |
| |
| if (!strictCheck) { |
| for (let index = 0; index !== bKeys.length; ++index) { |
| key = bKeys[index]; |
| if ((isAsymmetric(b[key]) || b[key] === undefined) && !hasKey(a, key)) { |
| aKeys.push(key); |
| } |
| } |
| for (let index = 0; index !== aKeys.length; ++index) { |
| key = aKeys[index]; |
| if ((isAsymmetric(a[key]) || a[key] === undefined) && !hasKey(b, key)) { |
| bKeys.push(key); |
| } |
| } |
| } |
|
|
| |
| let size = aKeys.length; |
| if (bKeys.length !== size) { |
| return false; |
| } |
| while (size--) { |
| key = aKeys[size]; |
|
|
| |
| if (strictCheck) |
| result = |
| hasKey(b, key) && |
| eq(a[key], b[key], aStack, bStack, customTesters, strictCheck); |
| else |
| result = |
| (hasKey(b, key) || isAsymmetric(a[key]) || a[key] === undefined) && |
| eq(a[key], b[key], aStack, bStack, customTesters, strictCheck); |
| if (!result) { |
| return false; |
| } |
| } |
| |
| aStack.pop(); |
| bStack.pop(); |
| return result; |
| } |
| function keys(obj, hasKey) { |
| const keys = []; |
| for (const key in obj) { |
| if (hasKey(obj, key)) { |
| keys.push(key); |
| } |
| } |
| return keys.concat( |
| Object.getOwnPropertySymbols(obj).filter( |
| symbol => Object.getOwnPropertyDescriptor(obj, symbol).enumerable |
| ) |
| ); |
| } |
| function hasKey(obj, key) { |
| return Object.prototype.hasOwnProperty.call(obj, key); |
| } |
| function isA(typeName, value) { |
| return Object.prototype.toString.apply(value) === `[object ${typeName}]`; |
| } |
| function isDomNode(obj) { |
| return ( |
| obj !== null && |
| typeof obj === 'object' && |
| typeof obj.nodeType === 'number' && |
| typeof obj.nodeName === 'string' && |
| typeof obj.isEqualNode === 'function' |
| ); |
| } |
|
|