Files
m3te/tests/swipe_intent.sx
swipelab 6f7d2f4db2 lang migration: rename signed integer types sN -> iN
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.
2026-06-12 09:36:51 +03:00

84 lines
4.0 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.
// Swipe-intent golden (P5.1): lock the pure drag → adjacent-swap mapping
// `swipe_intent`. Feeds SYNTHETIC down/up screen positions (built from the SAME
// BoardLayout the renderer uses) and asserts the resolved swap intent (A, B), so
// a drift in axis/direction/threshold logic changes both the dump and the exit
// code. No rendering, no model mutation — links headless like tests/hit_test.sx.
//
// Layout: 800×600, no safe inset → 600px square grid, cell 75, origin (100, 0);
// swipe threshold = cell_size * 0.5 = 37.5px on the dominant axis. A 60px drag
// clears it; a 10px drag does not. 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";
#import "swipe.sx";
cell_center :: (lay: *BoardLayout, col: i64, row: i64) -> Point {
cf := lay.cell_frame(col, row);
Point.{ x = cf.mid_x(), y = cf.mid_y() }
}
// Print the resolved intent (locked in the golden) and report whether it matches
// the expected adjacent pair (A, B). Drives the exit code alongside the dump.
expect_swap :: (label: string, got: ?Swap, ac: i64, ar: i64, bc: i64, br: i64) -> bool {
if s := got {
print("{}: ({},{})->({},{})\n", label, s.a.col, s.a.row, s.b.col, s.b.row);
return s.a.col == ac and s.a.row == ar and s.b.col == bc and s.b.row == br;
}
print("{}: none\n", label);
false
}
expect_none :: (label: string, got: ?Swap) -> bool {
if s := got {
print("{}: ({},{})->({},{})\n", label, s.a.col, s.a.row, s.b.col, s.b.row);
return false;
}
print("{}: none\n", label);
true
}
main :: () -> i32 {
lay : BoardLayout = ---;
lay.compute(Frame.make(0.0, 0.0, 800.0, 600.0), EdgeInsets.zero());
print("grid origin ({},{}) cell {} threshold {}\n",
cast(i64) lay.origin.x, cast(i64) lay.origin.y, cast(i64) lay.cell_size,
cast(i64) (lay.cell_size * SWIPE_THRESHOLD_FRACTION));
fails : i64 = 0;
// A known interior cell; every cardinal swipe from it stays on the board.
start := cell_center(@lay, 3, 5);
D : f32 = 60.0; // dominant-axis travel, well above the 37.5 threshold
if !expect_swap("right", swipe_intent(@lay, start, Point.{ x = start.x + D, y = start.y }), 3, 5, 4, 5) { fails += 1; }
if !expect_swap("left", swipe_intent(@lay, start, Point.{ x = start.x - D, y = start.y }), 3, 5, 2, 5) { fails += 1; }
if !expect_swap("up", swipe_intent(@lay, start, Point.{ x = start.x, y = start.y - D }), 3, 5, 3, 4) { fails += 1; }
if !expect_swap("down", swipe_intent(@lay, start, Point.{ x = start.x, y = start.y + D }), 3, 5, 3, 6) { fails += 1; }
// Below threshold on both axes → a tap, not a swipe.
if !expect_none("short", swipe_intent(@lay, start, Point.{ x = start.x + 10.0, y = start.y + 5.0 })) { fails += 1; }
// Diagonal drags resolve to the dominant axis (larger of |dx|, |dy|).
if !expect_swap("diag-horizontal", swipe_intent(@lay, start, Point.{ x = start.x + D, y = start.y + 25.0 }), 3, 5, 4, 5) { fails += 1; }
if !expect_swap("diag-vertical", swipe_intent(@lay, start, Point.{ x = start.x + 20.0, y = start.y - D }), 3, 5, 3, 4) { fails += 1; }
// Edge cell swiped outward → neighbour off the board → no intent.
edge_right := cell_center(@lay, 7, 0);
if !expect_none("offboard-right", swipe_intent(@lay, edge_right, Point.{ x = edge_right.x + D, y = edge_right.y })) { fails += 1; }
edge_top := cell_center(@lay, 2, 0);
if !expect_none("offboard-up", swipe_intent(@lay, edge_top, Point.{ x = edge_top.x, y = edge_top.y - D })) { fails += 1; }
// Drag starting off the board (left of the grid) → no intent.
off_start := Point.{ x = lay.origin.x - 5.0, y = lay.origin.y + 10.0 };
if !expect_none("start-offboard", swipe_intent(@lay, off_start, Point.{ x = off_start.x + D, y = off_start.y })) { fails += 1; }
if fails == 0 {
print("ok: swipe-intent mapping resolves all cases\n");
return 0;
}
print("FAIL: {} swipe-intent checks failed\n", fails);
return 1;
}