diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-11 12:38:56 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-09-15 17:24:42 -0300 |
| commit | 682e237df7e8b22f820d14a4adee58e6e2f84268 (patch) | |
| tree | 5d888cb46f1a49e89fc55e2a4c232d3af0265b1d /test/collapse_layout.py | |
| parent | 6878e1c309172d624c0d7a3555f6f0217ae6770e (diff) | |
| download | pardes-682e237df7e8b22f820d14a4adee58e6e2f84268.tar.gz pardes-682e237df7e8b22f820d14a4adee58e6e2f84268.zip | |
trunk: resume before the Reload experiment
Empty marker on the last pre-Reload change. Keep the Reload experiment on reload (3801914), its first change on reload-start (200a1fc), and the unfinished performance investigation on reload-perf-wip.
Diffstat (limited to 'test/collapse_layout.py')
| -rw-r--r-- | test/collapse_layout.py | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/test/collapse_layout.py b/test/collapse_layout.py new file mode 100644 index 00000000..e549bd37 --- /dev/null +++ b/test/collapse_layout.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +"""Check local Collapse height transfers through an owned SDL or TTY 9P session. + +python3 -B test/collapse_layout.py zig-out/column-review/bin/pardes-gui +python3 -B test/collapse_layout.py zig-out/column-review/bin/pardes --tty + +Measures tagline boundaries in the rendered core grid, not host pixel geometry. +No user session is contacted, and all fixture files live in a temporary directory. +""" +import argparse +from pathlib import Path +import tempfile + +from fs import new_pane, session +from ui_review import panes, require, wait_for + + +def geometry(client, names): + frame = client.screen() + rows = [''.join(cell[0] for cell in frame['cells'][row * frame['cols']:(row + 1) * frame['cols']]) + for row in range(frame['rows'])] + starts = [next((row for row, text in enumerate(rows) if '/' + name + ' ' in text), None) + for name in names] + if any(row is None for row in starts) or starts != sorted(set(starts)): + return None + ends = starts[1:] + [frame['rows']] + return tuple((start, end - start) for start, end in zip(starts, ends)) + + +def toggle(client, serial): + """Execute the default tag's Collapse word without changing any body or tag.""" + pane = f'/self/pane/{serial}' + tag = client.read(pane + '/tag') + at = tag.rfind(b' Collapse') + require(at >= 0, 'default pane tag lacks Collapse') + at += 1 + client.write(pane + '/event', f'Mx{at} {at + len("Collapse")}\n'.encode()) + + +def run(args): + binary = str(args.binary.resolve()) + with tempfile.TemporaryDirectory(prefix='pardes-collapse-') as directory: + root = Path(directory) + name = 'collapse-layout' + inherited = {} if args.tty else { + 'PARDES_TEST': '1', 'PARDES_TEST_COLS': '120', 'PARDES_TEST_ROWS': '48', + 'PARDES_TEST_CAPTURE_DIR': str(root), + 'SDL_VIDEODRIVER': 'x11', + } + launch = ['-c', 'stty cols 120 rows 48; exec "$@"', name, binary, + '--9p=' + name, str(root / (name + '.txt'))] + with session('/bin/sh', root, name, socket_name=name, tty=True, + launch=launch, inherited=inherited) as (client, _): + serials = [next(iter(panes(client)))] + names = [f'collapse-{letter}' for letter in 'ABCD'] + contents = b'owned collapse fixture\n' * 60 + for index, label in enumerate(names): + if index: + serials.append(new_pane(client, b'')) + pane = f'/self/pane/{serials[index]}' + client.write(pane + '/ctl', ('name ' + label + '\n').encode()) + client.write(pane + '/body', contents, truncate=True) + original = require(wait_for(lambda: geometry(client, names)), 'four pane tags not visible') + require(all(height > 1 for _, height in original), f'fixture has no body room: {original}') + for target in [1, 3, 0, 2, 1, 3, 0]: + recipient = target - 1 if target else 1 + heights = [height for _, height in original] + heights[recipient] += heights[target] - 1 + heights[target] = 1 + expected = [] + row = original[0][0] + for height in heights: + expected.append((row, height)) + row += height + toggle(client, serials[target]) + require(wait_for(lambda: geometry(client, names) == tuple(expected)), + f'Collapse {names[target]} changed unrelated geometry: {geometry(client, names)} != {expected}') + for index in range(4): + if index not in [target, recipient]: + require(expected[index] == original[index], 'unrelated pane moved') + toggle(client, serials[target]) + require(wait_for(lambda: geometry(client, names) == original), + f'expansion did not restore original geometry: {geometry(client, names)}') + for serial in serials: + require(client.read(f'/self/pane/{serial}/body') == contents, 'Collapse changed pane contents') + require((root / (name + '.txt')).read_bytes() == b'initial\n', 'fixture source file changed') + print(f'{"TTY" if args.tty else "SDL"}: 7 local collapse/expand pairs, exact unrelated pane geometry, and content preservation passed') + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('binary', type=Path) + parser.add_argument('--tty', action='store_true') + run(parser.parse_args()) |
