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.
106 lines
4.7 KiB
Plaintext
106 lines
4.7 KiB
Plaintext
// 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;
|
||
}
|