summaryrefslogtreecommitdiff
path: root/test/tag_cleanup.py
blob: ae0a0e66f3cd3e04c401002162a54a09f3410b35 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#!/usr/bin/env python3
"""Check compact PDF tags and Mode cycling and Ctrl-B in an isolated 9P session."""
import argparse
from pathlib import Path

from fs import session, new_pane, execute
from column_tags import Input as HostInput
from ui_review import capture, panes, require, wait_for


def run(args):
    root = args.output.resolve()
    root.mkdir(parents=True, mode=0o700, exist_ok=True)
    root.chmod(0o700)
    name = 'tag-cleanup'
    binary = str(args.binary.resolve())
    source = Path('docs/design.pdf').resolve()
    original = source.read_bytes()
    inherited = {} if args.tty else {
        'PARDES_TEST': '1', 'PARDES_TEST_CAPTURE_DIR': str(root),
        'PARDES_TEST_COLS': '150', 'PARDES_TEST_ROWS': '48',
        'SDL_VIDEODRIVER': 'x11',
    }
    launch = ['-c', 'stty cols 150 rows 48; exec "$@"', name, binary,
              '--9p=' + name, str(source)]
    terminal = {}
    with session('/bin/sh', root, name, socket_name=name, tty=True,
                 launch=launch, inherited=inherited, terminal=terminal) as (client, _):
        keys = HostInput(terminal['input_fd'])
        pdf = next(serial for serial, tag in panes(client).items() if str(source) in tag)
        pdf_tag = client.read(f'/pane/{pdf}/tag').decode().strip()
        require(pdf_tag.startswith(str(source) + ' [1/'), 'PDF name/page prefix missing')
        require(pdf_tag.endswith('] Tty Del PdfSections PdfTint Collapse'), 'PDF commands missing')
        require(all(word not in pdf_tag for word in ['PdfFit', 'filtered', 'full', 'disabled']), 'PDF tag contains fit or tint-state clutter')
        control = new_pane(client, b'')
        before = set(panes(client))
        execute(client, control, 'Tty')
        tty = require(wait_for(lambda: next((s for s in panes(client) if s not in before), None)), 'terminal missing')
        client.write(f'/pane/{control}/exec', b'Del\n')  # owned command-only scratch

        def tag_position():
            frame = client.screen()
            for row in range(frame['rows']):
                text = ''.join(c[0] for c in frame['cells'][row * frame['cols']:(row + 1) * frame['cols']])
                if ' Mode Filter' in text:
                    return text.index(' Mode Filter') + 1, row, text[0]
            return None

        require(wait_for(lambda: (p := tag_position()) and p[2] == '$'), 'new terminal not in raw mode')
        x, y, _ = tag_position()
        keys.click(x, y, button=1)
        require(wait_for(lambda: (p := tag_position()) and p[2] == ' '), 'Mode click did not enter normal mode')
        for badge in ('^', '$'):
            x, y, _ = tag_position()
            keys.click(x, y, button=1)
            require(wait_for(lambda: (p := tag_position()) and p[2] == badge), 'Mode cycle did not reach ' + badge)
        x, y, _ = tag_position()
        keys.click(x, y, button=1)
        require(wait_for(lambda: (p := tag_position()) and p[2] == ' '), 'Mode did not return to normal')
        keys.send(b'\x02')
        require(wait_for(lambda: (p := tag_position()) and p[2] == '$'), 'Ctrl-B did not restore raw mode')
        x, y, _ = tag_position()
        keys.click(x, y)
        keys.send(b'\t')
        require(wait_for(lambda: (p := tag_position()) and p[2] == ' '), 'Mode from edited tag ignored parked raw mode')
        keys.send(b'\x02')
        client.write(f'/pane/{tty}/pty/data', b"printf 'Mode toggle ready\\n'\r")
        require(wait_for(lambda: b'Mode toggle ready' in client.read(f'/pane/{tty}/body')), 'terminal input failed')
        capture(client, root, 'pdf-and-tty-tags', not args.tty)
        require(source.read_bytes() == original, 'PDF file changed')
        client.write(f'/pane/{tty}/pty/data', b'exit\r')
    print('PDF tag, Mode click, Ctrl-B, edited-tag execution and source preservation passed')


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('binary', type=Path)
    parser.add_argument('output', type=Path)
    parser.add_argument('--tty', action='store_true')
    run(parser.parse_args())