Standard 03 · Test discipline

Test System

Two parallel test surfaces per module. Pure-logic unit tests for contracts. Browser smoke for live behavior. Forbidden-state absence asserted explicitly. Deterministic, dependency-free, reproducible.

Two pipelines

Why every module has two test surfaces

They verify different things and coexist on purpose.

Pipeline A

Pure-logic unit tests

<module>/tests/<module>.test.ts
Discipline
  • Synchronous, dependency-free
  • No Date.now / no Math.random
  • Run-anywhere: node --experimental-strip-types --test
  • One file, no Vitest, no Jest
Pipeline B

Vite + Playwright release-gate

<module>/handover/tests/
Discipline
  • npm run verify:all end-to-end
  • Captures screenshots; verifies inventory
  • Playwright specs against the TSX
  • Required-PNG list contracted in verify-screenshots.mjs
Discipline

What every test must satisfy

Deterministic. Same inputs → same results, every run.
No clock. No Date.now; freeze time at fixture level if required.
No randomness. Fixed inputs, fixed expectations.
No network. No fetch, no live API; backend errors are stubbed.
Pure logic. Every helper is referentially transparent.
Run-anywhere. Node built-ins only, no Vitest/Jest in pure-logic suite.
Required coverage

Every test suite asserts these classes

§ A

Closed-set asset / state coverage

  • Asset list cardinality + membership
  • Wrapping / unwrapping bijection
  • Disjointness (wrapped ≠ external as input)
§ B

Validation discipline

  • Insufficient balance is DEFINE-stage only
  • Forbidden post-submit causes asserted absent
  • Validation states disjoint from terminal failures
§ C

Display-rounding invariant

  • toFixed output never reused as executable
  • Quick-fill output is raw numeric, no currency symbols
  • Round-trip validate(handlePercent(...)) = VALID
§ D

Forbidden-token absence

  • Source-scan TSX + preview
  • Reject percent-controls in Deposit
  • Reject user-facing tx-hash in Withdraw
Commands

Daily commands

# Pure-logic test (per module, from module root)
node --experimental-strip-types --test tests/<module>.test.ts

# Single test by name pattern
node --experimental-strip-types --test \
  --test-name-pattern '§9.1' tests/<module>.test.ts

# Browser smoke
node tests/smoke-*.mjs

# Capture preview screenshots
node tests/capture-*.mjs

# Vite-based release-gate
cd <module>/handover/tests
npm run verify:all