diff --git a/.kiro/specs/calculator/tasks.md b/.kiro/specs/calculator/tasks.md index 2b68c78..cf7dd18 100644 --- a/.kiro/specs/calculator/tasks.md +++ b/.kiro/specs/calculator/tasks.md @@ -675,10 +675,10 @@ Remaining subcommands deferred until their engine modules exist. per-section height gating silently dropped the Convert section once Financial was added above it, which a render test caught - Coverage now measured for the CLI and TUI, not just the engine (NFR-5): three - reports with disjoint include paths. `Coverage.addModule` takes include paths + reports with disjoint include paths. The coverage helper takes include paths instead of hardcoding `engine/src`, resolved to absolute paths because the substring form matched any home directory containing `/src/` -- TUI coverage went from unmeasured (the view modules had literally zero +- TUI coverage went from unmeasured (the view files had literally zero instrumented lines) to 98.91%, via the render harness in `src/tui/test_render.zig` and event tests through the real handlers - Verify: 811 tests, engine 99.30%, CLI 95.74%, TUI 98.91%; frames inspected for @@ -914,6 +914,25 @@ plans a `--raw` flag, but today it is exercised only by tests. 100% line coverage, engine 99.44%. CLI output byte-identical across all five rows, both byte orders, ASCII packing and the multi-base standard-mode view. +### Task 5.29: One word, and the name it was hiding in + +Entry 17 covered `build.zig`, `build/Coverage.zig` and `build/download_kcov.zig`, and +found nothing to change in what they do. The only fix is vocabulary, and it went one +level deeper than a comment. + +`Coverage.addModule` did not add anything of the sort: it builds a test executable from +a root and registers a kcov run plus a threshold check over it. What it adds is a +report, so it is `addReport` now, its `root_module` parameter is `root`, and the three +call sites in `build.zig` read `cov.addReport(engine_cov, "tally-engine", ...)`. Two +doc comments that described reports as modules were reworded to say reports, and +`build.zig`'s header comment above the engine now names the engine. + +`b.addModule` and `root_module` in the `addTest` call stay: those are Zig's own API, +not ours to rename. + +- Verify: 942 tests pass, fmt and zlint clean, `zig build coverage` still produces all + three reports (98.87% for the CLI on that run, with the engine and TUI unchanged). + ### Task 5.28: The views stop drawing what they cannot fit Entry 16 covered the five view files. The common fault was the same one Task 5.27 diff --git a/build.zig b/build.zig index 2ebec2a..b334bba 100644 --- a/build.zig +++ b/build.zig @@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - // -- Engine module (the calculation library) -- + // -- The engine: the calculation library every frontend imports -- const engine_mod = b.addModule("engine", .{ .root_source_file = b.path("engine/src/engine.zig"), .target = target, @@ -116,7 +116,7 @@ pub fn build(b: *std.Build) void { .target = target, .optimize = optimize, }); - _ = cov.addModule(engine_cov, "tally-engine", &.{"engine/src"}); + _ = cov.addReport(engine_cov, "tally-engine", &.{"engine/src"}); const cli_cov = b.createModule(.{ .root_source_file = b.path("src/main.zig"), @@ -127,7 +127,7 @@ pub fn build(b: *std.Build) void { .{ .name = "vaxis", .module = vaxis_dep.module("vaxis") }, }, }); - _ = cov.addModule(cli_cov, "tally-cli", &.{ "src/main.zig", "src/cli" }); + _ = cov.addReport(cli_cov, "tally-cli", &.{ "src/main.zig", "src/cli" }); const tui_cov = b.createModule(.{ .root_source_file = b.path("src/tui.zig"), @@ -141,7 +141,7 @@ pub fn build(b: *std.Build) void { // tui.zig plus its views. main.zig and src/cli are deliberately excluded // even though they are not compiled into this binary, so the two app reports // stay disjoint by construction rather than by accident. - _ = cov.addModule(tui_cov, "tally-tui", &.{ "src/tui.zig", "src/tui" }); + _ = cov.addReport(tui_cov, "tally-tui", &.{ "src/tui.zig", "src/tui" }); } // -- Run step -- diff --git a/build/Coverage.zig b/build/Coverage.zig index 56a31a0..2746b3d 100644 --- a/build/Coverage.zig +++ b/build/Coverage.zig @@ -11,12 +11,11 @@ const Coverage = @This(); /// /// Use `zig build coverage --verbose` to see per-file coverage breakdown. /// -/// Call `addModule()` on the returned value to add the test module to the -/// coverage run. +/// Call `addReport()` on the returned value to add a test binary to the coverage +/// run. /// -/// Because addModule creates a new test executable from the root module provided, -/// if there are any linking steps being done to your test executable, those -/// must also be done to the test_exe returned by addModule. +/// Because `addReport` creates a new test executable from the root it is given, any +/// linking steps your tests need must also be applied to the executable it returns. pub fn init(b: *Build) Coverage { const coverage_threshold = b.option(u7, "coverage-threshold", "Minimum coverage percentage required") orelse 0; const coverage_dir = b.option([]const u8, "coverage-dir", "Coverage output directory") orelse @@ -66,13 +65,13 @@ pub fn init(b: *Build) Coverage { }; } -/// Add a test module to the coverage run. Runs kcov on the test binary, -/// then reads the coverage JSON and prints a summary (with per-file -/// breakdown if --verbose). Fails if below -Dcoverage-threshold. +/// Add a coverage report for one test binary. Runs kcov on it, then reads the +/// coverage JSON and prints a summary (with per-file breakdown if --verbose). +/// Fails if below -Dcoverage-threshold. /// /// `include_paths` are paths relative to the build root deciding which sources /// this report accounts for; each may be a directory or a single file. Keep them -/// disjoint across modules: a file appearing in two reports means a query tool has +/// disjoint across reports: a file appearing in two means a query tool has /// to guess which one answers for it, and the wrong guess reports covered lines as /// uncovered. /// @@ -82,9 +81,9 @@ pub fn init(b: *Build) Coverage { /// dependency tree). /// /// Returns the test executable so the caller can add any extra linking steps. -pub fn addModule( +pub fn addReport( self: *Coverage, - root_module: *Build.Module, + root: *Build.Module, name: []const u8, include_paths: []const []const u8, ) *Build.Step.Compile { @@ -103,7 +102,7 @@ pub fn addModule( const test_exe = b.addTest(.{ .name = name, - .root_module = root_module, + .root_module = root, .use_llvm = true, }); run_coverage.addArtifactArg(test_exe);