a9c14dfd
Add test-render orchestrator
a73x 2026-04-17 15:55
Commit message
build.zig
| Old | New | ||
|---|---|---|---|
| @@ -353,4 +353,21 @@ pub fn build(b: *std.Build) void { | |||
| 353 | imgdiff_test_mod.addImport("png", png_mod); | 353 | imgdiff_test_mod.addImport("png", png_mod); |
| 354 | const imgdiff_tests = b.addTest(.{ .root_module = imgdiff_test_mod }); | 354 | const imgdiff_tests = b.addTest(.{ .root_module = imgdiff_test_mod }); |
| 355 | test_step.dependOn(&b.addRunArtifact(imgdiff_tests).step); | 355 | test_step.dependOn(&b.addRunArtifact(imgdiff_tests).step); |
| 356 | |||
| 357 | const test_render_mod = b.createModule(.{ | ||
| 358 | .root_source_file = b.path("src/tools/test_render.zig"), | ||
| 359 | .target = target, | ||
| 360 | .optimize = optimize, | ||
| 361 | }); | ||
| 362 | const test_render_exe = b.addExecutable(.{ | ||
| 363 | .name = "test-render", | ||
| 364 | .root_module = test_render_mod, | ||
| 365 | }); | ||
| 366 | b.installArtifact(test_render_exe); | ||
| 367 | |||
| 368 | const test_render_step = b.step("test-render", "Run all golden VT scripts and diff against references"); | ||
| 369 | test_render_step.dependOn(b.getInstallStep()); | ||
| 370 | const test_render_run = b.addRunArtifact(test_render_exe); | ||
| 371 | test_render_run.step.dependOn(b.getInstallStep()); | ||
| 372 | test_render_step.dependOn(&test_render_run.step); | ||
| 356 | } | 373 | } |
src/tools/test_render.zig
| Old | New | ||
|---|---|---|---|
| @@ -0,0 +1,75 @@ | |||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub fn main() !void { | ||
| 4 | var gpa: std.heap.DebugAllocator(.{}) = .init; | ||
| 5 | defer _ = gpa.deinit(); | ||
| 6 | const alloc = gpa.allocator(); | ||
| 7 | |||
| 8 | const mode_update = blk: { | ||
| 9 | const m = std.posix.getenv("WAYSTTY_GOLDEN_UPDATE") orelse break :blk false; | ||
| 10 | break :blk std.mem.eql(u8, m, "1"); | ||
| 11 | }; | ||
| 12 | |||
| 13 | try std.fs.cwd().makePath("tests/golden/output"); | ||
| 14 | |||
| 15 | var scripts_dir = try std.fs.cwd().openDir("tests/golden/scripts", .{ .iterate = true }); | ||
| 16 | defer scripts_dir.close(); | ||
| 17 | var it = scripts_dir.iterate(); | ||
| 18 | |||
| 19 | var passed: usize = 0; | ||
| 20 | var failed: usize = 0; | ||
| 21 | |||
| 22 | while (try it.next()) |entry| { | ||
| 23 | if (entry.kind != .file) continue; | ||
| 24 | if (!std.mem.endsWith(u8, entry.name, ".vt")) continue; | ||
| 25 | |||
| 26 | const base = entry.name[0 .. entry.name.len - 3]; | ||
| 27 | const script_path = try std.fmt.allocPrint(alloc, "tests/golden/scripts/{s}.vt", .{base}); | ||
| 28 | defer alloc.free(script_path); | ||
| 29 | const output_path = try std.fmt.allocPrint(alloc, "tests/golden/output/{s}.png", .{base}); | ||
| 30 | defer alloc.free(output_path); | ||
| 31 | const reference_path = try std.fmt.allocPrint(alloc, "tests/golden/reference/{s}.png", .{base}); | ||
| 32 | defer alloc.free(reference_path); | ||
| 33 | const diff_path = try std.fmt.allocPrint(alloc, "tests/golden/output/{s}.diff.png", .{base}); | ||
| 34 | defer alloc.free(diff_path); | ||
| 35 | |||
| 36 | // Run waystty --capture | ||
| 37 | const cap = try std.process.Child.run(.{ | ||
| 38 | .allocator = alloc, | ||
| 39 | .argv = &.{ "zig-out/bin/waystty", "--capture", script_path, output_path }, | ||
| 40 | }); | ||
| 41 | defer alloc.free(cap.stdout); | ||
| 42 | defer alloc.free(cap.stderr); | ||
| 43 | if (cap.term != .Exited or cap.term.Exited != 0) { | ||
| 44 | std.debug.print("FAIL: {s}: capture exited with {}\n stderr: {s}\n", | ||
| 45 | .{ base, cap.term, cap.stderr }); | ||
| 46 | failed += 1; | ||
| 47 | continue; | ||
| 48 | } | ||
| 49 | |||
| 50 | if (mode_update) { | ||
| 51 | try std.fs.cwd().makePath("tests/golden/reference"); | ||
| 52 | try std.fs.cwd().copyFile(output_path, std.fs.cwd(), reference_path, .{}); | ||
| 53 | std.debug.print("UPDATED: {s}\n", .{base}); | ||
| 54 | passed += 1; | ||
| 55 | continue; | ||
| 56 | } | ||
| 57 | |||
| 58 | // Run imgdiff | ||
| 59 | const dif = try std.process.Child.run(.{ | ||
| 60 | .allocator = alloc, | ||
| 61 | .argv = &.{ "zig-out/bin/imgdiff", output_path, reference_path, diff_path }, | ||
| 62 | }); | ||
| 63 | defer alloc.free(dif.stdout); | ||
| 64 | defer alloc.free(dif.stderr); | ||
| 65 | std.debug.print("{s}", .{dif.stdout}); | ||
| 66 | if (dif.term == .Exited and dif.term.Exited == 0) { | ||
| 67 | passed += 1; | ||
| 68 | } else { | ||
| 69 | failed += 1; | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | std.debug.print("\n=== test-render: {} passed, {} failed ===\n", .{ passed, failed }); | ||
| 74 | if (failed > 0) std.process.exit(1); | ||
| 75 | } | ||