Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Testing

A failing test should say which behavior or contract broke. The rules are in CONTRIBUTING.md. Two file-driven sweeps carry most of the evidence: a specimen joins the format sweep by being readable, and a capture joins the replay sweep by existing.

nord-format

cargo test -p nord-format runs the unit tests, a dispatch test that synthesizes a file for every registered tag and round-trips it through both container generations, the Stage body tests, and the specimen sweep over tests/fixtures: files this crate’s own writers produced, with sidecars recording what was set. The sweep fails unless that tree holds a file of every type the reader dispatches. Each specimen is parsed, round-tripped byte for byte, checked for unnameable values, and has every registry field set and read back without moving another. A piano library or sample instrument, alone or in a bundle, must also index to the bytes a whole read gives each stroke or zone, reading none of the audio to find them. A sample’s outline must answer as a whole read does, and an edit saved as a patch must write the bytes a whole edit writes. An edited piano library streamed from its file must write the bytes the whole library writes, reading one stroke at a time.

With --features corpus, NORD_CORPUS_ROOT names a corpus: any tree of Nord files. The sweep runs over every file in it the reader recognizes, wherever it sits. Claims about every file of a kind, such as a Stage 4 selector staying in panel range or a piano library rebuilding byte for byte, run once per file of that kind, so a tree without that kind runs none of them. Claims about one file live in the <file>.oracle.json beside it: decoded values, the project a sample was rendered from, the file another was edited from. A tree without sidecars still gets the round trips and the per-kind claims. A bit-ownership test flips every claimed body bit in the fixtures and one file of each container shape, and requires that it change only the field that claims it, or be refused. nix build .#nord.nord-format-corpus runs the suite over the private corpus, whose sidecars say the most.

nord-usb

cargo test -p nord-usb --features replay

The replay tests drive the whole stack from recorded captures and check that the bytes the crate emits are the bytes Nord Sound Manager sent. replay is not a default feature. Without it, cargo test -p nord-usb verifies none of the wire encoding. The Nix build enables it.

tests/replay runs one trial per script under tests/scripts, and under the corpus with --features corpus. Every script is checked for framing, and one that declares an intent is driven through an exact-match transport and judged against what it said to expect. One that declares none must name the tests that drive it, or say why nothing does.

# source: nord
# device: Nord Electro 5, firmware v2.04 build 592
# intent: program info 7:11
O 0000001200000006000000010000000006a1

A read that timed out, a write the device did not accept, and a transport failure are steps of their own, so a read the script does not expect fails the replay instead of passing as silence. nord … --record <path> writes a complete script. The step forms, the header keys, the expect values and the intent table are documented in crates/nord-usb/tests/scripts/README.md.

drawbar on an instrument

cargo test -p drawbar runs headless: the device worker talks to a scripted instrument, and no test needs hardware. A separate suite in crates/drawbar/src/device/hardware.rs drives drawbar’s own send paths against an attached instrument: a library over a temporary folder, the browser’s acts, the queue, and the device worker over USB. It sends piano libraries and sample instruments from the files they rest in, replaces an occupied slot, changes a file on disk while it is being sent, and checks that memory stays bounded by the transfer chunk.

The tests write to the instrument, so they are ignored and do nothing unless DRAWBAR_HARDWARE=1. Close drawbar and Nord Sound Manager first, so the interface is free, and run them one at a time:

DRAWBAR_HARDWARE=1 cargo test -p drawbar --lib device::hardware -- --ignored --test-threads=1 --nocapture

nord-cli reads the source objects, reads back what drawbar wrote, and deletes it again; DRAWBAR_HARDWARE_NORD names its binary when it is not nord on the path. The sources are slots on the instrument: DRAWBAR_HARDWARE_PIANO and DRAWBAR_HARDWARE_OTHER_PIANO, two piano libraries of a few megabytes, and DRAWBAR_HARDWARE_SAMPLE, a sample instrument of more than a megabyte. Each test writes only to the last vacant slots of bank 1 and deletes only names it gave, and the last test checks that every class holds what it held when the run started.

Everything at once

nix flake check and nix build .#nord.all run what CI runs. See Building from source.

nix build .#nord.all-corpus runs every suite against the pinned private corpus, and .#nord.<crate>-corpus runs one crate’s. .#nord.all-corpus-full uses the corpus’s R2 tier and needs a seeded store or R2 credentials. .#nord.corpus and .#nord.corpus-full are the corpus trees themselves.