Files
skills/docs/testkit/testing/ab-testing/src/targeting/targeting.md
2026-05-29 08:20:56 +01:00

3.6 KiB

targeting.ts — Targeting Rule Evaluation

(no submodules)

Purpose

Provides the evaluateTargeting function that evaluates an ordered list of targeting rules against a set of user attributes. The function implements AND semantics — every rule in the list must pass for the user to be considered eligible for the experiment. This single-function module is intentionally small and pure: it has no side effects, no I/O, no external dependencies, and is trivially unit-testable.

Targeting rules are the primary mechanism for gating experiment exposure to specific user segments. Common use cases include restricting to paid users, specific geographic regions, device types, or beta-program membership.

Features

  • Eight comparison operators: eq, neq, in, notIn, gt, lt, gte, lte
  • Numeric ordering operators (gt, lt, gte, lte) require both sides to be numbers; any type mismatch returns false rather than throwing
  • in / notIn accept any array on the right-hand side
  • An empty rules array always returns true (no restriction)
  • Absent attributes evaluate to undefined and fail equality/ordering tests gracefully without exceptions

Usage: Basic Example

import { evaluateTargeting } from '@suaveplan/ab-testing/targeting';

const eligible = evaluateTargeting(
  [{ attribute: 'plan', operator: 'eq', value: 'premium' }],
  { plan: 'premium', country: 'US' }
);
console.log(eligible); // true

Usage: Advanced Example

import { evaluateTargeting } from '@suaveplan/ab-testing/targeting';

// Multi-rule targeting: premium users in North America with high session count
const rules = [
  { attribute: 'plan',         operator: 'eq' as const,    value: 'premium' },
  { attribute: 'country',      operator: 'in' as const,    value: ['US', 'CA', 'MX'] },
  { attribute: 'sessionCount', operator: 'gte' as const,   value: 10 },
  { attribute: 'blocklisted',  operator: 'neq' as const,   value: true },
];

const user1 = { plan: 'premium', country: 'CA', sessionCount: 15, blocklisted: false };
const user2 = { plan: 'free',    country: 'US', sessionCount: 30, blocklisted: false };

console.log(evaluateTargeting(rules, user1)); // true  (all 4 rules pass)
console.log(evaluateTargeting(rules, user2)); // false (plan !== 'premium')

API Reference

evaluateTargeting(rules, attributes): boolean

  • rules — ReadonlyArray<TargetingRule> — ordered list of predicates
  • attributes — UserAttributes (Record<string, string | number | boolean>)
  • Returns — boolean — true iff every rule is satisfied (or rules is empty)

Supported operators

Operator Description RHS type
eq Strict equality (===) any
neq Strict inequality (!==) any
in LHS is contained in RHS array unknown[]
notIn LHS is not contained in RHS array unknown[]
gt LHS > RHS number
lt LHS < RHS number
gte LHS >= RHS number
lte LHS <= RHS number

Implementation Notes

All comparisons are intentionally strict (=== / !==) to avoid surprising truthy/falsy coercions. When the RHS is not of the expected type for ordering operators (e.g. a string is passed as the threshold for gt), the function returns false rather than throwing, making it safe to evaluate partially invalid rule sets without crashing the assignment pipeline.

The in / notIn operators use Array.isArray to check the RHS type before calling Array.prototype.includes. When the RHS is not an array, the rule evaluates to false.