9a964981
scenario: size-check golden in cell_matches_golden predicate
a73x 2026-04-19 09:38
Previously indexed into golden.pixels using image.width as stride, silently misreading if dimensions differed. Now returns pass=false with "golden size mismatch" reason. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
diff --git a/src/scenario.zig b/src/scenario.zig index 042249e..1f6007a 100644 --- a/src/scenario.zig +++ b/src/scenario.zig @@ -1302,6 +1302,9 @@ pub fn evalPredicate( const golden = golden_for_cell_matches orelse { return .{ .pass = false, .reason = "missing golden" }; }; if (golden.width != image.width or golden.height != image.height) { return .{ .pass = false, .reason = "golden size mismatch" }; } // Compute RMSE over the cell rect inline. var sum_sq: f64 = 0; const total_px: u32 = geom.cell_w_px * geom.cell_h_px; @@ -1499,6 +1502,28 @@ test "evalPredicate: cell-matches-golden with null golden fails with 'missing go try std.testing.expect(std.mem.indexOf(u8, r.reason, "missing golden") != null); } test "evalPredicate: cell-matches-golden fails when golden has different dimensions" { const alloc = std.testing.allocator; const img = try makeSolid(alloc, 80, 24, .{ 10, 20, 30, 255 }); defer alloc.free(img.pixels); const golden = try makeSolid(alloc, 40, 24, .{ 10, 20, 30, 255 }); // half-width defer alloc.free(golden.pixels); const r = evalPredicate(img, 0, 0, .{ .cell_w_px = 8, .cell_h_px = 16 }, .cell_matches_golden, golden); try std.testing.expect(!r.pass); try std.testing.expect(std.mem.indexOf(u8, r.reason, "size mismatch") != null); } test "evalPredicate: cell-matches-golden fails when golden height differs" { const alloc = std.testing.allocator; const img = try makeSolid(alloc, 80, 24, .{ 10, 20, 30, 255 }); defer alloc.free(img.pixels); const golden = try makeSolid(alloc, 80, 12, .{ 10, 20, 30, 255 }); // half-height defer alloc.free(golden.pixels); const r = evalPredicate(img, 0, 0, .{ .cell_w_px = 8, .cell_h_px = 16 }, .cell_matches_golden, golden); try std.testing.expect(!r.pass); try std.testing.expect(std.mem.indexOf(u8, r.reason, "size mismatch") != null); } // End-to-end tests: parse + state + predicate test "tick+eval: assert-cell evaluates against last capture" {