Skip to content

fix(tests): recursively collect nested zspec tests (#14) - #16

Merged
apotema merged 1 commit into
mainfrom
fix/14-recursive-test-discovery
Jun 19, 2026
Merged

apotema merged 1 commit into
mainfrom
fix/14-recursive-test-discovery

Conversation

@apotema

@apotema apotema commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Closes #14. One-level refAllDecls meant doubly-nested zspec tests (FooSpec → group → test) were never compiled or run under Zig 0.16 — zig build test ran only the root #13 test and passed even when broken. Added refAllDeclsRecursive; surfaced + fixed 0.16-stale library code it masked (a_star PriorityQueue → unmanaged initContext/push/pop/deinit(allocator); z_index_buckets + a floyd test ArrayListUnmanaged → .empty). 1 → 91 tests run, all green; force-failing a nested test now fails the build (verified). v0.7.2 → 0.7.3.

…w run (#14)

tests/root.zig used std.testing.refAllDecls, which is one level deep: it
referenced the imported test files but NOT the doubly-nested
`pub const FooSpec = struct { pub const group = struct { test ... } }` zspec
groups. Under Zig 0.16 a test block is only collected once its container is
analyzed, so every nested spec test was silently never compiled OR run —
`zig build test` reported only the single root-level #13 regression test and
passed even with failing assertions.

Add a local refAllDeclsRecursive (Zig 0.16 dropped the std one) so every
nested group is analyzed and its tests collected. This surfaced that the dead
tests were masking 0.16-stale code in the library itself:
  * src/a_star.zig — PriorityQueue moved to the unmanaged API
    (init->initContext, add->push(allocator), removeOrNull->pop, deinit(allocator))
  * src/z_index_buckets.zig — ArrayListUnmanaged init {} -> .empty
  * tests/floyd_warshall_optimized_test.zig — same ArrayListUnmanaged init

Result: 1 -> 91 tests run, all green; force-failing any nested test now fails
`zig build test`. version 0.7.2 -> 0.7.3.
@cursor

cursor Bot commented Jun 19, 2026 •

Copy link
Copy Markdown

PR Summary

Medium Risk
Test harness change materially increases what runs in CI; A* PriorityQueue and ArrayListUnmanaged init updates are mechanical but touch core pathfinding and storage code.

Overview
Fixes silent test skipping under Zig 0.16 by replacing one-level std.testing.refAllDecls in tests/root.zig with a local refAllDeclsRecursive, so doubly-nested zspec groups (*Spec → group → test) are analyzed and included in zig build test (closes #14).

Once those tests actually ran, the PR updates Zig 0.16 std API usage: A*’s open set uses PriorityQueue’s unmanaged initContext / push / pop / deinit(allocator); ArrayListUnmanaged initialization uses .empty in z_index_buckets and Floyd–Warshall optimized tests. Package version 0.7.2 → 0.7.3.

Reviewed by Cursor Bugbot for commit b627ac3. Bugbot is set up for automated code reviews on this repo. Configure here.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the codebase for compatibility with Zig 0.16.0. Key changes include updating std.PriorityQueue API usage in src/a_star.zig, adopting .empty initializers for Bucket and ArrayListUnmanaged, and introducing a custom refAllDeclsRecursive helper in tests/root.zig to ensure nested tests are run. Feedback on the changes suggests checking decl.is_pub within refAllDeclsRecursive to avoid attempting to inspect private declarations, which can lead to compile-time errors or increased compilation times.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread tests/root.zig
Comment on lines +26 to +35
inline for (comptime std.meta.declarations(T)) |decl| {
const field = @field(T, decl.name);
if (@TypeOf(field) == type) {
switch (@typeInfo(field)) {
.@"struct", .@"enum", .@"union", .@"opaque" => refAllDeclsRecursive(field),
else => {},
}
}
_ = &@field(T, decl.name);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Checking decl.is_pub is highly recommended here. Without this check, refAllDeclsRecursive will attempt to inspect private declarations (such as private imports like const std = @import("std"); or other helper constants/functions). This can lead to compile-time errors (since private declarations of other files/structs cannot be accessed from outside) or cause the compiler to recursively traverse the entire standard library, significantly increasing compile times or hitting recursion limits.

    inline for (comptime std.meta.declarations(T)) |decl| {
        if (!decl.is_pub) continue;
        const field = @field(T, decl.name);
        if (@TypeOf(field) == type) {
            switch (@typeInfo(field)) {
                .@"struct", .@"enum", .@"union", .@"opaque" => refAllDeclsRecursive(field),
                else => {},
            }
        }
        _ = &@field(T, decl.name);
    }

@apotema

apotema commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

This suggestion is based on an older Zig — in 0.16 std.builtin.Type.Declaration has only a name field (no is_pub), and std.meta.declarations returns info.decls which is already public-only. So decl.is_pub wouldn't compile, and the private-import / std-recursion concern can't happen: private decls (e.g. const std = @import("std")) aren't in declarations() at all. That's why this compiles fast and runs all 91 tests without traversing std. Leaving as-is.

@apotema
apotema merged commit f4e104b into main Jun 19, 2026
1 of 2 checks passed
@apotema
apotema deleted the fix/14-recursive-test-discovery branch June 19, 2026 12:19
@cursor

cursor Bot commented Jun 19, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_f7606078-da3c-49cb-93f7-ca613dd28211)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

zspec nested *Spec tests don't execute under zig build test (Zig 0.16) — tests silently pass

1 participant