Skip to content

Latest commit

 

History

History
130 lines (97 loc) · 6.39 KB

testing.md

File metadata and controls

130 lines (97 loc) · 6.39 KB

Testing

MIDNAT has three kinds of test: unit and integration suites in TypeScript, Foundry suites in Solidity, and truth suites that read the source tree and hold the shipped prose and the live chain to it. Counts below are stated as test files, which are verifiable from the source tree without running anything. Where a per-test count is quoted it is the number of it( or test( lines in a file, which is a lower bound when a suite generates cases dynamically.

Running the suites

From the root, every package that defines a test script runs:

pnpm run test

The packages that define a test script are services/api (@midnat/api), apps/terminal (@midnat/terminal), apps/web (@midnat/web) and packages/protocol-client (@midnat/protocol-client). protocol-math, db, api-zod, api-spec, desk-chips, openrouter-ai and api-client-react ship no test script; protocol-math is exercised through the suites of the packages that import it.

Per package:

pnpm --filter @midnat/api run test
pnpm --filter @midnat/terminal run test
pnpm --filter @midnat/web run test
pnpm --filter @midnat/protocol-client run test

Foundry, from the root:

pnpm run contracts:test    # forge test

What each suite covers and how large it is

Suite Test files Covers
services/api 54 The price engine, oracle signing, anchor posting, funding and liquidation keepers, the trade indexer, the AI desk and guardrails, the intelligence usage ledger, the routes, and the security-header and error-shape contracts.
apps/terminal 41 The trading interface: rendering of positions and the vault, the pretrade flow, host config, and the chain-parity fixtures the terminal relies on.
apps/web 5 The public site: the reference-feed geometry, the API reads, host routing, and the two truth suites below.
packages/protocol-client 6 The generated ABIs, the clients, the capacity math, the pretrade checks, the trade-detail decoding, and the on-chain live-fire (gated by an env flag).
contracts/test (Foundry) 19 (104 test functions across them) The on-chain protocol: 4626 attacks, decimals, funding conservation, access-control and oracle-authority fuzzing, open-interest and settlement fuzzing, share invariants, solvency invariants, ledger conservation, liquidation, modes and capacity, oracle attacks, the vault redemption gate, the withdraw guard, and the full vertical loop.

The Foundry profile in contracts/foundry.toml runs fuzz at 512 runs and invariants at 192 runs with depth 64.

The truth suites

These read source or live state rather than mocks, and fail when the product and its claims drift apart.

Suite Path What it holds
No-fake-data guard services/api/src/lib/noFakeData.test.ts Scans every shipped economic surface (the engine, vault, portfolio, market and open-interest, fees, funding, liquidation and settlement code, the terminal's financial state, the site, the DB layer, the API spec, the deployed contracts and their scripts, the protocol math, and the chain client) for the patterns that fabricate a financial number. It never scans tests, mocks, fixtures, generated clients or build output, because invented numbers are the point of a fixture. Also exposed as pnpm run guard.
Site truth apps/web/src/site-truth.test.ts Holds the public site's prose to the deployment so the site cannot claim something the live engine does not do.
Route truth apps/web/src/route-truth.test.ts Holds the site's routes and the route-truth.mjs harness to the same fingerprint, so a rename on either side fails the unit suite rather than turning the live check into a silent pass.
Host routing apps/web/src/host-routing.test.ts Pins how the host rewrites paths for the single-page app.

pnpm run guard runs the no-fake-data gate on its own:

pnpm run guard

Live and gated tests

Several tests only run when an environment flag is set, because they touch the live chain. They are off by default (see docs/development/environment.md):

  • services/api/src/lib/liquidation.live.test.ts runs only when MIDNAT_LIVE=1.
  • packages/protocol-client/src/live-fire.chain.test.ts runs only when MIDNAT_LIVE_FIRE=1 and reads a testnet keyfile path.
  • apps/web/src/lib/liquidation-chain-parity.test.ts uses a committed evidence fixture unless MIDNAT_CHAIN_EVIDENCE overrides it with a live run's output.

The verification harnesses in scripts/verify

Two harnesses check MIDNAT against reality rather than against its own documentation. Both read live state and both fail loudly.

chain-truth.sh

Reads the deployed clearing house, vault and collateral token directly with cast and prints one JSON document: block, vault NAV, share supply, cash balances, and every open position with its equity, maintenance margin and liquidation price as the contract computes them. Comparing an integer the contract returned against the number the product printed is the comparison that settles an argument.

scripts/verify/chain-truth.sh                 # to stdout
scripts/verify/chain-truth.sh chain.json      # to a file
RPC=https://your-node scripts/verify/chain-truth.sh

Requires Foundry for cast. No key: every call is a read.

route-truth.mjs

Drives a real browser over the deployed site and reads the rendered identity of every route in apps/web/src/lib/site-map.ts, plus a set of invented paths. The site is a single-page app, so the host rewrites every path to index.html and an HTTP sweep sees 200 OK for a real page and an invented one alike. This harness asserts that each real route renders its own identity, that an invented path renders the not-found page, and that the two differ.

CHROME_PATH=/path/to/chrome node scripts/verify/route-truth.mjs https://midnat.xyz

Requires playwright-core and a Chromium binary. It writes evidence to evidence/route-truth/ and exits non-zero on any failure.

verify-chain.mjs

The full chain reconciliation lives at contracts/scripts/verify-chain.mjs. It compares the runtime code at each address against what this repo compiles (with constructor immutables masked and then checked one by one), reads roles and globals off the chain, re-fetches every manifest transaction, and replays the event log in 100-block windows. Reproduce the deployment record's checks with:

node contracts/scripts/verify-chain.mjs