@gramforge/testing
v0.1.0
Published
Reusable vitest helpers for the Gramforge stack. Pure and JSR-publishable — it imports `@gramforge/core` + `@gramforge/render` but **not** vitest, so the helpers throw plain `Error`s and work under any runner (or bare `node`).
Downloads
86
Readme
@gramforge/testing
Reusable vitest helpers for the Gramforge stack. Pure and JSR-publishable — it
imports @gramforge/core + @gramforge/render but not vitest, so the
helpers throw plain Errors and work under any runner (or bare node).
Install
pnpm add -D @gramforge/testingPayload snapshots
Stable, serializable projections of the three renderers for toMatchSnapshot /
toEqual. snapshotEntities re-sorts entities by (offset asc, length desc,
type) so a snapshot reads top-to-bottom and survives internal walk-order
refactors.
import { snapshotEntities, snapshotHtml, snapshotMarkdown } from "@gramforge/testing";
const snap = snapshotEntities(message); // { text, entities } — entities sorted
expect(snap).toMatchSnapshot();
expect(snapshotHtml(message)).toContain("<b>");
snapshotMarkdown(message); // MarkdownV2 fallback stringLength / Unicode fixtures
Telegram meters length in UTF-16 code units (string.length), not code
points. UNICODE_FIXTURES pins the hazards (ASCII, CJK, astral emoji, ZWJ
family, combining marks, regional-flag) with documented utf16Length /
codePointLength, and assertUtf16Length checks a node list's rendered length.
import { UNICODE_FIXTURES, assertUtf16Length, fixtureNodes } from "@gramforge/testing";
for (const fx of UNICODE_FIXTURES) {
assertUtf16Length(fixtureNodes(fx), fx.utf16Length);
}Callback roundtrips
Encode → decode a payload in one call and assert the outcome. Deterministic deps (fixed HMAC secret + fixed clock + in-memory store) make signatures and spillover reproducible.
import {
createCallbackTestDeps,
roundtripCallback,
assertRoundtripOk,
assertSurvivesBothPaths
} from "@gramforge/testing";
const deps = createCallbackTestDeps();
const rt = await roundtripCallback(namespace, "approve", { id: 1 }, deps);
expect(rt.wireFormat).toBe("compact"); // "compact" | "pointer"
assertRoundtripOk(rt, { id: 1 });
// prove BOTH wire formats are lossless (small stays inline, big spills):
await assertSurvivesBothPaths(
namespace,
"approve",
{ compact: { id: 1 }, spillover: { id: 2, note: "x".repeat(200) } },
deps
);Also exported: createFakePointerStore (adds size() / has() inspection),
FIXED_HMAC_SECRET, FIXED_NOW_MS, fixedNow, DEFAULT_CALLBACK_TTL_MS,
callbackWireFormat, describeDecodeResult, toDecodeDeps, and
jsonDeepEqual.
