a7704310
test: e2e — one no_saved_tree helper replaces five copies of the same rm and comment
a73x 2026-08-28 19:53
Commit message
test/e2e_07_wallcli.sh
| Old | New | ||
|---|---|---|---|
| @@ -77,11 +77,7 @@ wait_grid "$SOCK26" "cwb-pin" "CLI wall: session b's marker" b | |||
| 77 | CWINJPID=$! | 77 | CWINJPID=$! |
| 78 | defer_kill "$CWINJPID" | 78 | defer_kill "$CWINJPID" |
| 79 | set +e | 79 | set +e |
| 80 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 80 | no_saved_tree "$CWSTATE" |
| 81 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 82 | # state home has already left one. The aspect rule applies only when | ||
| 83 | # nothing is saved. | ||
| 84 | rm -f "$CWSTATE/mux/layout" | ||
| 85 | XDG_STATE_HOME="$CWSTATE" timeout 40 "$PTYCLIENT" --cols 40 --rows 30 \ | 81 | XDG_STATE_HOME="$CWSTATE" timeout 40 "$PTYCLIENT" --cols 40 --rows 30 \ |
| 86 | --out "$OUT.cwcap" --err "$OUT.cwcap.err" -- \ | 82 | --out "$OUT.cwcap" --err "$OUT.cwcap.err" -- \ |
| 87 | "$MUX" --sock "$SOCK26" --session a > "$OUT.cwpc" 2>&1 <<'EOF' | 83 | "$MUX" --sock "$SOCK26" --session a > "$OUT.cwpc" 2>&1 <<'EOF' |
| @@ -133,11 +129,7 @@ start_daemon "$SOCK27" "$OUT.pfx.d" "prefix daemon never bound" --shell /bin/sh | |||
| 133 | D24PID=$DPID | 129 | D24PID=$DPID |
| 134 | 130 | ||
| 135 | set +e | 131 | set +e |
| 136 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 132 | no_saved_tree "$PFXSTATE" |
| 137 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 138 | # state home has already left one. The aspect rule applies only when | ||
| 139 | # nothing is saved. | ||
| 140 | rm -f "$PFXSTATE/mux/layout" | ||
| 141 | XDG_STATE_HOME="$PFXSTATE" timeout 40 "$PTYCLIENT" --cols 80 --rows 24 \ | 133 | XDG_STATE_HOME="$PFXSTATE" timeout 40 "$PTYCLIENT" --cols 80 --rows 24 \ |
| 142 | --out "$OUT.pfx" --err "$OUT.pfx.err" \ | 134 | --out "$OUT.pfx" --err "$OUT.pfx.err" \ |
| 143 | -- "$MUX" --sock "$SOCK27" > "$OUT.pfx.log" 2>&1 <<'EOF' | 135 | -- "$MUX" --sock "$SOCK27" > "$OUT.pfx.log" 2>&1 <<'EOF' |
| @@ -204,11 +196,7 @@ start_daemon "$SOCK28" "$OUT.nsw.d" "new-session daemon never bound" --shell /bi | |||
| 204 | D25PID=$DPID | 196 | D25PID=$DPID |
| 205 | 197 | ||
| 206 | set +e | 198 | set +e |
| 207 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 199 | no_saved_tree "$NSWSTATE" |
| 208 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 209 | # state home has already left one. The aspect rule applies only when | ||
| 210 | # nothing is saved. | ||
| 211 | rm -f "$NSWSTATE/mux/layout" | ||
| 212 | XDG_STATE_HOME="$NSWSTATE" timeout 40 "$PTYCLIENT" --cols 40 --rows 24 \ | 200 | XDG_STATE_HOME="$NSWSTATE" timeout 40 "$PTYCLIENT" --cols 40 --rows 24 \ |
| 213 | --out "$OUT.nsw" --err "$OUT.nsw.err" \ | 201 | --out "$OUT.nsw" --err "$OUT.nsw.err" \ |
| 214 | -- "$MUX" --sock "$SOCK28" > "$OUT.nsw.log" 2>&1 <<'EOF' | 202 | -- "$MUX" --sock "$SOCK28" > "$OUT.nsw.log" 2>&1 <<'EOF' |
| @@ -256,11 +244,7 @@ fill_sessions "$SOCK28" "$OUT.nswfill" fill 2 7 | |||
| 256 | wait_sessions "$SOCK28" 8 "new session: the wall's terminal should be exactly full" | 244 | wait_sessions "$SOCK28" 8 "new session: the wall's terminal should be exactly full" |
| 257 | 245 | ||
| 258 | set +e | 246 | set +e |
| 259 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 247 | no_saved_tree "$NSWSTATE" |
| 260 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 261 | # state home has already left one. The aspect rule applies only when | ||
| 262 | # nothing is saved. | ||
| 263 | rm -f "$NSWSTATE/mux/layout" | ||
| 264 | XDG_STATE_HOME="$NSWSTATE" timeout 60 "$PTYCLIENT" --cols 40 --rows 24 \ | 248 | XDG_STATE_HOME="$NSWSTATE" timeout 60 "$PTYCLIENT" --cols 40 --rows 24 \ |
| 265 | --out "$OUT.nsw2" --err "$OUT.nsw2.err" \ | 249 | --out "$OUT.nsw2" --err "$OUT.nsw2.err" \ |
| 266 | -- "$MUX" --sock "$SOCK28" > "$OUT.nsw2.log" 2>&1 <<'EOF' | 250 | -- "$MUX" --sock "$SOCK28" > "$OUT.nsw2.log" 2>&1 <<'EOF' |
| @@ -355,11 +339,7 @@ D26PID=$DPID | |||
| 355 | 339 | ||
| 356 | set +e | 340 | set +e |
| 357 | # tall: Ctrl-\ c adds tiles at 80x24 (80 >= 48) | 341 | # tall: Ctrl-\ c adds tiles at 80x24 (80 >= 48) |
| 358 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 342 | no_saved_tree "$RINGSTATE" |
| 359 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 360 | # state home has already left one. The aspect rule applies only when | ||
| 361 | # nothing is saved. | ||
| 362 | rm -f "$RINGSTATE/mux/layout" | ||
| 363 | XDG_STATE_HOME="$RINGSTATE" timeout 60 "$PTYCLIENT" --cols 40 --rows 24 \ | 343 | XDG_STATE_HOME="$RINGSTATE" timeout 60 "$PTYCLIENT" --cols 40 --rows 24 \ |
| 364 | --out "$OUT.ring" --err "$OUT.ring.err" \ | 344 | --out "$OUT.ring" --err "$OUT.ring.err" \ |
| 365 | -- "$MUX" --sock "$SOCK29" > "$OUT.ring.log" 2>&1 <<'EOF' | 345 | -- "$MUX" --sock "$SOCK29" > "$OUT.ring.log" 2>&1 <<'EOF' |
test/e2e_08_mouse.sh
| Old | New | ||
|---|---|---|---|
| @@ -364,11 +364,7 @@ ZSATT_BEFORE=$(attaches_now "$SOCK37") | |||
| 364 | watch_clients "$SOCK37" "$OUT.zswatch" | 364 | watch_clients "$SOCK37" "$OUT.zswatch" |
| 365 | set +e | 365 | set +e |
| 366 | # tall: the aspect rule would cut columns at 92x30 (92 >= 60) | 366 | # tall: the aspect rule would cut columns at 92x30 (92 >= 60) |
| 367 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 367 | no_saved_tree "$ZSSTATE" |
| 368 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 369 | # state home has already left one. The aspect rule applies only when | ||
| 370 | # nothing is saved. | ||
| 371 | rm -f "$ZSSTATE/mux/layout" | ||
| 372 | XDG_STATE_HOME="$ZSSTATE" timeout 90 "$PTYCLIENT" --cols 40 --rows 30 \ | 368 | XDG_STATE_HOME="$ZSSTATE" timeout 90 "$PTYCLIENT" --cols 40 --rows 30 \ |
| 373 | --out "$OUT.zscap" --err "$OUT.zscap.err" -- \ | 369 | --out "$OUT.zscap" --err "$OUT.zscap.err" -- \ |
| 374 | "$MUX" --sock "$SOCK37" > "$OUT.zspc" 2>&1 <<'EOF' | 370 | "$MUX" --sock "$SOCK37" > "$OUT.zspc" 2>&1 <<'EOF' |
| @@ -481,11 +477,7 @@ until "$MUXD" dump --sock "$SOCK41" | grep -q "wln100"; do | |||
| 481 | sleep 0.1 | 477 | sleep 0.1 |
| 482 | done | 478 | done |
| 483 | set +e | 479 | set +e |
| 484 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 480 | no_saved_tree "$ZWSTATE" |
| 485 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 486 | # state home has already left one. The aspect rule applies only when | ||
| 487 | # nothing is saved. | ||
| 488 | rm -f "$ZWSTATE/mux/layout" | ||
| 489 | XDG_STATE_HOME="$ZWSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 \ | 481 | XDG_STATE_HOME="$ZWSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 \ |
| 490 | --out "$OUT.zwcap" --err "$OUT.zwcap.err" -- \ | 482 | --out "$OUT.zwcap" --err "$OUT.zwcap.err" -- \ |
| 491 | "$MUX" --sock "$SOCK41" > "$OUT.zwpc" 2>&1 <<'EOF' | 483 | "$MUX" --sock "$SOCK41" > "$OUT.zwpc" 2>&1 <<'EOF' |
| @@ -559,11 +551,7 @@ done | |||
| 559 | # not. The tile claims the terminal on its first pass, so the modes are | 551 | # not. The tile claims the terminal on its first pass, so the modes are |
| 560 | # level-set before the wheel is sent. | 552 | # level-set before the wheel is sent. |
| 561 | set +e | 553 | set +e |
| 562 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 554 | no_saved_tree "$ZM2STATE" |
| 563 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 564 | # state home has already left one. The aspect rule applies only when | ||
| 565 | # nothing is saved. | ||
| 566 | rm -f "$ZM2STATE/mux/layout" | ||
| 567 | XDG_STATE_HOME="$ZM2STATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 \ | 555 | XDG_STATE_HOME="$ZM2STATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 \ |
| 568 | --out "$OUT.zm2cap" --err "$OUT.zm2cap.err" -- \ | 556 | --out "$OUT.zm2cap" --err "$OUT.zm2cap.err" -- \ |
| 569 | "$MUX" --sock "$SOCK42" > "$OUT.zm2pc" 2>&1 <<'EOF' | 557 | "$MUX" --sock "$SOCK42" > "$OUT.zm2pc" 2>&1 <<'EOF' |
test/e2e_11_select.sh
| Old | New | ||
|---|---|---|---|
| @@ -56,11 +56,7 @@ wait_grid "$SOCK50" "wmb-pin" "wall cluster: session b's marker" b | |||
| 56 | # other way. A negative that cannot fail is not a test, so each carries the | 56 | # other way. A negative that cannot fail is not a test, so each carries the |
| 57 | # marker that MUST land in the focused session. | 57 | # marker that MUST land in the focused session. |
| 58 | set +e | 58 | set +e |
| 59 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 59 | no_saved_tree "$WMSTATE" |
| 60 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 61 | # state home has already left one. The aspect rule applies only when | ||
| 62 | # nothing is saved. | ||
| 63 | rm -f "$WMSTATE/mux/layout" | ||
| 64 | XDG_STATE_HOME="$WMSTATE" timeout 60 "$PTYCLIENT" --cols 40 --rows 30 \ | 60 | XDG_STATE_HOME="$WMSTATE" timeout 60 "$PTYCLIENT" --cols 40 --rows 30 \ |
| 65 | --out "$OUT.wmcap3" --err "$OUT.wmcap3.err" -- \ | 61 | --out "$OUT.wmcap3" --err "$OUT.wmcap3.err" -- \ |
| 66 | "$MUX" --sock "$SOCK50" > "$OUT.wmpc3" 2>&1 <<'EOF' | 62 | "$MUX" --sock "$SOCK50" > "$OUT.wmpc3" 2>&1 <<'EOF' |
| @@ -91,11 +87,7 @@ grep -q "wm-three" "$OUT.wmfa" && { | |||
| 91 | # The other direction: focus b explicitly, then click a's content and watch | 87 | # The other direction: focus b explicitly, then click a's content and watch |
| 92 | # the focus come back to a. | 88 | # the focus come back to a. |
| 93 | set +e | 89 | set +e |
| 94 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 90 | no_saved_tree "$WMSTATE" |
| 95 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 96 | # state home has already left one. The aspect rule applies only when | ||
| 97 | # nothing is saved. | ||
| 98 | rm -f "$WMSTATE/mux/layout" | ||
| 99 | XDG_STATE_HOME="$WMSTATE" timeout 60 "$PTYCLIENT" --cols 40 --rows 30 \ | 91 | XDG_STATE_HOME="$WMSTATE" timeout 60 "$PTYCLIENT" --cols 40 --rows 30 \ |
| 100 | --out "$OUT.wmcap4" --err "$OUT.wmcap4.err" -- \ | 92 | --out "$OUT.wmcap4" --err "$OUT.wmcap4.err" -- \ |
| 101 | "$MUX" --sock "$SOCK50" > "$OUT.wmpc4" 2>&1 <<'EOF' | 93 | "$MUX" --sock "$SOCK50" > "$OUT.wmpc4" 2>&1 <<'EOF' |
| @@ -132,11 +124,7 @@ ok "a click in a tile's rect focuses it, from wherever the focus was" | |||
| 132 | # test in rectHit earns its keep: focus starts on a (the left pane) and | 124 | # test in rectHit earns its keep: focus starts on a (the left pane) and |
| 133 | # the click must move it to b (the right pane). | 125 | # the click must move it to b (the right pane). |
| 134 | set +e | 126 | set +e |
| 135 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 127 | no_saved_tree "$WMSTATE" |
| 136 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 137 | # state home has already left one. The aspect rule applies only when | ||
| 138 | # nothing is saved. | ||
| 139 | rm -f "$WMSTATE/mux/layout" | ||
| 140 | XDG_STATE_HOME="$WMSTATE" timeout 60 "$PTYCLIENT" --cols 100 --rows 30 \ | 128 | XDG_STATE_HOME="$WMSTATE" timeout 60 "$PTYCLIENT" --cols 100 --rows 30 \ |
| 141 | --out "$OUT.wmcap5" --err "$OUT.wmcap5.err" -- \ | 129 | --out "$OUT.wmcap5" --err "$OUT.wmcap5.err" -- \ |
| 142 | "$MUX" --sock "$SOCK50" > "$OUT.wmpc5" 2>&1 <<'EOF' | 130 | "$MUX" --sock "$SOCK50" > "$OUT.wmpc5" 2>&1 <<'EOF' |
test/e2e_12_panes.sh
| Old | New | ||
|---|---|---|---|
| @@ -80,11 +80,7 @@ pipe_detach | |||
| 80 | wait_grid "$SOCK52" "mc-pin" "cursor: session c's marker" c | 80 | wait_grid "$SOCK52" "mc-pin" "cursor: session c's marker" c |
| 81 | 81 | ||
| 82 | set +e | 82 | set +e |
| 83 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 83 | no_saved_tree "$CUSTATE" |
| 84 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 85 | # state home has already left one. The aspect rule applies only when | ||
| 86 | # nothing is saved. | ||
| 87 | rm -f "$CUSTATE/mux/layout" | ||
| 88 | XDG_STATE_HOME="$CUSTATE" timeout 40 "$PTYCLIENT" --cols 40 --rows 30 --out "$OUT.cucap" --err "$OUT.cucap.err" -- \ | 84 | XDG_STATE_HOME="$CUSTATE" timeout 40 "$PTYCLIENT" --cols 40 --rows 30 --out "$OUT.cucap" --err "$OUT.cucap.err" -- \ |
| 89 | "$MUX" --sock "$SOCK52" > "$OUT.cupc" 2>&1 <<'EOF' | 85 | "$MUX" --sock "$SOCK52" > "$OUT.cupc" 2>&1 <<'EOF' |
| 90 | expect mc-pin 20000 | 86 | expect mc-pin 20000 |
| @@ -173,11 +169,7 @@ pipe_detach | |||
| 173 | wait_grid "$SOCK53" "sb2nbr" "scrollback-rect: session b's pin" b | 169 | wait_grid "$SOCK53" "sb2nbr" "scrollback-rect: session b's pin" b |
| 174 | 170 | ||
| 175 | set +e | 171 | set +e |
| 176 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 172 | no_saved_tree "$SB2STATE" |
| 177 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 178 | # state home has already left one. The aspect rule applies only when | ||
| 179 | # nothing is saved. | ||
| 180 | rm -f "$SB2STATE/mux/layout" | ||
| 181 | XDG_STATE_HOME="$SB2STATE" timeout 90 "$PTYCLIENT" --cols 40 --rows 30 --out "$OUT.sb2cap" --err "$OUT.sb2cap.err" -- \ | 173 | XDG_STATE_HOME="$SB2STATE" timeout 90 "$PTYCLIENT" --cols 40 --rows 30 --out "$OUT.sb2cap" --err "$OUT.sb2cap.err" -- \ |
| 182 | "$MUX" --sock "$SOCK53" > "$OUT.sb2pc" 2>&1 <<'EOF' | 174 | "$MUX" --sock "$SOCK53" > "$OUT.sb2pc" 2>&1 <<'EOF' |
| 183 | expect sb2nbr 20000 | 175 | expect sb2nbr 20000 |
| @@ -236,11 +228,7 @@ wait_grid "$SOCK54" "fs-init-b" "fullscreen: session b's marker" b | |||
| 236 | 228 | ||
| 237 | set +e | 229 | set +e |
| 238 | # wide: 80x24 trips the aspect rule (80 >= 48 → beside) | 230 | # wide: 80x24 trips the aspect rule (80 >= 48 → beside) |
| 239 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 231 | no_saved_tree "$FSSTATE" |
| 240 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 241 | # state home has already left one. The aspect rule applies only when | ||
| 242 | # nothing is saved. | ||
| 243 | rm -f "$FSSTATE/mux/layout" | ||
| 244 | XDG_STATE_HOME="$FSSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 --out "$OUT.fscap" --err "$OUT.fscap.err" -- \ | 232 | XDG_STATE_HOME="$FSSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 --out "$OUT.fscap" --err "$OUT.fscap.err" -- \ |
| 245 | "$MUX" --sock "$SOCK54" > "$OUT.fspc" 2>&1 <<'EOF' | 233 | "$MUX" --sock "$SOCK54" > "$OUT.fspc" 2>&1 <<'EOF' |
| 246 | expect fs-init-b 20000 | 234 | expect fs-init-b 20000 |
| @@ -328,11 +316,7 @@ set +e | |||
| 328 | # 80x24: aspect rule makes beside; two panes split 39/40 with the rail | 316 | # 80x24: aspect rule makes beside; two panes split 39/40 with the rail |
| 329 | # at column 40 (1-indexed). Three l presses grow the left pane by 3, | 317 | # at column 40 (1-indexed). Three l presses grow the left pane by 3, |
| 330 | # moving the rail to column 43. | 318 | # moving the rail to column 43. |
| 331 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 319 | no_saved_tree "$RSZSTATE" |
| 332 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 333 | # state home has already left one. The aspect rule applies only when | ||
| 334 | # nothing is saved. | ||
| 335 | rm -f "$RSZSTATE/mux/layout" | ||
| 336 | XDG_STATE_HOME="$RSZSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 --out "$OUT.rszcap" --err "$OUT.rszcap.err" -- \ | 320 | XDG_STATE_HOME="$RSZSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 --out "$OUT.rszcap" --err "$OUT.rszcap.err" -- \ |
| 337 | "$MUX" --sock "$SOCK55" > "$OUT.rszpc" 2>&1 <<'EOF' | 321 | "$MUX" --sock "$SOCK55" > "$OUT.rszpc" 2>&1 <<'EOF' |
| 338 | expect rsz-init-b 20000 | 322 | expect rsz-init-b 20000 |
| @@ -361,12 +345,9 @@ set -e | |||
| 361 | # The rail paints as ESC[row;colH followed by ESC[7m (reverse video). | 345 | # The rail paints as ESC[row;colH followed by ESC[7m (reverse video). |
| 362 | # Extract the column from every CUP that precedes a reverse-video | 346 | # Extract the column from every CUP that precedes a reverse-video |
| 363 | # space — the rail's column — and verify it moved right by 3. | 347 | # space — the rail's column — and verify it moved right by 3. |
| 364 | _rail_re=$'\x1b\\[[0-9][0-9]*;[0-9][0-9]*H\x1b\\[7m' | ||
| 365 | # Before resize: rail at column 40 (1-indexed). After lll: column 43. | 348 | # Before resize: rail at column 40 (1-indexed). After lll: column 43. |
| 366 | # Grab all rail CUP columns; the last one is the post-resize position. | 349 | # All rail columns; the last one is the post-resize position. |
| 367 | _rail_cols=$(grep -ao "$_rail_re" "$OUT.rszcap" | \ | 350 | _last_rail=$(rail_cols "$OUT.rszcap" | tail -1) |
| 368 | sed 's/.*\x1b\[[0-9]*;\([0-9]*\)H\x1b\[7m/\1/' | sort -n) | ||
| 369 | _last_rail=$(echo "$_rail_cols" | tail -1) | ||
| 370 | [ -n "$_last_rail" ] || { | 351 | [ -n "$_last_rail" ] || { |
| 371 | echo "e2e FAIL: resize: no rail glyph found in the capture:" | 352 | echo "e2e FAIL: resize: no rail glyph found in the capture:" |
| 372 | cat "$OUT.rszcap"; exit 1; } | 353 | cat "$OUT.rszcap"; exit 1; } |
| @@ -411,11 +392,7 @@ wait_grid "$SOCK56" "spc-right-survivor" "span-clear: right session's marker" b | |||
| 411 | set +e | 392 | set +e |
| 412 | # 80x24: aspect rule → beside. The wall client is a tty session: its | 393 | # 80x24: aspect rule → beside. The wall client is a tty session: its |
| 413 | # stdout is the terminal's full byte stream, captured by ptyclient. | 394 | # stdout is the terminal's full byte stream, captured by ptyclient. |
| 414 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 395 | no_saved_tree "$SPCSTATE" |
| 415 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 416 | # state home has already left one. The aspect rule applies only when | ||
| 417 | # nothing is saved. | ||
| 418 | rm -f "$SPCSTATE/mux/layout" | ||
| 419 | XDG_STATE_HOME="$SPCSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 --out "$OUT.spccap" --err "$OUT.spccap.err" -- \ | 396 | XDG_STATE_HOME="$SPCSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 --out "$OUT.spccap" --err "$OUT.spccap.err" -- \ |
| 420 | "$MUX" --sock "$SOCK56" > "$OUT.spcpc" 2>&1 <<'EOF' | 397 | "$MUX" --sock "$SOCK56" > "$OUT.spcpc" 2>&1 <<'EOF' |
| 421 | expect spc-right-survivor 20000 | 398 | expect spc-right-survivor 20000 |
| @@ -468,11 +445,7 @@ wait_grid "$SOCK57" "hjk-origin" "hjkl: origin marker" | |||
| 468 | set +e | 445 | set +e |
| 469 | # 80x24: aspect rule → beside for the first split; the second split goes | 446 | # 80x24: aspect rule → beside for the first split; the second split goes |
| 470 | # below, producing a 1 | (2 over 3) tree. | 447 | # below, producing a 1 | (2 over 3) tree. |
| 471 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 448 | no_saved_tree "$HJKSTATE" |
| 472 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 473 | # state home has already left one. The aspect rule applies only when | ||
| 474 | # nothing is saved. | ||
| 475 | rm -f "$HJKSTATE/mux/layout" | ||
| 476 | XDG_STATE_HOME="$HJKSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 --out "$OUT.hjkcap" --err "$OUT.hjkcap.err" -- \ | 449 | XDG_STATE_HOME="$HJKSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 --out "$OUT.hjkcap" --err "$OUT.hjkcap.err" -- \ |
| 477 | "$MUX" --sock "$SOCK57" > "$OUT.hjkpc" 2>&1 <<'EOF' | 450 | "$MUX" --sock "$SOCK57" > "$OUT.hjkpc" 2>&1 <<'EOF' |
| 478 | expect hjk-origin 20000 | 451 | expect hjk-origin 20000 |
| @@ -543,11 +516,7 @@ wait_grid "$SOCK58" "spl-origin" "split-birth: origin marker" | |||
| 543 | set +e | 516 | set +e |
| 544 | # 80x24: aspect rule → beside. One tile starts, then Ctrl-\ | births a | 517 | # 80x24: aspect rule → beside. One tile starts, then Ctrl-\ | births a |
| 545 | # second session to the right. | 518 | # second session to the right. |
| 546 | # No saved tree: this leg asserts the DEFAULT cut, and a wall ON A | 519 | no_saved_tree "$SPLSTATE" |
| 547 | # TERMINAL saves its tree on the way out — so a ptyclient leg sharing this | ||
| 548 | # state home has already left one. The aspect rule applies only when | ||
| 549 | # nothing is saved. | ||
| 550 | rm -f "$SPLSTATE/mux/layout" | ||
| 551 | XDG_STATE_HOME="$SPLSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 --out "$OUT.splcap" --err "$OUT.splcap.err" -- \ | 520 | XDG_STATE_HOME="$SPLSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 --out "$OUT.splcap" --err "$OUT.splcap.err" -- \ |
| 552 | "$MUX" --sock "$SOCK58" > "$OUT.splpc" 2>&1 <<'EOF' | 521 | "$MUX" --sock "$SOCK58" > "$OUT.splpc" 2>&1 <<'EOF' |
| 553 | expect spl-origin 20000 | 522 | expect spl-origin 20000 |
| @@ -568,9 +537,7 @@ wait_sessions "$SOCK58" 2 "split-birth: split did not birth a new session" | |||
| 568 | # The rail paints as ESC[row;colH ESC[7m (reverse video). The new pane's | 537 | # The rail paints as ESC[row;colH ESC[7m (reverse video). The new pane's |
| 569 | # label bar is at a column greater than the rail's column — it sits to | 538 | # label bar is at a column greater than the rail's column — it sits to |
| 570 | # the right of the separator, which is the whole point of beside. | 539 | # the right of the separator, which is the whole point of beside. |
| 571 | _rail_re=$'\x1b\\[[0-9][0-9]*;[0-9][0-9]*H\x1b\\[7m' | 540 | _rail_col=$(rail_cols "$OUT.splcap" | head -1) |
| 572 | _rail_col=$(grep -ao "$_rail_re" "$OUT.splcap" | \ | ||
| 573 | sed 's/.*\x1b\[[0-9]*;\([0-9]*\)H\x1b\[7m/\1/' | sort -n | head -1) | ||
| 574 | [ -n "$_rail_col" ] || { | 541 | [ -n "$_rail_col" ] || { |
| 575 | echo "e2e FAIL: split-birth: no rail glyph found in the capture:" | 542 | echo "e2e FAIL: split-birth: no rail glyph found in the capture:" |
| 576 | cat "$OUT.splcap"; exit 1; } | 543 | cat "$OUT.splcap"; exit 1; } |
| @@ -619,7 +586,7 @@ mkdir -p "$LPSTATE/mux" | |||
| 619 | printf -- '--sock %s\n' "$SOCK59" > "$LPHOSTS" | 586 | printf -- '--sock %s\n' "$SOCK59" > "$LPHOSTS" |
| 620 | # ...and no saved tree yet: what this leg saves and restores has to be the | 587 | # ...and no saved tree yet: what this leg saves and restores has to be the |
| 621 | # tree the FIRST ptyclient builds, not one an earlier terminal left here. | 588 | # tree the FIRST ptyclient builds, not one an earlier terminal left here. |
| 622 | rm -f "$LPLAYOUT" | 589 | no_saved_tree "$LPSTATE" |
| 623 | 590 | ||
| 624 | set +e | 591 | set +e |
| 625 | # First ptyclient: hydrate, resize three right, detach. The detach saves | 592 | # First ptyclient: hydrate, resize three right, detach. The detach saves |
| @@ -690,11 +657,8 @@ set -e | |||
| 690 | echo "e2e FAIL: layout-restore: second ptyclient exited $RC:" | 657 | echo "e2e FAIL: layout-restore: second ptyclient exited $RC:" |
| 691 | cat "$OUT.lprpc2" "$OUT.lprcap2.err"; exit 1; } | 658 | cat "$OUT.lprpc2" "$OUT.lprcap2.err"; exit 1; } |
| 692 | # The rail's CUP column in the second capture must be >= 43 — three | 659 | # The rail's CUP column in the second capture must be >= 43 — three |
| 693 | # right-resizes moved the boundary from 41 to 44. The _rail_re idiom | 660 | # right-resizes moved the boundary from 41 to 44. |
| 694 | # (from the split-birth leg) matches ESC[row;colH ESC[7m. | 661 | _max_rail=$(rail_cols "$OUT.lprcap2" | tail -1) |
| 695 | _rail_re=$'\x1b\\[[0-9][0-9]*;[0-9][0-9]*H\x1b\\[7m' | ||
| 696 | _max_rail=$(grep -ao "$_rail_re" "$OUT.lprcap2" | \ | ||
| 697 | sed 's/.*\x1b\[[0-9]*;\([0-9]*\)H\x1b\[7m/\1/' | sort -n | tail -1) | ||
| 698 | [ -n "$_max_rail" ] || { | 662 | [ -n "$_max_rail" ] || { |
| 699 | echo "e2e FAIL: layout-restore: no rail glyph in the second capture:" | 663 | echo "e2e FAIL: layout-restore: no rail glyph in the second capture:" |
| 700 | cat "$OUT.lprcap2"; exit 1; } | 664 | cat "$OUT.lprcap2"; exit 1; } |
| @@ -747,7 +711,7 @@ wait_grid "$SOCK60" "lph-doomed-b" "layout-heal: session b marker" b | |||
| 747 | mkdir -p "$LPHSTATE/mux" | 711 | mkdir -p "$LPHSTATE/mux" |
| 748 | printf -- '--sock %s\n' "$SOCK60" > "$LPHHOSTS" | 712 | printf -- '--sock %s\n' "$SOCK60" > "$LPHHOSTS" |
| 749 | # No saved tree yet, for the restore leg's reason. | 713 | # No saved tree yet, for the restore leg's reason. |
| 750 | rm -f "$LPHLAYOUT" | 714 | no_saved_tree "$LPHSTATE" |
| 751 | 715 | ||
| 752 | set +e | 716 | set +e |
| 753 | XDG_STATE_HOME="$LPHSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 \ | 717 | XDG_STATE_HOME="$LPHSTATE" timeout 90 "$PTYCLIENT" --cols 80 --rows 24 \ |
| @@ -845,18 +809,12 @@ grep -qi "layout" "$OUT.lphcap2.err" && { | |||
| 845 | # Two tiles: the survivor and the newcomer. The daemon has 0 and c, and | 809 | # Two tiles: the survivor and the newcomer. The daemon has 0 and c, and |
| 846 | # the tile the sidecar's surviving leaf carries is the one the marker | 810 | # the tile the sidecar's surviving leaf carries is the one the marker |
| 847 | # landed in. | 811 | # landed in. |
| 848 | # A rail is a CUP followed by reverse video; a BESIDE cut puts one in a | 812 | # A BESIDE cut puts a rail in a column of its own; a stacked cut has one |
| 849 | # column of its own, a stacked cut only ever at column 1 (the label bars). | 813 | # only at column 1, which is a label bar and what `rail_cols`' callers |
| 850 | # Spelled here rather than leaning on the earlier legs' copy: a variable | 814 | # filter out. |
| 851 | # an unrelated block happens to have left set is not an input. | ||
| 852 | _lph_re=$'\x1b\\[[0-9][0-9]*;[0-9][0-9]*H\x1b\\[7m' | ||
| 853 | _lph_cols() { | ||
| 854 | grep -ao "$_lph_re" "$1" | \ | ||
| 855 | sed 's/.*\x1b\[[0-9]*;\([0-9]*\)H\x1b\[7m/\1/' | sort -n | uniq | ||
| 856 | } | ||
| 857 | # Run 1 is the anchor: it really was cut beside and `lll` really moved the | 815 | # Run 1 is the anchor: it really was cut beside and `lll` really moved the |
| 858 | # rail, so run 2's silence below is a difference and not an empty capture. | 816 | # rail, so run 2's silence below is a difference and not an empty capture. |
| 859 | _lph_r1=$(_lph_cols "$OUT.lphcap1" | awk '$1 > 1' | tail -1) | 817 | _lph_r1=$(rail_cols "$OUT.lphcap1" | awk '$1 > 1' | tail -1) |
| 860 | [ -n "$_lph_r1" ] && [ "$_lph_r1" -ge 43 ] || { | 818 | [ -n "$_lph_r1" ] && [ "$_lph_r1" -ge 43 ] || { |
| 861 | echo "e2e FAIL: layout-heal: run 1's rail ended at column ${_lph_r1:-none}, want >= 43" | 819 | echo "e2e FAIL: layout-heal: run 1's rail ended at column ${_lph_r1:-none}, want >= 43" |
| 862 | echo " — the resize this leg saves a tree for did not happen" | 820 | echo " — the resize this leg saves a tree for did not happen" |
| @@ -874,7 +832,7 @@ _lph_r1=$(_lph_cols "$OUT.lphcap1" | awk '$1 > 1' | tail -1) | |||
| 874 | # and that is the one answer neither of those can produce. Asserting "no | 832 | # and that is the one answer neither of those can produce. Asserting "no |
| 875 | # rail at all" instead would fail the improvement and blame the restore for | 833 | # rail at all" instead would fail the improvement and blame the restore for |
| 876 | # not having run, which is the opposite of what would have happened. | 834 | # not having run, which is the opposite of what would have happened. |
| 877 | _lph_r2=$(_lph_cols "$OUT.lphcap2" | awk '$1 > 1' | tail -1) | 835 | _lph_r2=$(rail_cols "$OUT.lphcap2" | awk '$1 > 1' | tail -1) |
| 878 | [ -z "$_lph_r2" ] || [ "$_lph_r2" -ge 43 ] || { | 836 | [ -z "$_lph_r2" ] || [ "$_lph_r2" -ge 43 ] || { |
| 879 | echo "e2e FAIL: layout-heal: run 2's vertical rail is at column $_lph_r2 — neither" | 837 | echo "e2e FAIL: layout-heal: run 2's vertical rail is at column $_lph_r2 — neither" |
| 880 | echo " the sidecar's own cut (>= 43, where run 1 left it) nor the bare" | 838 | echo " the sidecar's own cut (>= 43, where run 1 left it) nor the bare" |
test/e2e_13_birth.sh
| Old | New | ||
|---|---|---|---|
| @@ -95,9 +95,7 @@ wait_grid "$SOCK63" "pr-bmark" "prompt: daemon B's marker" | |||
| 95 | 95 | ||
| 96 | mkdir -p "$PRSTATE/mux" | 96 | mkdir -p "$PRSTATE/mux" |
| 97 | printf -- '--sock %s\n' "$SOCK62" > "$PRHOSTS" | 97 | printf -- '--sock %s\n' "$SOCK62" > "$PRHOSTS" |
| 98 | # No saved tree: a wall on a terminal saves its tree on the way out, and | 98 | no_saved_tree "$PRSTATE" |
| 99 | # this leg asserts the default cut. | ||
| 100 | rm -f "$PRSTATE/mux/layout" | ||
| 101 | 99 | ||
| 102 | # The spelling goes in TWO sends with a settle between: the prompt paints | 100 | # The spelling goes in TWO sends with a settle between: the prompt paints |
| 103 | # its echo when a read ENDS with the prompt still open, so a spelling that | 101 | # its echo when a read ENDS with the prompt still open, so a spelling that |
test/e2e_lib.sh
| Old | New | ||
|---|---|---|---|
| @@ -464,6 +464,32 @@ repaints() { | |||
| 464 | grep -a -F -o "$_clr" "$1" 2>/dev/null | wc -l | 464 | grep -a -F -o "$_clr" "$1" 2>/dev/null | wc -l |
| 465 | } | 465 | } |
| 466 | 466 | ||
| 467 | # rail_cols FILE — the column of every vertical rail in a capture, | ||
| 468 | # ascending and deduplicated. A rail paints as a CUP followed by reverse | ||
| 469 | # video, which is how a label bar starts too, so column 1 is a bar and | ||
| 470 | # never a rail; a caller that cares filters it (`awk '$1 > 1'`). | ||
| 471 | # | ||
| 472 | # Here rather than in the four legs that had spelled it out: an escape | ||
| 473 | # sequence copied per leg is four places a terminal change has to be found, | ||
| 474 | # and a function is hermetic in the way the `_rail_re` variable those | ||
| 475 | # copies shared a name for was not. | ||
| 476 | rail_cols() { | ||
| 477 | grep -ao $'\x1b\\[[0-9][0-9]*;[0-9][0-9]*H\x1b\\[7m' "$1" | | ||
| 478 | sed 's/.*\x1b\[[0-9]*;\([0-9]*\)H\x1b\[7m/\1/' | sort -n | uniq | ||
| 479 | } | ||
| 480 | |||
| 481 | # no_saved_tree STATE — forget the layout sidecar under STATE. | ||
| 482 | # | ||
| 483 | # A wall on a TERMINAL saves its pane tree on the way out and restore is | ||
| 484 | # VERBATIM, so a leg that asserts the default cut must not inherit the tree | ||
| 485 | # an earlier ptyclient run left behind. Whether any run has actually shared | ||
| 486 | # this home is not the caller's to know: legs move, homes get reused, and | ||
| 487 | # the failure — a wall cut by somebody else's resize — reads as this leg's | ||
| 488 | # geometry assertion being wrong. | ||
| 489 | no_saved_tree() { | ||
| 490 | rm -f "$1/mux/layout" | ||
| 491 | } | ||
| 492 | |||
| 467 | # await_repaint FILE BASELINE LABEL — wait until repaints FILE exceeds | 493 | # await_repaint FILE BASELINE LABEL — wait until repaints FILE exceeds |
| 468 | # BASELINE (5s, scaled), FAIL with the capture otherwise. | 494 | # BASELINE (5s, scaled), FAIL with the capture otherwise. |
| 469 | await_repaint() { | 495 | await_repaint() { |