scripts/test-micromanager-settings.py
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env python3
"""Exercise the actual crossterm editor in an isolated POSIX PTY."""
import argparse
import errno
import fcntl
import json
import os
import pty
import select
import struct
import subprocess
import tempfile
import termios
import time
from pathlib import Path
parser = argparse.ArgumentParser()
parser.add_argument('--test-binary', required=True, type=Path)
args = parser.parse_args()
with tempfile.TemporaryDirectory(prefix='firecrab-settings-') as directory:
def session(keys, expected):
master, slave = pty.openpty()
original = termios.tcgetattr(slave)
fcntl.ioctl(slave, termios.TIOCSWINSZ, struct.pack('HHHH', 28, 80, 0, 0))
env = dict(os.environ, FIRECRAB_TUI_TEST_HOME=directory)
process = subprocess.Popen([
str(args.test_binary.resolve()), '--exact',
'micromanager::settings_tui::tests::interactive_terminal', '--ignored', '--nocapture'
], stdin=slave, stdout=slave, stderr=slave, env=env)
output = bytearray()
def until(needle):
deadline = time.monotonic() + 10
while needle not in output:
assert time.monotonic() < deadline, output.decode(errors='replace')
ready, _, _ = select.select([master], [], [], 0.1)
if ready:
try:
chunk = os.read(master, 65536)
except OSError as error:
if error.errno == errno.EIO:
break
raise
if not chunk:
break
output.extend(chunk)
assert needle in output, output.decode(errors='replace')
try:
until(b'microManager settings')
# Resize uses the real event loop; the editor remains usable.
fcntl.ioctl(slave, termios.TIOCSWINSZ, struct.pack('HHHH', 30, 96, 0, 0))
os.write(master, keys)
until(expected)
if b'Unsaved' in expected:
os.write(master, b'y')
else:
os.write(master, b'\x1b')
assert process.wait(timeout=10) == 0
assert termios.tcgetattr(slave) == original, 'raw terminal mode leaked after exit'
finally:
if process.poll() is None:
process.kill()
process.wait()
os.close(master)
os.close(slave)
session(b'\r4\r\x13', b'Saved.')
path = Path(directory) / 'settings.json'
assert json.loads(path.read_text())['cpu'] == 4
previous = path.read_bytes()
session(b'\r8\r\x1b', b'Unsaved changes.')
assert path.read_bytes() == previous, 'discard wrote an unsaved draft'
print('PASS: keyboard edit/save, resize, discard, atomic persistence, terminal cleanup')