Something went wrong

Thank you for being patient! We're working hard on resolving the issue

Snapshot Testing - Lona Docs Log in

Snapshot Testing

ops --json emits one machine-readable JSON record per op. Pair with a .snap.json checked into the test tree to catch behavior drift without writing TS test code.

Workflow

  1. Author an ops fixture that exercises the scenario.
  2. Run with --json and capture output:
deno run --allow-read --unstable-sloppy-imports \
  tento/tento-lona-js/cli/rows-fixtures/src/lona-rows.deno.ts ops \
  my-scenario.ops.json --json > my-scenario.snap.json
  1. Inspect the snapshot. If correct, commit it.
  2. Add a Deno test that re-runs the fixture and diffs against the snapshot.

Snapshot record shape

Each line in --json mode is one op record:

{
  "op": 1,
  "kind": "setCell",
  "row": "Weight",
  "date": "ymd-2026-4-18",
  "value": 200,
  "events": [
    { "class": "ColumnDataChanged", "row": "Weight", "date": "ymd-2026-4-18" },
    { "class": "ColumnDataChanged", "row": "Weight Plus 10", "date": "ymd-2026-4-18" }
  ],
  "snapshot": {
    "cells": [
      { "row": "Weight", "date": "ymd-2026-4-18", "value": 200 },
      { "row": "Weight Plus 10", "date": "ymd-2026-4-18", "value": 210 }
    ]
  }
}

events lists every invalidation event fired during the op (in order). snapshot is the post-op cell state for every source + formula row in the sheet.

Diffing against a snapshot

Use any line-based diff tool — git diff --no-index, delta, or jq for structural comparison:

deno run --allow-read --unstable-sloppy-imports \
  tento/tento-lona-js/cli/rows-fixtures/src/lona-rows.deno.ts ops my-scenario.ops.json --json | \
  diff -u my-scenario.snap.json -

Drift fails CI; updating is cp .../actual.json .../expected.snap.json after manual review.

What snapshots catch

  • Cell value drift — a number-formatting change, a default swap, an off-by-one in formula evaluation.
  • Event order changes — invalidation cascade reorders.
  • New / missing events — a previously-unfired event now fires (or vice versa).
  • Hidden state changes — a row's snapshot suddenly grows / shrinks rows because of an alias-hydration regression.

What snapshots miss

  • Behavior under different RawSheet inputs — pair multiple .ops.json × .snap.json per scenario for coverage.
  • Async timing — the CLI runs ops synchronously and snapshots are deterministic. Real-world async cascades need TS tests.
  • DOM-side rendering — for that, use CLI/DOM parity coverage such as tento/tento-lona-js/sheets-ui/src/sheet/plugin-keys-derived.deno.test.ts and the scene/diff work tracked in __design_docs/cli/work-tracker.md.

Test integration

Wire a snapshot fixture into a Deno test:

import { assertEquals } from "jsr:@std/assert";

Deno.test("formula propagation snapshot", async () => {
  const proc = new Deno.Command("deno", {
    args: ["run", "--allow-read", "--unstable-sloppy-imports",
           "tento/tento-lona-js/cli/rows-fixtures/src/lona-rows.deno.ts", "ops",
           "tests/formula/basic.ops.json", "--json"],
    stdout: "piped",
  });
  const { stdout } = await proc.output();
  const actual = new TextDecoder().decode(stdout);
  const expected = await Deno.readTextFile("tests/formula/basic.snap.json");
  assertEquals(actual.trim(), expected.trim());
});

See also

  • ops--json and --assert-expected flags
  • Ops Fixtures — fixture authoring