All files equals.ts

100% Statements 49/49
100% Branches 38/38
100% Functions 2/2
100% Lines 49/49

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 1168x     8x 8x 8x                                                                   8x 92x       92x 31x     61x 42x 42x 42x 42x 42x   42x 10x 10x 1x   9x 15x 4x     5x     32x 2x     30x 30x 30x 1x   29x 3x     26x 26x 26x 1x   25x 3x     22x 22x   22x 3x     19x 28x 4x       15x 24x 24x 4x       11x     19x    
import { purry } from './purry';
 
// from https://github.com/epoberezkin/fast-deep-equal/blob/master/index.js
const isArray = Array.isArray;
const keyList = Object.keys;
const hasProp = Object.prototype.hasOwnProperty;
 
/**
 * Returns true if its arguments are equivalent, false otherwise.
 * @warning Doesn't handle cyclical data structures.
 * @param a the first object to compare
 * @param b the second object to compare
 * @signature
 *    P.equals(a, b)
 * @example
 *    P.equals(1, 1) //=> true
 *    P.equals(1, '1') //=> false
 *    P.equals([1, 2, 3], [1, 2, 3]) //=> true
 * @data_first
 * @category Object
 */
export function equals(a: any, b: any): boolean;
 
/**
 * Returns true if its arguments are equivalent, false otherwise.
 * @warning Doesn't handle cyclical data structures.
 * @param a the first object to compare
 * @param b the second object to compare
 * @signature
 *    P.equals(b)(a)
 * @example
 *    P.equals(1)(1) //=> true
 *    P.equals('1')(1) //=> false
 *    P.equals([1, 2, 3])([1, 2, 3]) //=> true
 * @data_last
 * @category Object
 */
export function equals(a: any): (b: any) => boolean;
 
export function equals() {
  return purry(_equals, arguments);
}
 
function _equals(a: any, b: any) {
  if (a === b) {
    return true;
  }
 
  if (a && b && typeof a === 'object' && typeof b === 'object') {
    const arrA = isArray(a);
    const arrB = isArray(b);
    let i;
    let length;
    let key;
 
    if (arrA && arrB) {
      length = a.length;
      if (length !== b.length) {
        return false;
      }
      for (i = length; i-- !== 0; ) {
        if (!equals(a[i], b[i])) {
          return false;
        }
      }
      return true;
    }
 
    if (arrA !== arrB) {
      return false;
    }
 
    const dateA = a instanceof Date;
    const dateB = b instanceof Date;
    if (dateA !== dateB) {
      return false;
    }
    if (dateA && dateB) {
      return a.getTime() === b.getTime();
    }
 
    const regexpA = a instanceof RegExp;
    const regexpB = b instanceof RegExp;
    if (regexpA !== regexpB) {
      return false;
    }
    if (regexpA && regexpB) {
      return a.toString() === b.toString();
    }
 
    const keys = keyList(a);
    length = keys.length;
 
    if (length !== keyList(b).length) {
      return false;
    }
 
    for (i = length; i-- !== 0; ) {
      if (!hasProp.call(b, keys[i])) {
        return false;
      }
    }
 
    for (i = length; i-- !== 0; ) {
      key = keys[i];
      if (!equals(a[key], b[key])) {
        return false;
      }
    }
 
    return true;
  }
 
  return a !== a && b !== b;
}