clone

an offline map explorer where each world, from a game map to a city's open data, ships as one .atlas file

feat/atlas-next-horizon
atlas / docs / testing.md
testing.md 4.9K rendered
1# Testing23One rule above the others: **a gate that did not judge may not say PASS.**4Every required test's inputs are committed to this repository or built by5the run itself. No required test skips, reads an `ATLAS_*` variable, or6looks in the home directory. CI enforces the first half of that7structurally: Go tests run through `tools/testgate`, which fails the run if8any test skipped, whatever the exit code said.910History, where it is needed, is a pointer rather than a chapter: the11pre-rewrite tree and its capture programs are archived on the12`golden-reference` tag (mirrored at `archive/golden-reference`), and the13behavioral differences accepted against it are14[decision 18](decisions/0018-divergences-from-the-reference.md).1516## The layers1718**`make test`** is the whole required surface, and what CI runs on19ubuntu, macOS and Windows (spelled step by step in20`.github/workflows/ci.yml`, because the Windows runner has no make):2122- `go vet ./...`, then `go run ./tools/testgate ./...` — every Go test in23 the module, skip-proof, with `-race` on the platform where a C toolchain24 is free.25- `npm run lane` and `npm run seam-lane` — each TypeScript lane's boundary26 rules, `tsc --strict`, and its own suite.27- `go run ./tools/depcheck` — the import matrix, hostenv purity, network28 confinement, semconv discipline.2930**`make test-e2e`** is the application in a real browser. The run builds31every one of its own prerequisites: the seam (`make static`), a registry32packed from the committed corpus (`tests/e2e/prep`), and the server33Playwright starts itself. The specs assert arrangement — URLs, the state34island, the topbar's controls, session memory — never pixels.3536**`make corpus-smoke`** is the maintainer's deep check and deliberately not37a CI gate: it walks a real installed library (`-bundles`, else38`$ATLAS_BUNDLES_DIR`, else the application's data directory) and holds39every current-format bundle to the reader's invariants. It compares no40stamps, no hashes and no content.4142**`make release-packaging`** is the hermetic half of native distribution43acceptance. It parses the macOS property list and Linux shared-MIME XML, checks44the Windows installer association, and holds the workflow to draft-first,45exact-asset publication. The platform jobs perform the dynamic half: Windows46installs its package and reads the registered open command, Linux installs its47`.deb` and checks MIME registration, and macOS unpacks and verifies its app48seal and UTI. All three packaged executables must intake the exact same freshly49built Sample Region `.atlas` into isolated libraries. The release job also50inspects payloads and builds Sample Region online and offline through the51packaged CLI. Byte inequality is a release failure.5253## What tests are made of5455**Stated bundles.** The default. A test that needs a bundle writes one56through `format/bundle`'s real writer from a few lines of Go (see57`format/bundle/fixture_test.go`, `internal/workbench/bundles_test.go`) —58nothing opaque is committed, and a bundle a test measures is a bundle the59application could open.6061**The corpus** (`testdata/corpus/`). Real extractions, kept because their62provenance is public: bend-or is city open data, mars is NASA Trek. They63give the format, render, island and e2e suites real bytes with real depth —64multipart zones, described shapes, a sphere with two lenses — at the price65of about 14 MB. Public provenance is the bar for adding anything here; see66its README.6768**Hand-derived vectors** (`analysis/testdata/cells/`). The cell-system69contract, written down rather than recorded, and read by both70implementations of the arithmetic: the TypeScript lane's conformance suite71and the Go twin's (`tests/cells`). Until the planned unification deletes72one copy, these vectors are what keep the two from drifting.7374**Property tests** for what no single example can pin down: containment,75hierarchy, carry and plan-order invariants over invented locations in the76analysis lane; determinism in the pipeline (build twice, byte-identical);77fuzzing where bytes cross a trust boundary (`format/bundle`'s reader).7879## Where tests live8081Tests live with their package. Two trees exist because some tests cannot:8283- `tests/` — Go tests that need `os` against packages that may not84 (`hostenv` forbids `internal/app` the filesystem): `tests/island` drives85 the application's routes over the corpus, `tests/cells` reads the shared86 vectors, `tests/e2e` is the browser suite, `tests/corpus` the shared87 packer.88- `tools/` — the enforcement commands: `depcheck`, `testgate`,89 `corpussmoke`.9091## The bar for a new test9293Ask one question: what breaks if this test is deleted? A test that anchors94a number nobody can recompute, reads a path only one machine has, or skips95when the world is not to its liking does not clear it. State the bundle,96derive the expectation by hand, and if the inputs cannot be committed, the97check belongs behind `make corpus-smoke` — named as a maintainer's check,98not dressed as a gate.