diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-27 17:41:55 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | 542dd489149e33915d19878a277e23b3a9c0b070 (patch) | |
| tree | aeb557581446621c366a2d3cd5888d25b37c5916 /test | |
| parent | c11ffe24f022d61cdd479e1ee946033c42e9a08c (diff) | |
| download | pardes-542dd489149e33915d19878a277e23b3a9c0b070.tar.gz pardes-542dd489149e33915d19878a277e23b3a9c0b070.zip | |
Record /log whether or not anyone reads it, with the editor's messages in it
/log is now one ring (64 KiB, 4 KiB on the board) that records new, del,
rename and save, and a msg line for everything the editor says. An open
freezes it, so cat log shows what happened lately and ends; writing
follow to that same open makes reads past it wait for newer records, and
a follower the ring outran reads lost N first.
The message log keeps the pane's serial, not its reusable slot.
A test now fails when the tree serves a file /README never mentions; it
caught pty/status, now documented along with typing through pty/data.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'test')
| -rw-r--r-- | test/fs.py | 24 | ||||
| -rw-r--r-- | test/panes.zig | 1 |
2 files changed, 18 insertions, 7 deletions
@@ -185,7 +185,11 @@ def discovery(binary, embedded=False): # An open of /pane/new makes a pane and the read names it; each # open makes another. A stat makes none, which is why new can be # listed at all: ls -l stats every name a listing gave it. - log = client.open('/log') + # /log answers the recent past and ends; `follow` written to the + # same open makes its reads past that wait for new records. + log = client.open('/log', 2) + frozen = len(client.read_fid(log)) + client.rpc(118, struct.pack('<IQI', log, 0, 7) + b'follow\n') first = int(client.read('/pane/new')) assert first == newest(client) second = int(client.read('/pane/new')) @@ -193,8 +197,14 @@ def discovery(binary, embedded=False): assert 'new' in client.list('/pane'), 'new should be visible to ls' client.stat('/pane/new') assert newest(client) == second, 'a stat of new made a pane' - assert client.read_fid(log) == f'new {first} {root}/+New\n'.encode() - assert client.read_fid(log) == f'new {second} {root}/+New\n'.encode() + # What the editor said is in the stream too, and the fixture's own + # `new` lands on whichever side of the open its first update did. + def pane_event(): + while (record := client.read_fid(log, frozen)).startswith((b'msg ', f'new {fixture} '.encode())): + pass + return record + assert pane_event() == f'new {first} {root}/+New\n'.encode() + assert pane_event() == f'new {second} {root}/+New\n'.encode() assert set(client.list('/pane')) == {'new', str(fixture), str(first), str(second)} client.write(f'/pane/{first}/body', b'first pane', truncate=True) assert client.read(f'/pane/{first}/body') == b'first pane' @@ -206,7 +216,7 @@ def discovery(binary, embedded=False): assert client.read(f'/pane/{first}/name') == f'{root}/+New\n'.encode() client.write(f'/pane/{first}/name', b'notes.txt\n') assert client.read(f'/pane/{first}/name') == f'{root}/notes.txt\n'.encode() - assert client.read_fid(log) == f'rename {first} {root}/notes.txt\n'.encode() + assert pane_event() == f'rename {first} {root}/notes.txt\n'.encode() assert client.stat(f'/pane/{first}/name')['length'] == len(f'{root}/notes.txt\n') # Copying addr onto dot selects that range; sel reads and replaces it. client.write(f'/pane/{first}/addr', b'#0,#5') @@ -223,11 +233,11 @@ def discovery(binary, embedded=False): assert client.read(f'/pane/{first}/dirty') == b'1\n' client.write(f'/pane/{first}/exec', b'Save\n') assert (root / 'notes.txt').read_bytes() == b'FIRST pane' - assert client.read_fid(log) == f'save {first} {root}/notes.txt\n'.encode() + assert pane_event() == f'save {first} {root}/notes.txt\n'.encode() assert client.read('/exec') == f'{first}\n'.encode() assert client.read(f'/pane/{first}/dirty') == b'0\n' client.remove(f'/pane/{second}') - assert client.read_fid(log) == f'del {second} {root}/+New\n'.encode() + assert pane_event() == f'del {second} {root}/+New\n'.encode() assert str(second) not in client.list('/pane') # look opens a file; the serial reads back. (root / 'opened.txt').write_bytes(b'one\ntwo\nthree\n') @@ -236,7 +246,7 @@ def discovery(binary, embedded=False): assert opened not in (fixture, first, second), opened assert client.read(f'/pane/{opened}/body') == b'one\ntwo\nthree\n' assert client.read(f'/pane/{opened}/name') == f'{root}/opened.txt\n'.encode() - assert client.read_fid(log) == f'new {opened} {root}/opened.txt\n'.encode() + assert pane_event() == f'new {opened} {root}/opened.txt\n'.encode() client.write(f'/pane/{first}/look', f'{root}/opened.txt:3\n'.encode()) assert client.read('/look') == f'{opened}\n'.encode(), 'a repeated look targets the open pane' assert {str(fixture), str(first), str(opened)} <= set(client.list('/pane')) diff --git a/test/panes.zig b/test/panes.zig index 2d3aed43..2f307cb5 100644 --- a/test/panes.zig +++ b/test/panes.zig @@ -2193,6 +2193,7 @@ test "document panes ignore terminal output without allocating terminal state" { const p = try Pardes.init(allocator.allocator(), .{ .tty_only = true }); defer p.deinit(); const pane = try p.setTestFile("document body\n"); + p.update(.tick); // the step that installed it records it in /log while (p.nextEffect()) |_| {} const revision = pane.file.?.revision; const allocations = allocator.alloc_index; |
