Files
m3te/tests/swipe_commit.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

106 lines
4.7 KiB
Plaintext
Raw Permalink 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→commit wiring golden (P5.2): prove the full input-to-model path P5.2
// adds — a touch drag resolved by `swipe_intent` and fed straight into
// `commit_swap` — on the SAME seeded board the iOS app renders (SEED 1337).
// Feeds SYNTHETIC down/up screen positions built from a BoardLayout, resolves
// the swap intent, then commits it, asserting:
// - an ILLEGAL swipe ((0,0)->(1,0): two reds → no match) reverts: the board is
// byte-for-byte unchanged, score stays 0, and no move is spent;
// - a known LEGAL swipe ((5,4)->(6,4): brings R into (5,4), completing R,R,R
// across cols 3-5 of row 4) commits: the board changes, score accrues, and
// exactly one move is spent.
// No rendering, no model reach-around — it calls exactly what BoardView.handle_event
// calls. Links headless like tests/swipe_intent.sx; avoids tests/test.sx because
// its trace.sx pulls in a second `Frame` that collides with the UI one. 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";
SEED :: 1337;
cell_center :: (lay: *BoardLayout, col: i64, row: i64) -> Point {
cf := lay.cell_frame(col, row);
Point.{ x = cf.mid_x(), y = cf.mid_y() }
}
boards_equal :: (x: *Board, y: *Board) -> bool {
for 0..BOARD_CELLS (i) {
if !(x.cells[i] == y.cells[i]) { return false; }
}
true
}
main :: () -> i32 {
// 800×600, no safe inset → 600px square grid, cell 75, origin (100, 0). A
// 60px drag clears the cell*0.5 = 37.5px swipe threshold on the dominant axis.
lay : BoardLayout = ---;
lay.compute(Frame.make(0.0, 0.0, 800.0, 600.0), EdgeInsets.zero());
D : f32 = 60.0;
fails : i64 = 0;
// ── ILLEGAL swipe reverts ──────────────────────────────────────────────
// (0,0) and (1,0) are both red on the seed board, so swapping them forms no
// match. The rightward drag must resolve to exactly this pair, and
// commit_swap must reject it — board untouched, score 0, no move spent.
print("== illegal swipe reverts ==\n");
bi : Board = ---;
bi.init(SEED);
before : Board = bi;
out(board_dump(@bi));
a_il := cell_center(@lay, 0, 0);
if s := swipe_intent(@lay, a_il, Point.{ x = a_il.x + D, y = a_il.y }) {
print("intent ({},{})->({},{})\n", s.a.col, s.a.row, s.b.col, s.b.row);
if !(s.a.col == 0 and s.a.row == 0 and s.b.col == 1 and s.b.row == 0) { fails += 1; }
mv := commit_swap(@bi, s.a, s.b);
print("legal {} awarded {} score {} moves_made {} moves_remaining {}\n",
mv.legal, mv.cascade.awarded, bi.score, bi.moves_made, mv.moves_remaining);
if mv.legal { fails += 1; }
if !boards_equal(@before, @bi) { fails += 1; }
if bi.score != 0 { fails += 1; }
if bi.moves_made != 0 { fails += 1; }
if mv.moves_remaining != bi.move_limit { fails += 1; }
} else {
print("intent none\n");
fails += 1;
}
// ── LEGAL swipe commits ────────────────────────────────────────────────
// (5,4)->(6,4): the rightward swipe brings R into (5,4), completing R,R,R
// across cols 3-5 of row 4. commit_swap applies it, resolves the cascade
// (score accrues into Board.score) and spends one move; the board changes.
print("== legal swipe commits ==\n");
bl : Board = ---;
bl.init(SEED);
pre : Board = bl;
a_le := cell_center(@lay, 5, 4);
if s := swipe_intent(@lay, a_le, Point.{ x = a_le.x + D, y = a_le.y }) {
print("intent ({},{})->({},{})\n", s.a.col, s.a.row, s.b.col, s.b.row);
if !(s.a.col == 5 and s.a.row == 4 and s.b.col == 6 and s.b.row == 4) { fails += 1; }
mv := commit_swap(@bl, s.a, s.b);
print("legal {} depth {} awarded {} score {} moves_made {} moves_remaining {}\n",
mv.legal, mv.cascade.depth, mv.cascade.awarded, bl.score, bl.moves_made, mv.moves_remaining);
if !mv.legal { fails += 1; }
if boards_equal(@pre, @bl) { fails += 1; }
if !(bl.score > 0) { fails += 1; }
if bl.moves_made != 1 { fails += 1; }
if mv.moves_remaining != bl.move_limit - 1 { fails += 1; }
out("after:\n");
out(board_dump(@bl));
} else {
print("intent none\n");
fails += 1;
}
if fails == 0 {
print("ok: swipe reverts illegal, commits legal\n");
return 0;
}
print("FAIL: {} swipe-commit checks failed\n", fails);
return 1;
}