summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-10-01 17:43:39 -0300
committerGabriel Schneider <[email protected]>2026-10-01 20:04:42 -0300
commit805b9f188768fee523d462411d846912e0877ff3 (patch)
treedc17de5cee6e4b554446052a29fd55e8a5285498 /test
parent0728b937028418232a1da3d9922615a6f49680f2 (diff)
downloadpardes-805b9f188768fee523d462411d846912e0877ff3.tar.gz
pardes-805b9f188768fee523d462411d846912e0877ff3.zip
Edit runs acme's file and shell commands: < | > through the session's Shell off the loop (one undo step, a failure changes nothing, its stderr in +Errors, a 9P write answered when done), X and Y over the open text panes, b B D e r f w and the "file" address; checked against sam -d, and the reference's Edit section and Coming from acme row say so
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'test')
-rw-r--r--test/fs.py59
1 files changed, 59 insertions, 0 deletions
diff --git a/test/fs.py b/test/fs.py
index 65b354d9..1303db0d 100644
--- a/test/fs.py
+++ b/test/fs.py
@@ -1008,9 +1008,68 @@ def cut_writes(binary):
assert (screen['cols'], screen['rows']) == (132, 40), (screen['cols'], screen['rows'])
+def edit_commands(binary):
+ """Edit's `< | >` run off the loop and answer the write that ran them
+ once applied; a failing one changes nothing and fails the write in its
+ words; X edits every open file it matches; w writes. The editor answers
+ other requests while a slow command runs."""
+ with tempfile.TemporaryDirectory(prefix='pardes-edit-') as directory:
+ root = Path(directory)
+ (root / 'a.txt').write_bytes(b'pear\napple\nfig\n')
+ (root / 'b.txt').write_bytes(b'apple pie\n')
+ with session(binary, root, 'edit') as (client, address):
+ a = look(client, str(root / 'a.txt'))
+ b = look(client, str(root / 'b.txt'))
+ # The write returns with the text sorted, through the session's
+ # shell in the file's directory.
+ client.write(f'/pane/{a}/ctl', b'Edit , | sort\n')
+ assert client.read(f'/pane/{a}/body') == b'apple\nfig\npear\n'
+ client.write(f'/pane/{a}/ctl', b'Edit $ < pwd\n')
+ assert client.read(f'/pane/{a}/body') == f'apple\nfig\npear\n{root}\n'.encode()
+ client.write(f'/pane/{a}/ctl', b'Undo\n')
+ assert client.read(f'/pane/{a}/body') == b'apple\nfig\npear\n'
+ # A per-match command, one undo step.
+ client.write(f'/pane/{a}/ctl', b'Edit ,x/[a-z]+/ | tr a-z A-Z\n')
+ assert client.read(f'/pane/{a}/body') == b'APPLE\nFIG\nPEAR\n'
+ # A failing command: nothing changed, the write fails in words,
+ # its stderr in +Errors.
+ try:
+ client.write(f'/pane/{a}/ctl', b'Edit , | echo nope >&2; exit 4\n')
+ raise AssertionError('a failing Edit command was taken')
+ except OSError as why:
+ assert 'exit status 4' in str(why), why
+ assert client.read(f'/pane/{a}/body') == b'APPLE\nFIG\nPEAR\n'
+ index = client.read('/index').decode()
+ errors = [line.split()[0] for line in index.splitlines() if line.endswith(('+Errors', f'{root}/+Errors')) or '+Errors' in line]
+ assert errors and any(b'nope' in client.read(f'/pane/{e}/body') for e in errors), index
+ # While a slow command runs, the editor answers.
+ done = threading.Event()
+
+ def slow():
+ with Client(address) as other:
+ other.write(f'/pane/{b}/ctl', b'Edit , | sleep 1; cat\n')
+ done.set()
+ worker = threading.Thread(target=slow)
+ worker.start()
+ time.sleep(.2)
+ began = time.monotonic()
+ client.read('/index')
+ assert time.monotonic() - began < .5 and not done.is_set(), 'the editor waited on the command'
+ worker.join(timeout=15)
+ assert done.is_set()
+ # X: each open file whose line matches; w writes it.
+ client.write(f'/pane/{a}/ctl', b'Edit X/b\\.txt$/ ,s/apple/APPLE/\n')
+ assert client.read(f'/pane/{b}/body') == b'APPLE pie\n'
+ client.write(f'/pane/{b}/ctl', b'Edit w\n')
+ assert (root / 'b.txt').read_bytes() == b'APPLE pie\n'
+ client.write(f'/pane/{a}/ctl', b'Edit 1 w first.txt\n')
+ assert (root / 'first.txt').read_bytes() == b'APPLE\n'
+
+
def test(binary, quic=False):
started = time.monotonic()
cut_writes(binary)
+ edit_commands(binary)
odd_paths(binary)
delcol_last_keeps_window(binary)
run_file(binary)