Files
m3te/tests/banner_layout.sx
swipelab a7b41ccbca migrate to the new for-loop syntax
Drop the ':' before captures (for xs (x) / for 0..n (i)); the index
capture becomes the trailing open range (for xs, 0.. (x, i)). 136
headers across 26 files, mechanical.

Five headless tests (banner_layout, hit_test, swipe_commit,
swipe_intent, swipe_reshuffle) also gain a direct
#import "modules/ui/types.sx" — they named Point/Frame through a
transitive import, which bare visibility no longer permits.

Gates: sx build --target ios-sim main.sx links; tools/run_tests.sh
23/23.
2026-06-10 20:39:59 +03:00

83 lines
3.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Banner / restart hit-test golden (P7.2): lock the win/lose banner geometry and
// the restart-button hit-test that `BoardView.handle_event` relies on. The button
// rect is derived from the SAME grid layout the gems use, and a finished level
// freezes every board-cell tap, so the button is the only live target — if its
// rect drifted from what `render_banner` draws, a tap on the visible button would
// miss and the level could never be restarted. This test checks, headlessly:
//
// * the button is centered over the grid and sits fully inside the panel,
// * the button centre hit-tests INTO the button (tap → restart),
// * an off-button tap (a board corner) hit-tests OUT (frozen, no restart).
//
// Imports BoardLayout (no GL/stb), not BoardView, so it links headless — same
// shape and rationale as tests/hit_test.sx. Failure is signalled via a non-zero
// exit code (the runner checks exit code AND stdout).
#import "modules/std.sx";
#import "modules/ui/types.sx";
#import "board.sx";
#import "board_layout.sx";
irect :: (f: Frame) -> string {
format("({},{},{},{})",
cast(s64) f.origin.x, cast(s64) f.origin.y,
cast(s64) f.size.width, cast(s64) f.size.height)
}
main :: () -> s32 {
// 800×600, no safe inset → 600px square grid, cell 75, origin (100,0): the
// same layout tests/hit_test.sx pins, so the numbers are checkable by hand.
lay : BoardLayout = ---;
lay.compute(Frame.make(0.0, 0.0, 800.0, 600.0), EdgeInsets.zero());
grid := lay.grid_frame();
bl := lay.banner();
print("grid {}\n", irect(grid));
print("panel {}\n", irect(bl.panel));
print("title {}\n", irect(bl.title));
print("button {}\n", irect(bl.button));
fails : s64 = 0;
// The button is horizontally centered on the grid (centred banner).
bcx := bl.button.mid_x();
if cast(s64) bcx != cast(s64) grid.mid_x() { fails += 1; }
print("button mid_x {} grid mid_x {}\n", cast(s64) bcx, cast(s64) grid.mid_x());
// The whole button sits inside the panel — its four corners are contained,
// so it can never spill outside the drawn card.
bx0 := bl.button.origin.x; by0 := bl.button.origin.y;
bx1 := bl.button.max_x(); by1 := bl.button.max_y();
corners_in : s64 = 0;
if bl.panel.contains(Point.{ x = bx0, y = by0 }) { corners_in += 1; }
if bl.panel.contains(Point.{ x = bx1, y = by0 }) { corners_in += 1; }
if bl.panel.contains(Point.{ x = bx0, y = by1 }) { corners_in += 1; }
if bl.panel.contains(Point.{ x = bx1, y = by1 }) { corners_in += 1; }
if corners_in != 4 { fails += 1; }
print("button corners inside panel: {}/4\n", corners_in);
// A tap on the button centre restarts (hit-test true); the panel itself is
// also contained, so the centre is unambiguously on the button.
center := Point.{ x = bl.button.mid_x(), y = bl.button.mid_y() };
hit_center := bl.button.contains(center);
if !hit_center { fails += 1; }
print("button center hit: {}\n", hit_center);
// Off-button taps that a finished level must NOT treat as restart: the grid's
// top-left corner cell centre, and a point just outside the panel. Neither is
// in the button, so each leaves the level frozen.
corner_cell := Point.{ x = grid.origin.x + lay.cell_size * 0.5, y = grid.origin.y + lay.cell_size * 0.5 };
outside := Point.{ x = bl.panel.origin.x - 5.0, y = bl.panel.mid_y() };
off_hits : s64 = 0;
if bl.button.contains(corner_cell) { off_hits += 1; }
if bl.button.contains(outside) { off_hits += 1; }
if off_hits != 0 { fails += 1; }
print("off-button taps that hit the button: {}\n", off_hits);
if fails == 0 {
print("ok: restart button hit-test matches the drawn banner\n");
return 0;
}
print("FAIL: {} banner hit-test checks failed\n", fails);
return 1;
}