Skip to main content
niceeval/expect provides only pure Match factories. A Match compares one candidate value; it does not record a result or decide a Verdict or score. t.check(value, match) reads value when called and registers an Assertion directly; the returned handle only configures that same entry.

How to use it

Numeric units

Calculate with ordinary numbers, then wrap the result with ms, seconds, tokens, usd, ratio, count, or bytes. Each constructor returns a frozen Quantity<U> with .value and .unit. Quantities do not support arithmetic or automatic conversion. Constructors require finite numbers. ratio(n) also requires 0 ≤ n ≤ 1; invalid values throw RangeError.
measured accepts number | null or Quantity<U> | null. quantile accepts ordinary numbers or quantities sharing one unit, and preserves that unit. Mixing units or mixing numbers with quantities throws TypeError. Empty samples and missing observations remain unavailable. atLeast, atMost, greaterThan, and lessThan require thresholds with the observation’s unit. between(minimum, maximum) uses inclusive bounds with one unit, ordered from lower to upper. Unitless observations require ordinary numeric thresholds. TypeScript rejects incompatible units. When JavaScript bypasses the types, the check becomes unavailable and reports the mismatch. show and view format units as 512 ms, 61.2%, and $0.031.

Matchers

The signature and description for every matcher below are generated from the niceeval/expect source and stay in sync with the current implementation.

and

Requires every Boolean Match to hold for the same candidate. All operands must belong to the same domain.

or

Accepts a candidate when any Boolean Match holds. All operands must belong to the same domain, and unknown evidence is not a definite mismatch.

not

Negates a Boolean Match within its domain. Unavailable evidence remains unavailable rather than becoming a successful negation.

includes

Checks that text contains a substring. Comment stripping is opt-in, and an empty expected string is rejected.

excludes

Checks that text does not contain a substring. Comment stripping is opt-in, and an empty expected string is rejected.

pattern

Checks text against a regular expression. Each evaluation starts with a fresh cursor and leaves the supplied expression unchanged.

similarity

Normalized Levenshtein similarity; it is a continuous score and carries no default threshold or Verdict policy.

includesUrl

A plain-text matcher that requires at least min distinct http(s) URLs.

hasSections

A plain-text matcher that requires at least min Markdown headings.

isDefined

isTrue

A refinement matcher for value === true.

isFalse

A refinement matcher for value === false.

commandSucceeded

An exitCode === 0 matcher for CommandResult-like candidates; it does not read stdout / stderr.

equals

Checks deep value equality against the supplied reference. It compares structure rather than object identity.

matches

Validates a value using Standard Schema v1. Refinement preserves the original candidate and ignores schema transforms.

satisfies

Wraps a named synchronous or asynchronous Boolean predicate as a value Match. The callback must return a Boolean and remain deterministic and free of side effects.

defineValueMatch

Defines a reusable Boolean value comparison with optional refinement. Report unknown evidence explicitly as unavailable rather than returning false.

defineScoreMatch

Defines a reusable finite [0,1] measurement, optionally using managed LLM primitives. Apply thresholds through the assertion handle, not inside Match configuration.

eventMatch

Matches a supported message or operation event. Use event-specific filters; tool filters belong on operation events.

mapValue

Project a single value without replacing the original subject’s refinement.

mapEach

Project each complete item, retaining its material identity and order.

filterWhere

Select only definite matches; an unknown selector makes the aggregate unavailable.

countWhere

Compare an exact match count only after every item in a complete collection is known.

defineMaterialMatch

Defines a synchronous context collection reader and item selector. Preserve collection completeness and unique item IDs instead of silently discarding unknown items.

defineContextMatch

Defines a synchronous readonly context reader and a Match for one fact. Return an unavailable fact explicitly when evidence cannot be read.

Match tool calls

ToolMatch compares one LogicalToolOccurrence, and expresses the occurrence count with methods such as .exactly(n) and .atLeast(n). calledTool accepts a name, an unquantified ToolMatch, or a positive occurrence Match; notCalledTool uses an unquantified selector to express zero matches.
Use jsonMatch for ordinary JSON, referencesAnyPath for paths, and commandMatch for command tokens. When output is absent, material is incomplete, or HITL has not finished, the Match becomes unavailable; it does not pretend to be an ordinary mismatch. referencesAnyPath searches literal path components and directory prefixes, with case-sensitive matching by default. It does not support glob patterns or interpret command semantics. Use secrets, rather than secrets/**, for that directory. For example, rg --files -g '!secrets/**' still mentions secrets and matches even though it excludes the directory. A match does not prove that a file was read or changed. Use commandMatch for command arguments and file-change assertions for changes. For complete signatures, material states, and three-valued counting rules, see Scoped assertions.

Common usage examples

Composition and three states

Matches within the same and / or must belong to the same domain. The internal result of a Boolean Match is matched, mismatched, or unavailable. or returns unavailable only when no child matches and at least one child’s evidence is incomplete; it does not treat unknown as negative. A Match itself holds no Verdict, scoring, or control flow; .gate(minimum), .score(n), and .orStop(minimum) for a continuous measurement all belong to the registered AssertionHandle. The following lists stable fields on Match values themselves. Brands and evaluators are module-private implementation details, not author API.

Match

domain

name

BooleanMatch

kind

[matchRefinementBrand]

ScoreMatch

kind

Ordering conditions in a collection

inOrder combines 2–64 ordinary value Matches into a collection Match, which you pass to t.check or to an application’s collection assertion method. It accepts a read-only array or a MaterialCollection with a completeness state, and looks for a strictly increasing subsequence by original position; the items need not be adjacent.
The same item cannot satisfy two steps, and each step can use and to constrain the same fact. The application is responsible for providing the formal commit order; a request being sent does not mean the operation was adopted or finished executing. When you only need both parties to have spoken, check existence separately. An incomplete collection returns undecidable. A complete collection passes when there is known ordering evidence, fails when no ordering is possible, and is undecidable when it can only hold by depending on unknown items. Diagnostics keep the original positions, material IDs, and step judgments. Ordering combinations of ToolMatch and EventMatch keep their own Agent scope and cannot be mixed with ordinary value steps.

Custom matchers

Use defineValueMatch for a custom Boolean Match and defineScoreMatch for a continuous score. Both implement only a single-candidate comparison; reading files, scanning events, deciding coverage, and changing a Verdict remain the responsibility of Assertion registration entry points and the Runner.