Something went wrong

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

ops - Lona Docs Log in

ops <fixture-path>|- [flags]

Run an ops fixture end-to-end. A fixture is a JSON document matching OpsFixtureInput — it lives on disk, or is piped in as - on stdin. Most fixture tests can be authored as pure JSON and run through this command without any TS boilerplate.

# Run a fixture, assert expectations, verify the invariant per-op.
deno run --allow-read --unstable-sloppy-imports \
  tento/tento-lona-js/cli/rows-fixtures/src/lona-rows.deno.ts ops \
  tento/tento-lona-js/sheets/tests/formula/basic-propagation.ops.json \
  --verify --assert-expected

# Pipe in from stdin (path is `-`). The `input` path inside the
# fixture is resolved relative to the current working directory.
cat my-fixture.ops.json | \
  deno run --allow-read --unstable-sloppy-imports \
  tento/tento-lona-js/cli/rows-fixtures/src/lona-rows.deno.ts ops -

Flags

FlagPurpose
--stepPause between ops on an stdin gate (interactive debugging)
--verifyAfter every op, assert the incremental TableView + TreeView match a fresh canonical rebuild. Exits non-zero with a diff on drift.
--jsonEmit one machine-readable JSON record per op (instead of the human-readable block). Good for snapshot testing.
--assert-expectedAfter all ops run, validate fixture.expected.cells. Prints ✓ on pass; exits non-zero with ✗ <detail> lines on any mismatch.

Per-op output

Human-readable (default):

── op 1/3 ─ setCell Weight ymd-2026-4-18 = 200 ─
  [event] ColumnDataChanged  Weight  ymd-2026-4-18
  [event] ColumnDataChanged  Weight Plus 10  ymd-2026-4-18
═══ Formula Simple (seeded) ═══
<TableView-rendered grid>

JSON (--json):

{"op":1,"kind":"setCell","row":"Weight","date":"ymd-2026-4-18","value":200,"events":[...],"snapshot":{...}}

Authoring an ops fixture

See Ops Fixtures for the full schema. Minimal example:

{
  "input": "tento/tento-lona-js/sheets/tests.shared/sheets/empty.sheet.json",
  "ops": [
    { "kind": "addRow", "type": "number", "label": "Weight" },
    { "kind": "setCell", "row": "Weight", "date": "ymd-2026-4-18", "value": 200 }
  ],
  "expected": {
    "cells": [
      { "row": "Weight", "date": "ymd-2026-4-18", "value": 200 }
    ]
  }
}

Drop a .ops.json under tento/tento-lona-js/sheets/tests/...; the test harness picks it up as a regression test AND the CLI runs it unchanged.

Scripted demos

The formula-propagation + alias-lifecycle scenarios that used to live behind demo formula / demo alias are now declarative ops fixtures under tento/tento-lona-js/sheets/tests/demo/:

# Formula: addRow Weight → set cells → addRow Weight Plus 10 →
# observe cascade.
deno run --allow-read --unstable-sloppy-imports \
  tento/tento-lona-js/cli/rows-fixtures/src/lona-rows.deno.ts ops \
  tento/tento-lona-js/sheets/tests/demo/formula-from-empty.ops.json \
  --verify --assert-expected

# Alias: addRow AliasRow → setProp → detach → reset.
deno run --allow-read --unstable-sloppy-imports \
  tento/tento-lona-js/cli/rows-fixtures/src/lona-rows.deno.ts ops \
  tento/tento-lona-js/sheets/tests/demo/alias-lifecycle.ops.json \
  --verify --assert-expected

Writing a new demo is now pure JSON — no TS code.

See also

  • Ops Fixtures — the authoring schema
  • Snapshot Testing — using --json for byte-stable test fixtures
  • watch — for ad-hoc exploration when you don't want to write an ops file