test: run example corpus in zig build test; sx ir → stdout
`zig build test` now runs the full examples/ + issues/ regression corpus alongside the Zig unit tests, driven by a pure-Zig test (src/corpus_run.test.zig) — no shell script in the build path. It spawns the installed `sx` per example (subprocess-isolated, per-run timeout), diffs stdout/stderr/exit and optional `sx ir` snapshots, and fails the build on any mismatch. The file list is enumerated at runtime, so new examples are covered with no test edit. - `sx ir` / `ir-dump` now write to stdout (fd 1) instead of stderr, so the dumps can be piped/redirected. - `zig build test -Dupdate-goldens` regenerates snapshots in-build, byte-identical to the legacy `run_examples.sh --update`; on mismatch the runner prints how to regenerate. - run_examples.sh kept (still used by tools/verify-step.sh) and made portable to a bare macOS: timeout/gtimeout fallback, bash 3.2-safe empty-array handling. - CLAUDE.md: document the new workflow.
This commit is contained in:
33
build.zig
33
build.zig
@@ -193,28 +193,49 @@ pub fn build(b: *std.Build) void {
|
||||
run_cmd.addArgs(args);
|
||||
}
|
||||
|
||||
// Corpus paths for the LSP corpus-sweep test (src/lsp/corpus_sweep.test.zig).
|
||||
// Inject absolute corpus dirs at configure time so the in-process analyzer
|
||||
// sweep is CWD-independent; the test still ENUMERATES the directory
|
||||
// contents at runtime (new examples are covered with no test edit).
|
||||
// Corpus paths for the corpus tests (src/lsp/corpus_sweep.test.zig — the
|
||||
// in-process analyzer sweep — and src/corpus_run.test.zig — the end-to-end
|
||||
// example/issue runner). Inject absolute corpus dirs + the installed `sx`
|
||||
// binary path at configure time so the tests are CWD-independent; the
|
||||
// runner still ENUMERATES the directory contents at runtime, so new
|
||||
// examples are covered with no test edit.
|
||||
const corpus_opts = b.addOptions();
|
||||
corpus_opts.addOption([]const u8, "examples_dir", b.path("examples").getPath(b));
|
||||
corpus_opts.addOption([]const u8, "issues_dir", b.path("issues").getPath(b));
|
||||
corpus_opts.addOption([]const u8, "library_dir", b.path("library").getPath(b));
|
||||
// Absolute path to the installed `sx` binary the corpus runner spawns per
|
||||
// example. The runner test depends on the install step (below) so this
|
||||
// exists — and so the sibling library/ tree the binary loads is in place.
|
||||
corpus_opts.addOption([]const u8, "sx_exe", b.getInstallPath(.bin, "sx"));
|
||||
// `zig build test -Dupdate-goldens` flips src/corpus_run.test.zig from
|
||||
// verify mode to regenerate mode: it overwrites each example's expected
|
||||
// .exit/.stdout/.stderr (+ .ir where one exists) with freshly-normalized
|
||||
// output instead of asserting against it. The in-build equivalent of the
|
||||
// legacy `run_examples.sh --update`.
|
||||
const update_goldens = b.option(
|
||||
bool,
|
||||
"update-goldens",
|
||||
"Regenerate example/issue snapshots instead of verifying them (use with `zig build test`)",
|
||||
) orelse false;
|
||||
corpus_opts.addOption(bool, "update_goldens", update_goldens);
|
||||
mod.addOptions("corpus_paths", corpus_opts);
|
||||
|
||||
const mod_tests = b.addTest(.{
|
||||
.root_module = mod,
|
||||
});
|
||||
const run_mod_tests = b.addRunArtifact(mod_tests);
|
||||
// src/corpus_run.test.zig spawns the installed `sx` binary per example, so
|
||||
// the mod test binary must not run until `zig-out/bin/sx` + `zig-out/library`
|
||||
// are installed. This is what folds the full example/issue regression suite
|
||||
// into `zig build test` — no shell script, just a Zig test.
|
||||
run_mod_tests.step.dependOn(b.getInstallStep());
|
||||
|
||||
const exe_tests = b.addTest(.{
|
||||
.root_module = exe.root_module,
|
||||
});
|
||||
const run_exe_tests = b.addRunArtifact(exe_tests);
|
||||
|
||||
const test_step = b.step("test", "Run tests");
|
||||
const test_step = b.step("test", "Run unit tests + the example/issue regression suite");
|
||||
test_step.dependOn(&run_mod_tests.step);
|
||||
test_step.dependOn(&run_exe_tests.step);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user