All files / src/utils matchesStringOrRegExp.js

72% Statements 18/25
61.54% Branches 16/26
100% Functions 3/3
72% Lines 18/25

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                        10x 10x                           10x       10x 18x 18x 6x     4x         18x             18x 18x 18x     18x         18x     18x 8x     8x       10x    
/**
 * Compares a string to a second value that, if it fits a certain convention,
 * is converted to a regular expression before the comparison.
 * If it doesn't fit the convention, then two strings are compared.
 *
 * Any strings starting and ending with `/` are interpreted
 * as regular expressions.
 */
export function matchesStringOrRegExp(
  input /*: string | Array<string>*/,
  comparison /*: string | Array<string> */
) /*: false | { match: string, pattern: string }*/ {
  Eif (!Array.isArray(input)) {
    return testAgainstStringOrRegExpOrArray(input, comparison);
  }
 
  for (const inputItem of input) {
    const testResult = testAgainstStringOrRegExpOrArray(inputItem, comparison);
    if (testResult) {
      return testResult;
    }
  }
 
  return false;
}
 
function testAgainstStringOrRegExpOrArray(value, comparison) {
  Iif (!Array.isArray(comparison)) {
    return testAgainstStringOrRegExp(value, comparison);
  }
 
  for (const comparisonItem of comparison) {
    const testResult = testAgainstStringOrRegExp(value, comparisonItem);
    if (testResult) {
      return testResult;
    }
  }
  return false;
}
 
function testAgainstStringOrRegExp(value, comparison) {
  // If it's a RegExp, test directly
  Iif (comparison instanceof RegExp) {
    return comparison.test(value)
      ? { match: value, pattern: comparison }
      : false;
  }
 
  // Check if it's RegExp in a string
  const firstComparisonChar = comparison[0];
  const lastComparisonChar = comparison[comparison.length - 1];
  const secondToLastComparisonChar = comparison[comparison.length - 2];
 
  const comparisonIsRegex =
    firstComparisonChar === "/" &&
    (lastComparisonChar === "/" ||
      (secondToLastComparisonChar === "/" && lastComparisonChar === "i"));
 
  const hasCaseInsensitiveFlag =
    comparisonIsRegex && lastComparisonChar === "i";
 
  // If so, create a new RegExp from it
  if (comparisonIsRegex) {
    const valueMatches = hasCaseInsensitiveFlag
      ? new RegExp(comparison.slice(1, -2), "i").test(value)
      : new RegExp(comparison.slice(1, -1)).test(value);
    return valueMatches ? { match: value, pattern: comparison } : false;
  }
 
  // Otherwise, it's a string. Do a strict comparison
  return value === comparison ? { match: value, pattern: comparison } : false;
}