aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-29 18:12:28 +0100
committereunhhu <[email protected]>2026-09-29 18:12:28 +0100
commit461714a01549841746b721d38441df21f74a4077 (patch)
tree1260c5ddc04d841474667e7c0d46da236946647e /tests
parentc919b5f81ad6cad55935fa7a22bfda9539dd584f (diff)
downloadvega-461714a01549841746b721d38441df21f74a4077.tar.gz
vega-461714a01549841746b721d38441df21f74a4077.zip
Keep a key cut across the terminal's reads until it comes whole
handle_input found escape sequences only whole within one read, so an arrow whose ESC [ came in one read and its A in the next was Escape, [ and A (Pure's review 004, F5); a UTF-8 character cut the same way went in pieces. A read's bytes are not the terminal's keys: now an escape sequence, a mouse report or a character cut short waits for the next read. An escape alone that nothing follows within 100 ms (vim's ttimeoutlen) is the Escape key; the rest of a key already begun waits up to a second. check.py's interactive runs a third session with every key coming a byte at a time, 50 ms apart, and the arrow's A 150 ms after its ESC [: the focus moves, as when keys come whole; Vega before this marks the wrong task done.
Diffstat (limited to 'tests')
-rw-r--r--tests/check.py22
1 files changed, 18 insertions, 4 deletions
diff --git a/tests/check.py b/tests/check.py
index efe5027..b556b3a 100644
--- a/tests/check.py
+++ b/tests/check.py
@@ -801,11 +801,15 @@ def scores(vega, module):
return len(out)
-def interactive(vega, module, store=None, replace=None):
+def interactive(vega, module, store=None, replace=None, cut=False):
"""The terminal surface on a real pseudo-terminal: typed text commits
with Enter, arrow keys and letters reach the app after Tab, Ctrl-C leaves
and restores the terminal. With replace, it runs with --watch and replace
- is then written over module: the terminal shows it, with the same tasks."""
+ is then written over module: the terminal shows it, with the same tasks.
+ With cut, every key comes a byte at a time, 50 ms apart, and an arrow's
+ escape sequence 150 ms after its first two bytes: the terminal's reads
+ are not its keys (a UTF-8 character or a sequence cut short waits for
+ its rest)."""
import fcntl, pty, select, struct, termios, time
pid, fd = pty.fork()
if pid == 0:
@@ -827,7 +831,16 @@ def interactive(vega, module, store=None, replace=None):
screen = read_for(0.3)
# Then a click on line 5 (béton's row): a mouse report, press and release.
for keys in (b'milk\r', 'b\u00e9ton\r'.encode(), b'\t', b'\x1b[A', b' ', b'u', b'\x1b[<0;3;5M\x1b[<0;3;5m'):
- os.write(fd, keys)
+ if not cut:
+ os.write(fd, keys)
+ elif keys == b'\x1b[A':
+ os.write(fd, keys[:2])
+ screen += read_for(0.15)
+ os.write(fd, keys[2:])
+ else:
+ for k in range(len(keys)):
+ os.write(fd, keys[k:k + 1])
+ screen += read_for(0.05)
screen += read_for(0.2)
if replace:
shutil.copy(replace, module.with_suffix('.tmp'))
@@ -1723,7 +1736,8 @@ def main():
report['web_screens'] = web(vega, modules['todo'], work, range(args.seeds))
report['browser_steps'] = browser(vega, modules['todo'], work)
report['interactive_sessions'] = interactive(vega, modules['todo']) + \
- interactive(vega, modules['todo'], work / 'interactive-store')
+ interactive(vega, modules['todo'], work / 'interactive-store') + \
+ interactive(vega, modules['todo'], cut=True)
report['stored_surface_lines'] = stored_surfaces(vega, modules['todo'], work, range(args.seeds))
report['hangul'] = hangul(vega, modules['todo'])
report['convention_findings'] = conventions(vega, aup, work, modules)