All files / src/conditions evaluateCondition.ts

85.71% Statements 18/21
84% Branches 21/25
100% Functions 4/4
85% Lines 17/20

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      1x         76x   76x 58x     18x       18x 1x       1x 1x           17x 1x     16x         364x 289x     75x 2x     74x    
import type { FieldValue, FormValues, VisibilityCondition, VisibilityRule } from "../schema/types";
 
function hasValue(value: FieldValue): boolean {
  return value !== undefined && value !== null && value !== "";
}
 
/** Evaluate one intentionally small, non-executable visibility condition. */
function evaluateSingleCondition(condition: VisibilityCondition, values: FormValues): boolean {
  const actualValue = values[condition.field];
 
  if (condition.equals !== undefined && actualValue !== condition.equals) {
    return false;
  }
 
  Iif (condition.notEquals !== undefined && actualValue === condition.notEquals) {
    return false;
  }
 
  if (condition.includes !== undefined) {
    Iif (Array.isArray(actualValue)) {
      return actualValue.includes(condition.includes);
    }
 
    Eif (typeof actualValue === "string") {
      return actualValue.includes(String(condition.includes));
    }
 
    return false;
  }
 
  if (condition.exists !== undefined) {
    return condition.exists ? hasValue(actualValue) : !hasValue(actualValue);
  }
 
  return true;
}
 
/** Evaluate a missing rule, a single condition, or a simple AND array. */
export function evaluateCondition(rule: VisibilityRule | undefined, values: FormValues): boolean {
  if (!rule) {
    return true;
  }
 
  if (Array.isArray(rule)) {
    return rule.every((condition) => evaluateSingleCondition(condition, values));
  }
 
  return evaluateSingleCondition(rule, values);
}