mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
four layers carry it: the page's envelope, the driver's unwrap, the runner's count check and the verifier's decode. each has a unit test and only a run proves they compose. goes red both ways, decoding an absent value as null and dropping the envelope.
27 lines
1.1 KiB
TypeScript
27 lines
1.1 KiB
TypeScript
import { always, extract, taps } from "@sanderling/spec";
|
|
|
|
// Two extractors that resolve nothing, the shape every route-scoped extractor
|
|
// has on the steps it is off its own screen (folio has nine of them). JSON has
|
|
// no undefined, so these are what the {value} envelope exists for.
|
|
const absent = extract((s) => s.ax.find({ id: "nothing-is-ever-here" })).named("absent");
|
|
const absentText = extract((s) => s.ax.find({ id: "missing" })?.text).named("absentText");
|
|
|
|
const bumps = extract((s) => {
|
|
const el = s.ax.find({ id: "count" });
|
|
return el ? parseInt(el.text, 10) || 0 : 0;
|
|
}).named("bumps");
|
|
|
|
// A reading the page could not take must arrive as undefined, not as null and
|
|
// not as goja's reading of the dump. This property is what a spec sees.
|
|
const undefinedStaysUndefined = always(
|
|
() => absent.current === undefined && absentText.current === undefined,
|
|
);
|
|
|
|
// The run has to actually be doing something, or the property above holds for
|
|
// the wrong reason.
|
|
const counterNeverMoves = always(() => bumps.current === 0);
|
|
|
|
export const properties = { undefinedStaysUndefined, counterNeverMoves };
|
|
|
|
export const actionsRoot = taps;
|