c36f3a11
test: a rendered wall says which chord reaches which tile
a73x 2026-08-25 19:33
Commit message
src/wallview.zig
| Old | New | ||
|---|---|---|---|
| @@ -3416,23 +3416,34 @@ test "labelText: the state word survives truncation at every width" { | |||
| 3416 | // not the label's own length. | 3416 | // not the label's own length. |
| 3417 | const long = "x" ** 400; | 3417 | const long = "x" ** 400; |
| 3418 | 3418 | ||
| 3419 | // The markers are the ones a bar actually carries: three bytes with the | ||
| 3420 | // chord digit, four for tiles 10 and up. Every one of them comes out of | ||
| 3421 | // the label's cut, so the marker width is part of what this pins — a | ||
| 3422 | // two-byte marker exercises no bar that ships. | ||
| 3423 | |||
| 3419 | // Narrow: the label is cut, the bar fits the terminal, the state stays. | 3424 | // Narrow: the label is cut, the bar fits the terminal, the state stays. |
| 3420 | const narrow = labelText(&buf, 30, "> ", long, "up"); | 3425 | const narrow = labelText(&buf, 30, "1> ", long, "up"); |
| 3421 | try std.testing.expect(std.mem.endsWith(u8, narrow, " [up]")); | 3426 | if (!std.mem.endsWith(u8, narrow, " [up]")) return error.OneDigitNarrowBarLostTheStateWord; |
| 3422 | try std.testing.expect(narrow.len <= 30); | 3427 | if (narrow.len > 30) return error.OneDigitNarrowBarOverranTheTerminal; |
| 3428 | |||
| 3429 | // The same width with the widest marker: the two extra bytes come off | ||
| 3430 | // the label, never off the state. | ||
| 3431 | const narrow2 = labelText(&buf, 30, "12 ", long, "up"); | ||
| 3432 | if (!std.mem.endsWith(u8, narrow2, " [up]")) return error.TwoDigitNarrowBarLostTheStateWord; | ||
| 3433 | if (narrow2.len > 30) return error.TwoDigitNarrowBarOverranTheTerminal; | ||
| 3423 | 3434 | ||
| 3424 | // Wide: `cols` alone would have asked for more than `buf` holds, and the | 3435 | // Wide: `cols` alone would have asked for more than `buf` holds, and the |
| 3425 | // failed bufPrint used to hand back the buffer's undefined bytes — with | 3436 | // failed bufPrint used to hand back the buffer's undefined bytes — with |
| 3426 | // the state word among what was lost. | 3437 | // the state word among what was lost. |
| 3427 | const wide = labelText(&buf, 300, "> ", long, "reconnecting"); | 3438 | const wide = labelText(&buf, 300, "12> ", long, "reconnecting"); |
| 3428 | try std.testing.expect(std.mem.endsWith(u8, wide, " [reconnecting]")); | 3439 | if (!std.mem.endsWith(u8, wide, " [reconnecting]")) return error.TwoDigitWideBarLostTheStateWord; |
| 3429 | try std.testing.expect(wide.len <= buf.len); | 3440 | if (wide.len > buf.len) return error.TwoDigitWideBarOverranItsBuffer; |
| 3430 | 3441 | ||
| 3431 | // Wider than `buf` with the longest status word a bar can carry: the | 3442 | // Wider than `buf` with the longest status word a bar can carry: the |
| 3432 | // bound that matters is `buf`'s, and it is not `cols`'. | 3443 | // bound that matters is `buf`'s, and it is not `cols`'. |
| 3433 | const widest = labelText(&buf, 400, " ", long, State.reconnecting.word()); | 3444 | const widest = labelText(&buf, 400, "12 ", long, State.reconnecting.word()); |
| 3434 | try std.testing.expect(std.mem.endsWith(u8, widest, " [reconnecting]")); | 3445 | if (!std.mem.endsWith(u8, widest, " [reconnecting]")) return error.TwoDigitWidestBarLostTheStateWord; |
| 3435 | try std.testing.expect(widest.len <= buf.len); | 3446 | if (widest.len > buf.len) return error.TwoDigitWidestBarOverranItsBuffer; |
| 3436 | } | 3447 | } |
| 3437 | 3448 | ||
| 3438 | /// A wall of `n` tiles with none forgotten. | 3449 | /// A wall of `n` tiles with none forgotten. |
test/e2e.sh
| Old | New | ||
|---|---|---|---|
| @@ -1493,7 +1493,7 @@ cleanup() { | |||
| 1493 | "$OUT.sb2cap" "$OUT.sb2cap.err" "$OUT.sb2pc" "$OUT.sb2stop" "$SOCK53" \ | 1493 | "$OUT.sb2cap" "$OUT.sb2cap.err" "$OUT.sb2pc" "$OUT.sb2stop" "$SOCK53" \ |
| 1494 | "$OUT.fs.d" "$OUT.fsa" "$OUT.fsa.err" "$OUT.fsb" "$OUT.fsb.err" \ | 1494 | "$OUT.fs.d" "$OUT.fsa" "$OUT.fsa.err" "$OUT.fsb" "$OUT.fsb.err" \ |
| 1495 | "$OUT.fscap" "$OUT.fscap.err" "$OUT.fspc" "$OUT.fsfa" "$OUT.fsfb" \ | 1495 | "$OUT.fscap" "$OUT.fscap.err" "$OUT.fspc" "$OUT.fsfa" "$OUT.fsfb" \ |
| 1496 | "$OUT.fsstop" "$SOCK54" \ | 1496 | "$OUT.fsgrid" "$OUT.fsstop" "$SOCK54" \ |
| 1497 | "$OUT.rsz.d" "$OUT.rszcap" "$OUT.rszcap.err" "$OUT.rszpc" \ | 1497 | "$OUT.rsz.d" "$OUT.rszcap" "$OUT.rszcap.err" "$OUT.rszpc" \ |
| 1498 | "$OUT.rsza" "$OUT.rsza.err" "$OUT.rszb" "$OUT.rszb.err" \ | 1498 | "$OUT.rsza" "$OUT.rsza.err" "$OUT.rszb" "$OUT.rszb.err" \ |
| 1499 | "$OUT.rszsta" "$OUT.rszstb" "$OUT.rszstop" "$SOCK55" \ | 1499 | "$OUT.rszsta" "$OUT.rszstb" "$OUT.rszstop" "$SOCK55" \ |
| @@ -7863,6 +7863,21 @@ grep -q "fs-two" "$OUT.fsfb" || { | |||
| 7863 | grep -q "fs-two" "$OUT.fsfa" && { | 7863 | grep -q "fs-two" "$OUT.fsfa" && { |
| 7864 | echo "e2e FAIL: fullscreen: fs-two reached session a, which was hidden after the focus move:" | 7864 | echo "e2e FAIL: fullscreen: fs-two reached session a, which was hidden after the focus move:" |
| 7865 | cat "$OUT.fsfa"; exit 1; } | 7865 | cat "$OUT.fsfa"; exit 1; } |
| 7866 | # What the human saw after Ctrl-\ 2: the `>` moved and the digits did not. | ||
| 7867 | # A bar's digit is the chord that reaches that tile for its whole life, not | ||
| 7868 | # a count of who holds the focus — the render oracle is the only witness, | ||
| 7869 | # since the daemon's grid has no bars in it. The label is cut to the stripe | ||
| 7870 | # at 80 columns beside, so the marker and the head of the spelling are what | ||
| 7871 | # survive; the digit is what tells the two stripes apart. | ||
| 7872 | "$RENDER" --cols 80 --rows 24 < "$OUT.fscap" > "$OUT.fsgrid" || { | ||
| 7873 | echo "e2e FAIL: fullscreen: render oracle failed" | ||
| 7874 | cat "$OUT.fsgrid"; exit 1; } | ||
| 7875 | grep -q -- " 2> --sock" "$OUT.fsgrid" || { | ||
| 7876 | echo "e2e FAIL: fullscreen: Ctrl-\\ 2 did not leave the \`>\` on tile 2's digit:" | ||
| 7877 | cat "$OUT.fsgrid"; exit 1; } | ||
| 7878 | grep -q -- " 1 --sock" "$OUT.fsgrid" || { | ||
| 7879 | echo "e2e FAIL: fullscreen: tile 1 lost its digit or kept the \`>\`:" | ||
| 7880 | cat "$OUT.fsgrid"; exit 1; } | ||
| 7866 | assert_stopped "$SOCK54" "$D55PID" "fullscreen" "$OUT.fsstop" | 7881 | assert_stopped "$SOCK54" "$D55PID" "fullscreen" "$OUT.fsstop" |
| 7867 | D55PID="" | 7882 | D55PID="" |
| 7868 | ok "fullscreen gives the focused tile the terminal; focus follows; f restores" | 7883 | ok "fullscreen gives the focused tile the terminal; focus follows; f restores" |
| @@ -8640,6 +8655,19 @@ grep -q -- "#hyb \[up\]" "$OUT.hydgrid" || { | |||
| 8640 | grep -q -- "#hyghost \[refused\]" "$OUT.hydgrid" || { | 8655 | grep -q -- "#hyghost \[refused\]" "$OUT.hydgrid" || { |
| 8641 | echo "e2e FAIL: hydrate-create: the remote tile did not say [refused]:" | 8656 | echo "e2e FAIL: hydrate-create: the remote tile did not say [refused]:" |
| 8642 | cat "$OUT.hydgrid"; exit 1; } | 8657 | cat "$OUT.hydgrid"; exit 1; } |
| 8658 | # ...and each bar carries the chord that reaches it. Ctrl-\ 1-9 focuses by | ||
| 8659 | # POSITION while the bar named the session, and the two series disagree the | ||
| 8660 | # moment a tile is forgotten or a session dies. Tile 1 has the focus here, | ||
| 8661 | # so its digit carries the `>` and the other two the same-width blank. | ||
| 8662 | grep -q -- " 1> .*#hya \[up\]" "$OUT.hydgrid" || { | ||
| 8663 | echo "e2e FAIL: hydrate-create: the focused bar does not read \` 1> \`:" | ||
| 8664 | cat "$OUT.hydgrid"; exit 1; } | ||
| 8665 | grep -q -- " 2 .*#hyb \[up\]" "$OUT.hydgrid" || { | ||
| 8666 | echo "e2e FAIL: hydrate-create: the second tile's bar does not read \` 2 \`:" | ||
| 8667 | cat "$OUT.hydgrid"; exit 1; } | ||
| 8668 | grep -q -- " 3 .*#hyghost \[refused\]" "$OUT.hydgrid" || { | ||
| 8669 | echo "e2e FAIL: hydrate-create: a refused tile lost its chord digit:" | ||
| 8670 | cat "$OUT.hydgrid"; exit 1; } | ||
| 8643 | # The OTHER road a restored line takes: `Ctrl-\ w`. A no-argv `mux wall` | 8671 | # The OTHER road a restored line takes: `Ctrl-\ w`. A no-argv `mux wall` |
| 8644 | # runs the startup tile loop; the fold runs `hydrate()`, a different call | 8672 | # runs the startup tile loop; the fold runs `hydrate()`, a different call |
| 8645 | # site of the same rule, and the ruling covers both. Same daemon, same | 8673 | # site of the same rule, and the ruling covers both. Same daemon, same |