All files / src/ast/operator equality.ts

100% Statements 16/16
100% Branches 26/26
100% Functions 1/1
100% Lines 16/16

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                          382x 8x   374x 2x     372x   333x             39x 39x 3x     36x 7x   29x 6x       23x 19x     4x    
/**
 * Spring's `Operator#equalityCheck`.
 *
 * The important property is the absence of coercion between unrelated types: a
 * String is never equal to a Number, and a Boolean is never equal to a Number,
 * because Java compares either numerically or with `equals`, and never both.
 * The previous implementation fell back to comparing `String(left)` with
 * `String(right)`, which made `'1' == 1` and `true == 1` both true.
 */
import { compareNumericValues } from '../../type/numeric.js';
 
export function equalityCheck(left: unknown, right: unknown): boolean {
  // Null is equal only to null.
  if (left === null || left === undefined) {
    return right === null || right === undefined;
  }
  if (right === null || right === undefined) {
    return false;
  }
 
  if (typeof left === 'number' && typeof right === 'number') {
    // `NaN !== NaN` here, as in Java.
    return left === right;
  }
 
  // A BigInt is compared numerically and exactly against another integral value,
  // so `10n == 10` holds and a value beyond float64 precision does not round to
  // its neighbour. Before this it fell through to the typeof check below and was
  // reported as unequal.
  const numeric = compareNumericValues(left, right);
  if (numeric !== undefined) {
    return numeric === 0;
  }
 
  if (typeof left === 'string' && typeof right === 'string') {
    return left === right;
  }
  if (typeof left === 'boolean' && typeof right === 'boolean') {
    return left === right;
  }
 
  // Different families never compare equal, so no coercion is attempted.
  if (typeof left !== typeof right) {
    return false;
  }
 
  return Object.is(left, right);
}