Mechanical sweep of all .sx sources, plan docs, and tests/expected snapshots for the sx language rename (s8/s16/s32/s64 -> i8/i16/i32/i64). Verified: tools/run_tests.sh 23/23. Note: the ios-sim build has 2 pre-existing 'restart' dot-call errors from the sx opt-in UFCS change (sx a47ea14) — independent of this rename (present pre-sweep); migrated in the follow-up commit.
70 lines
3.3 KiB
Plaintext
70 lines
3.3 KiB
Plaintext
// Hit-test golden (P4.4): lock the touch→cell mapping `BoardLayout.point_to_cell`
|
||
// as the exact inverse of `cell_frame`. The two are written independently — one
|
||
// multiplies a cell index by cell_size, the other divides a point by cell_size
|
||
// and truncates — so round-tripping every cell center back to its own cell is a
|
||
// real check, not a tautology. BoardView and P5's swap input both reuse this
|
||
// mapping, so a drift here would silently send taps/swaps to the wrong cell.
|
||
//
|
||
// Imports BoardLayout (no GL/stb), not BoardView, so it links headless. It also
|
||
// avoids tests/test.sx, whose modules/process.sx → modules/trace.sx pulls in a
|
||
// second `Frame` struct that collides with the UI `Frame`. 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";
|
||
|
||
main :: () -> i32 {
|
||
// 800×600 with no safe inset → a 600px square grid, cell 75, centered: the
|
||
// grid origin lands at (100, 0). Integer math keeps the dump deterministic.
|
||
lay : BoardLayout = ---;
|
||
lay.compute(Frame.make(0.0, 0.0, 800.0, 600.0), EdgeInsets.zero());
|
||
|
||
print("grid origin ({},{}) cell {}\n",
|
||
cast(i64) lay.origin.x, cast(i64) lay.origin.y, cast(i64) lay.cell_size);
|
||
|
||
fails : i64 = 0;
|
||
|
||
// Every cell center must map back to its own cell.
|
||
hits : i64 = 0;
|
||
for 0..BOARD_ROWS (row) {
|
||
for 0..BOARD_COLS (col) {
|
||
cf := lay.cell_frame(col, row);
|
||
center := Point.{ x = cf.mid_x(), y = cf.mid_y() };
|
||
if h := lay.point_to_cell(center) {
|
||
if h.col == col and h.row == row { hits += 1; }
|
||
}
|
||
}
|
||
}
|
||
if hits != BOARD_CELLS { fails += 1; }
|
||
print("ok: {}/{} cell centers round-trip\n", hits, BOARD_CELLS);
|
||
|
||
// A cell's top-left corner belongs to that cell (the leading edge is
|
||
// inclusive), so corner-of-(3,5) resolves to (3,5).
|
||
corner := Point.{ x = lay.origin.x + 3.0 * lay.cell_size, y = lay.origin.y + 5.0 * lay.cell_size };
|
||
corner_col : i64 = -1;
|
||
corner_row : i64 = -1;
|
||
if h := lay.point_to_cell(corner) { corner_col = h.col; corner_row = h.row; }
|
||
if corner_col != 3 or corner_row != 5 { fails += 1; }
|
||
print("corner maps to ({},{})\n", corner_col, corner_row);
|
||
|
||
// Off-board taps reject (null): left of, above, and right of the grid. None
|
||
// should resolve to a cell, so the on-board count must stay 0.
|
||
off_left := Point.{ x = lay.origin.x - 5.0, y = lay.origin.y + 10.0 };
|
||
off_above := Point.{ x = lay.origin.x + 10.0, y = lay.origin.y - 5.0 };
|
||
off_right := Point.{ x = lay.origin.x + 8.0 * lay.cell_size + 1.0, y = lay.origin.y + 10.0 };
|
||
on_board : i64 = 0;
|
||
if h := lay.point_to_cell(off_left) { on_board += 1; print("off_left hit ({},{})\n", h.col, h.row); }
|
||
if h := lay.point_to_cell(off_above) { on_board += 1; print("off_above hit ({},{})\n", h.col, h.row); }
|
||
if h := lay.point_to_cell(off_right) { on_board += 1; print("off_right hit ({},{})\n", h.col, h.row); }
|
||
if on_board != 0 { fails += 1; }
|
||
print("ok: {} off-board taps resolved to a cell\n", on_board);
|
||
|
||
if fails == 0 {
|
||
print("ok: hit-test mapping is the inverse of the layout\n");
|
||
return 0;
|
||
}
|
||
print("FAIL: {} hit-test checks failed\n", fails);
|
||
return 1;
|
||
}
|