niceeval/expect module provides a small set of composable matchers that you pass to t.check() and t.require(). Each matcher is a function that returns an Assertion — a typed scoring function of shape (value: unknown) => number | Promise<number> — and carries a default severity (gate or soft) that determines how a failure affects the eval outcome. You can override the severity on any matcher by chaining .gate() or .atLeast(0.7).
How matchers are used
You pass matchers as the second argument tot.check() or t.require():
check and require:
| Method | On failure | Use for |
|---|---|---|
t.check | Records result, execution continues | Most assertions |
t.require | Throws immediately, aborts the test | Preconditions where continuing is meaningless |
Matchers
includes
value (coerced to a string) contains substring, or that it
matches pattern if a RegExp is provided. Case-sensitive by default when
passing a string.
Default severity: gate
.atLeast(0.7) if you want this to score rather than hard-fail:
equals
value and expected. Works on
primitives, plain objects, arrays, and nested structures. Equivalent to a
recursive JSON.stringify-style comparison (order-insensitive for object keys,
order-sensitive for arrays).
Default severity: gate
matches
value against a Standard Schema
compatible schema. Zod, Valibot, ArkType, and other Standard Schema-compliant
libraries work out of the box.
Default severity: gate
1 if validation passes, 0 if it fails. When the schema
produces a parse error, the error message is attached to the recorded assertion
for easy debugging.
similarity
value (coerced to a string) against expected using normalized
Levenshtein distance, returning a score between 0 (completely different)
and 1 (identical). Useful when you want to reward approximate correctness
rather than enforce an exact match.
Default severity: soft
.gate() if a minimum similarity must be met for the eval to pass:
opts fields:
Minimum score (0–1) required to pass. Defaults to the threshold set by
chaining
.atLeast(n) on the returned assertion; if neither is specified the
assertion always records the raw score as a soft metric.satisfies
value satisfies an arbitrary predicate function. The optional label
string appears in reports and logs to make the assertion’s intent readable.
Default severity: gate
value without type coercion — cast as needed
inside the function. Return true for pass, false for fail.
Chaining severity
Every matcher returns anAssertion object that exposes .gate() and .atLeast(0.7)
methods, letting you override the default severity inline:
| Severity | Failure effect | Strict mode (--strict) |
|---|---|---|
gate | Eval is failed | Same |
soft | Eval is passed (not failed) | Eval is failed |
gate for correctness requirements and soft for quality metrics you want
to track but not block on by default.
The Assertion type
AnAssertion is a scoring function with attached metadata:
[0, 1]:
1— fully passing0— fully failing- Values between 0 and 1 — partial credit (primarily used by
similarityand judge assertions)
gate assertions, any score below 1 is treated as a failure. For soft
assertions, scores are recorded and compared against the configured threshold
(set via .atLeast(n)).
Custom matchers with makeAssertion
When the built-in matchers don’t cover your use case, create a custom assertion withmakeAssertion. Your scoring function receives the raw value and must
return a number (synchronously or as a Promise).
A short identifier shown in reports and logs when this assertion fails.
Use a descriptive name that makes the failure reason self-evident.
The default severity for this assertion. Can be overridden by callers via
.gate() and .atLeast(0.7) chaining, just like built-in matchers.The scoring function. Receives the raw value and must return a number in
[0, 1]. Async scoring functions (e.g. calling an external API) are fully
supported.Async custom matchers
Custom matchers supportasync scoring natively. The runner awaits all
assertions before computing the final outcome.
Quick reference
| Matcher | Default severity | Score type | Best for |
|---|---|---|---|
includes(str | RegExp) | gate | binary (0 or 1) | Keyword / pattern presence |
equals(expected) | gate | binary (0 or 1) | Exact value or structural match |
matches(schema) | gate | binary (0 or 1) | Schema / type validation |
similarity(expected) | soft | continuous (0–1) | Near-match text, approximate answers |
satisfies(predicate, label?) | gate | binary (0 or 1) | Arbitrary logic |
makeAssertion({ name, severity, score }) | configurable | continuous (0–1) | Any custom requirement |