test(vterm): write CRLF from the raw-mode probe

The diagnostic added in the previous commit answered the question on its
first macOS run:

    rendered prefix: 6/15 bytes ("VTERM_") — child text rendered only partially

So the child wrote and the host received part of the marker, but stripping
escapes did not rejoin the rest: other repainted cells sit between the two
pieces, not just cursor moves.

Six characters is exactly what fits before the right margin of this
session's 40-column child. The probe writes bare `\n`, and the supervisor's
PTY trampoline runs `stty raw`, which clears OPOST — so a lone `\n` moves
down without returning to column 1 and every line staircases five columns
right. After twenty lines the marker starts in the right margin, wraps
mid-word, and reaches the host as two pieces that no contiguous match can
join.

That also explains the intermittency: the wrap column depends on whether
pmacs has already resized the PTY from the requested 40 columns to the
window width, which races the child's first writes.

Write explicit carriage returns so every line returns to column 1 and the
markers start there. The fixture was wrong about its own line discipline;
the emulator was behaving correctly throughout.

The escape-stripped matching and the rendered-prefix diagnostic from the
previous commit are kept: they are what produced this answer, and they keep
the next such failure legible.

Test-only; no runtime code.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Levi Neuwirth 2026-07-24 14:02:25 -04:00
parent 8ef2fa0793
commit f77ff3074d
1 changed files with 12 additions and 2 deletions

View File

@ -735,12 +735,22 @@ fn real_tui_terminal_smoke_restores_host_after_output_input_resize_scroll_copy_a
" data = b''\n",
" while marker not in data:\n",
" data += os.read(0, 4096)\n",
// CRLF, not bare LF. The supervisor's PTY trampoline runs
// `stty raw`, which clears OPOST, so a lone `\n` moves DOWN
// without returning to column 1 and every line staircases five
// columns right. Against this session's 40-column child that
// walks the readiness marker into the right margin, where it
// wraps mid-word and reaches the host as two pieces separated by
// other repainted cells — unmatchable, and intermittent because
// the column depends on whether pmacs has resized the PTY to the
// window width yet. Explicit carriage returns keep every write
// column-stable, so the markers below start at column 1.
"os.write(1, b'\\x1b[?1049h\\x1b[2J')\n",
"for i in range(20): os.write(1, b'alt%02d\\n' % i)\n",
"for i in range(20): os.write(1, b'alt%02d\\r\\n' % i)\n",
"os.write(1, b'VTERM_ALT_READY')\n",
"read_until(b'ALT_GATE\\n')\n",
"os.write(1, b'\\x1b[?1049l')\n",
"for i in range(40): os.write(1, b'main%02d\\n' % i)\n",
"for i in range(40): os.write(1, b'main%02d\\r\\n' % i)\n",
"os.write(1, b'VTERM_MAIN_READY\\x07')\n",
"data = read_exact(18)\n",
"open({:?}, 'wb').write(data)\n",