64b6755254d1
wire refAllDecls(@This()) into main.zig so zig build test discovers test blocks in errors.zig, config.zig, exec.zig, commands.zig, and types.zig; fix leaked TranslatedError string fields in errors.zig tests and leaked config/machine-name allocations in config.zig tests that this surfaced
- time
- 2026-07-02 13:32 UTC · 3 months ago
- machine
- koh2
- agent
- claude-sonnet-5
- session
- wire refAllDecls into zig build test
- parent
- b3f422a2f4b6
↓ nina-64b67552.tar.gzatlas at this save
files changed3 files
src/config.zig+5 −0src/errors.zig+8 −3src/main.zig+12 −1src/config.zig+5 −0
@@ -207,6 +207,8 @@207207 ;208208 const config = try parse(std.testing.allocator, input, "/home/test");209209 defer std.testing.allocator.free(config.machines);210+ defer std.testing.allocator.free(config.editor);211+ defer std.testing.allocator.free(config.machines[0].name);210212 211213 try std.testing.expectEqualStrings("hx", config.editor);212214 try std.testing.expectEqual(@as(u32, 3), config.generations);@@ -229,6 +231,7 @@229231 ;230232 const config = try parse(std.testing.allocator, input, "/home/test");231233 defer std.testing.allocator.free(config.machines);234+ defer std.testing.allocator.free(config.machines[0].name);232235 233236 try std.testing.expect(config.confirm);234237 try std.testing.expect(!config.teach);@@ -246,6 +249,7 @@246249 ;247250 const cfg_with = try parse(std.testing.allocator, with, "/home/test");248251 defer std.testing.allocator.free(cfg_with.machines);252+ defer std.testing.allocator.free(cfg_with.machines[0].name);249253 try std.testing.expect(cfg_with.flake);250254 251255 const without =@@ -254,6 +258,7 @@254258 ;255259 const cfg_without = try parse(std.testing.allocator, without, "/home/test");256260 defer std.testing.allocator.free(cfg_without.machines);261+ defer std.testing.allocator.free(cfg_without.machines[0].name);257262 try std.testing.expect(!cfg_without.flake);258263 }259264 src/errors.zig+8 −3
@@ -162,7 +162,7 @@162162 fn findLocationInLine(allocator: std.mem.Allocator, line: []const u8) ?[]const u8 {163163 const nix_pos = std.mem.indexOf(u8, line, ".nix:") orelse return null;164164 const before = line[0 .. nix_pos + 4]; // includes ".nix"165- const rest = line[nix_pos + 5..]; // "47:3" or "47"165+ const rest = line[nix_pos + 5 ..]; // "47:3" or "47"166166 const colon_or_end = std.mem.indexOf(u8, rest, ":") orelse rest.len;167167 const line_num_str = rest[0..colon_or_end];168168 if (line_num_str.len == 0 or line_num_str.len > 6) return null;@@ -653,6 +653,9 @@653653 test "layer 1: undefined variable" {654654 const t = matchKnownPattern(std.testing.allocator, "error: undefined variable 'pkgs.notexist'");655655 try std.testing.expect(t != null);656+ defer std.testing.allocator.free(t.?.title);657+ defer std.testing.allocator.free(t.?.body);658+ defer std.testing.allocator.free(t.?.suggestion);656659 try std.testing.expect(std.mem.indexOf(u8, t.?.title, "notexist") != null);657660 }658661 @@ -666,6 +669,7 @@666669 test "layer 1: unfree" {667670 const t = matchKnownPattern(std.testing.allocator, "error: Package 'discord' has an unfree license");668671 try std.testing.expect(t != null);672+ defer std.testing.allocator.free(t.?.body);669673 try std.testing.expectEqualStrings("package has an unfree license", t.?.title);670674 }671675 @@ -675,10 +679,11 @@675679 }676680 677681 test "layer 1: service activation failure" {678- const t = matchKnownPattern(std.testing.allocator,679- "warning: the following units failed: rtorrent.service\n" ++682+ const t = matchKnownPattern(std.testing.allocator, "warning: the following units failed: rtorrent.service\n" ++680683 "Command 'systemd-run ...' returned non-zero exit status 4.");681684 try std.testing.expect(t != null);685+ defer std.testing.allocator.free(t.?.body);686+ defer std.testing.allocator.free(t.?.suggestion);682687 try std.testing.expectEqualStrings("service failed after upgrade", t.?.title);683688 try std.testing.expect(std.mem.indexOf(u8, t.?.body, "rtorrent.service") != null);684689 try std.testing.expect(std.mem.indexOf(u8, t.?.suggestion, "rtorrent.service") != null);src/main.zig+12 −1
@@ -252,7 +252,10 @@252252 if (std.mem.eql(u8, cmd, "home")) return commands.home(ctx);253253 if (std.mem.eql(u8, cmd, "goodbye")) return commands.goodbye(ctx);254254 if (std.mem.eql(u8, cmd, "hello")) return commands.hello(ctx);255- if (std.mem.eql(u8, cmd, "help")) { output.help(); return; }255+ if (std.mem.eql(u8, cmd, "help")) {256+ output.help();257+ return;258+ }256259 257260 errors.error_info.setMessage("unknown command: {s}", .{cmd});258261 errors.error_info.setSuggestion("nina help", .{});@@ -345,6 +348,14 @@345348 if (std.mem.eql(u8, cmd, m)) return true;346349 }347350 return false;351+}352+353+// Zig 0.16's test runner only discovers `test` blocks in files it can see are354+// reachable from the root; refAllDecls forces every decl main.zig imports355+// (transitively) to be referenced, which is what pulls in test blocks living356+// in exec.zig, commands.zig, errors.zig, config.zig, etc.357+test {358+ std.testing.refAllDecls(@This());348359 }349360 350361 test "parse args basic" {