aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-25 15:52:01 +0100
committereunhhu <[email protected]>2026-09-25 15:52:01 +0100
commit2d7024ba01875a8fc7a2c99e78c62911bcc7fe3f (patch)
tree1ca962fe09ab32bae4d26bb1a203f1010887fe28 /tests
parent12c377ea70c8928f96d02d0885744bd6818c10c6 (diff)
downloadvega-2d7024ba01875a8fc7a2c99e78c62911bcc7fe3f.tar.gz
vega-2d7024ba01875a8fc7a2c99e78c62911bcc7fe3f.zip
Keep a surface's app in a store
Every surface takes --store PATH and runs the app on Pure's tree store, so a list typed in the terminal is there the next time, on any surface. Vega and the app carry no saving code; Vega saves the last frame changes when it ends. Checks let the CLI and the sentence surface take turns on one store and match the model each time, and reopen an interactive session's store.
Diffstat (limited to 'tests')
-rw-r--r--tests/check.py46
1 files changed, 43 insertions, 3 deletions
diff --git a/tests/check.py b/tests/check.py
index 2d01c98..6256023 100644
--- a/tests/check.py
+++ b/tests/check.py
@@ -14,6 +14,8 @@
3. Tables: examples/scores.aup aligns its columns by display width and marks
row tones.
4. Every aup example runs on every surface under random keys without a crash.
+5. Stored: surfaces take turns on one store and each continues the list; an
+ interactive session's entries are there in the next one.
"""
import argparse
import json
@@ -146,6 +148,39 @@ def cli_and_say(vega, module, seeds, steps=300):
return compared, failures
+def stored_surfaces(vega, module, work, seeds, steps=240):
+ """One store, several surfaces in turn: each run continues the list where
+ the last one left it, and prints or says what the model says."""
+ compared = 0
+ for seed in seeds:
+ rng = random.Random(seed + 500)
+ model, store = Todo(), work / f'store-{seed}'
+ cuts = sorted(rng.sample(range(1, steps), 6))
+ for number, (start, end) in enumerate(zip([0] + cuts, cuts + [steps])):
+ surface = ['cli', 'say'][number % 2]
+ script, expected = [], []
+ for _ in range(start, end):
+ if rng.random() < 0.3:
+ word = rng.choice(WORDS)
+ script.append('text ' + (word.encode().hex() or '-'))
+ ok, name = model.event('add', word), 'add'
+ else:
+ name = rng.choice(list(KEYS) + ['drop'])
+ script.append(f'key {KEYS[name]}')
+ ok = model.event(name)
+ if surface == 'say':
+ expected.append(model.focus() if ok else f'Could not {name}.')
+ script.append('show')
+ expected += model.cli() if surface == 'cli' else model.say()
+ out = run(vega, surface, module, '--store', store, stdin='\n'.join(script) + '\n')
+ assert out.returncode == 0 and out.stdout.splitlines() == expected, \
+ (seed, number, [(a, b) for a, b in zip(out.stdout.splitlines(), expected) if a != b][:3])
+ compared += len(expected)
+ frame = run(vega, 'tui', module, '--store', store, '--dump', '40x12', stdin='show\n').stdout.splitlines()
+ assert frame[2].startswith(f'|tasks_list ({len(model.tasks)})'), frame
+ return compared
+
+
def frames(output, height):
lines = output.splitlines()
for start in range(0, len(lines), height + 1):
@@ -229,14 +264,14 @@ def scores(vega, module):
return len(out)
-def interactive(vega, module):
+def interactive(vega, module, store=None):
"""The terminal surface on a real pseudo-terminal: typed text commits
with Enter, arrow keys and letters reach the app after Tab, Ctrl-C leaves
and restores the terminal."""
import fcntl, pty, select, struct, termios, time
pid, fd = pty.fork()
if pid == 0:
- os.execv(str(vega), [str(vega), 'tui', str(module)])
+ os.execv(str(vega), [str(vega), 'tui', str(module)] + (['--store', str(store)] if store else []))
fcntl.ioctl(fd, termios.TIOCSWINSZ, struct.pack('HHHH', 10, 40, 0, 0))
os.kill(pid, 28) # SIGWINCH: take the size
@@ -263,6 +298,9 @@ def interactive(vega, module):
assert os.WIFEXITED(status) and os.WEXITSTATUS(status) == 0, status
assert '\x1b[?1049h' in text and text.rstrip().endswith('\x1b[?1049l'), text[-80:]
assert 'milk' in text and 'béton' in text and '(2)' in text and 'done' in text, text[-400:]
+ if store: # what was typed is still there in the next session
+ again = run(vega, 'cli', module, '--store', store, stdin='show\n').stdout.splitlines()
+ assert again == ['To do', 'left: 2 tasks', 'tasks_list (2)', '> milk [done] (muted)', ' béton'], again
return 1
@@ -316,7 +354,9 @@ def main():
cli_and_say(vega, modules['todo'], range(args.seeds))
report['tui_frames'] = tui(vega, modules['todo'], range(args.seeds), [(40, 12), (24, 9), (80, 30), (16, 6)])
report['table_lines'] = scores(vega, modules['scores'])
- report['interactive_sessions'] = interactive(vega, modules['todo'])
+ report['interactive_sessions'] = interactive(vega, modules['todo']) + \
+ interactive(vega, modules['todo'], work / 'interactive-store')
+ report['stored_surface_lines'] = stored_surfaces(vega, modules['todo'], work, range(args.seeds))
report['examples'], report['robustness_runs'] = robustness(vega, aup, work, args.rounds)
print(json.dumps(report))