The validation corpus for @voxgig/apidef:
real API definitions, the model apidef is expected to generate from each of
them, and a harness that runs a pinned apidef revision over every definition
and diffs its output against those golden files. When apidef changes, this is
where the change shows up as a diff a human can read.
| Path | What it holds |
|---|---|
def/ |
the API definitions: OpenAPI 2 and 3 documents in JSON and YAML, and GraphQL schemas as SDL and as introspection JSON |
v1/guide/ |
the golden guides, one base guide and one final guide per definition, plus the *-guide.aontu source each case starts from |
v1/model/<case>/ |
the golden entity models, one file per entity |
v1/test/main.test.ts |
the case list and the TypeScript harness |
v1/go/validate_test.go |
the Go harness, with the same case list minus the GraphQL cases |
src/main.ts |
the sandbox both TypeScript suites share: a union filesystem that keeps generated output in memory, and the line differ |
A case is named after its definition file, so petstore-1.0.7-swagger-2.0
is def/petstore-1.0.7-swagger-2.0.json, its guides are
v1/guide/petstore-1.0.7-swagger-2.0-*.aontu, and its entity models sit
under v1/model/petstore-1.0.7-swagger-2.0/.
Install Node.js 24 or later and Git. Build the root package first, then the harness:
npm ci && npm run build
cd v1
npm ci && npm run build
npm testThe apidef version is pinned exactly in v1/package.json, and npm ci
installs the published package from the registry. That is the point: this
harness checks the artifact a consumer installs, so what that package contains
and the dependency ranges it declares are both part of what is under test. A
harness that built apidef from source could see neither a packaging fault nor a
peer range admitting a broken dependency, and for a time this one could not.
npm access is needed; no sibling checkout and no GitHub access are.
The suite runs every case twice: guide-case stops the
apidef pipeline after guide generation and compares the base and final
guides, and model-case runs the whole pipeline and compares the entity
models. A mismatch fails the test with a line diff.
Select cases by name:
TEST_CASE=petstore,solar npm test
npm run test-guide-case
npm run test-model-caseIf the installed apidef predates GraphQL ingestion, the GraphQL cases are skipped and the run says so.
The Go harness runs the Go apidef module over the same definitions, minus the GraphQL cases, which the Go port does not ingest. Install Go 1.25 or later, then run:
cd v1
make testThe module version in v1/go/go.mod pins the Go port, which is released on
its own cadence, so it names an earlier version than v1/package.json after
a release that carried the npm package only. Go downloads it without a local workspace. The
harness diffs the base guide and the entity models the Go module writes, and
the final guide it returns, against the goldens, and a mismatch fails the
test with a line diff. It also checks that fields are maps keyed by n and that
their human titles match their names. The Go module writes no # why
annotations, so the trailing comments of the golden are dropped before the
base guide comparison.
The Go port reproduces every golden of its cases, so guide-case and
model-case compare each one strictly, and the list at the top of
v1/go/validate_test.go is empty. The list is where a known gap goes when
a release leaves the port behind: one entry per gap, holding a path glob,
the reason, and the number of distinct goldens under that glob the port is
expected to miss. A matching golden is still compared and logged, and a
mismatch does not fail the run; the count does. A complete run holds every
entry to its number in both directions, so a golden the port has started to
reproduce fails the run while its siblings still differ, and so does a
golden that starts failing under a glob already listed. The number counts
distinct paths rather than comparisons, because both phases compare the
guides. A complete run also fails an entry whose glob matches no golden at
all, which is what a typo in a glob looks like. A run narrowed by
TEST_CASE, or to one of the two phases, compares part of the corpus only,
so there a rise in a count is what fails.
A skipped mismatch is logged with its reason, the number of differing lines, and the first golden line that differs, so the size and the place of a gap are in the log without the generated files being kept.
The run ends by printing the split: how many distinct goldens it compared strictly, how many the skip list covered, and how many of those the Go run produced no entity for. Each golden is counted once there. The two per-phase totals count a guide golden twice, once per phase, so they are not the figures to add together.
TEST_CASE selects cases here too, TEST_OUT names a directory that keeps
the generated files, and make update-apidef moves the pin to the latest
published module.
Every TypeScript run writes a .gen.aontu twin beside each golden it
compares, so the generated output is always on disk next to what was
expected. The Go check writes nothing into the repository: its output goes
to a temporary directory unless TEST_OUT keeps it. A golden that does not
exist yet is created by the TypeScript run from its output, which is how a
new case pins itself on its first run; the Go check reports it as missing.
A golden line carrying a ## comment marks a known gap: it is dropped
before the comparison and counted as an open TODO.
When apidef changes on purpose, move the version pin in v1/package.json to
the release that carries the change, reinstall so package-lock.json follows,
and run go get github.com/voxgig/apidef/go@v<version> from v1/go. A release
that leaves go/ untouched publishes no module version, and the module pin
then stays where it is. To test a version apidef has not published yet, link a
checkout into v1/node_modules locally and do not commit the result: the
committed pin names a published version, always. Run the suite, read the diff, and
replace the golden with its .gen.aontu twin. A
stale golden does not announce itself, so record why a refresh happened in
the commit message.
This README is the doorway. The tutorial, how-to guides, reference, and explanation for apidef itself are in the apidef documentation, and the prose here follows the style guide.
To reset the snapshots to the current apidef output:
cd v1
npm run test-update
npm testThe reset updates expected and generated guides and entity models. It also
removes stale entity snapshots for the selected cases. Set TEST_CASE to
limit the reset, for example TEST_CASE=solar npm run test-update.