ludic.ui: a rule's selector text is interned - {sel} was sel itself (a template of one string hole passes the string through) and lss_rule frees sel, so rules <id> named whatever reused the bytes; smoke.txt's tree order follows the document, and smoke.py runs the transcript
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
e74656c372
commit
a436cfbe35
4 changed files with 38 additions and 3 deletions
|
|
@ -19,7 +19,7 @@ function lss_rule_add(f: UiFile, decls: UiRule, sel: string, err: []string, line
|
||||||
let r = new UiRule
|
let r = new UiRule
|
||||||
r.keys = decls.keys
|
r.keys = decls.keys
|
||||||
r.vals = decls.vals
|
r.vals = decls.vals
|
||||||
r.text = `{sel}` # a copy: the selector's text is given back below
|
r.text = intern(sel) # a copy: lss_rule frees sel (`{sel}` was sel itself, and dangled)
|
||||||
r.at = `{f.path}:{line}`
|
r.at = `{f.path}:{line}`
|
||||||
r.sel = sel_parse(sel, err)
|
r.sel = sel_parse(sel, err)
|
||||||
if r.sel != null {
|
if r.sel != null {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ ludic ui-preview [--font DIR] # the host on stdin/stdout; DIR holds the gam
|
||||||
```
|
```
|
||||||
|
|
||||||
**The wire protocol is [protocol-v1.md](protocol-v1.md)**, frozen: every request, every reply and
|
**The wire protocol is [protocol-v1.md](protocol-v1.md)**, frozen: every request, every reply and
|
||||||
every line format. `smoke.txt` is a scripted session with what each reply must contain.
|
every line format. `smoke.txt` is a scripted session with what each reply must contain, and `smoke.py` runs it
|
||||||
|
(`python3 tools/ui-preview/smoke.py tools/ui-preview/smoke.txt bin/ludic-ui-preview`).
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
|
|
|
||||||
34
tools/ui-preview/smoke.py
Normal file
34
tools/ui-preview/smoke.py
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# smoke.py - runs smoke.txt against a ui-preview binary and checks each reply: `> ` lines are requests,
|
||||||
|
# `< ` a reply line must contain the text (in order), `<= ` the exact final line, `<! ` no line may
|
||||||
|
# python3 tools/ui-preview/smoke.py tools/ui-preview/smoke.txt bin/ludic-ui-preview
|
||||||
|
import subprocess, sys
|
||||||
|
reqs, exp = [], []
|
||||||
|
for line in open(sys.argv[1]):
|
||||||
|
line = line.rstrip("\n")
|
||||||
|
if line.startswith("> ") or line == ">": reqs.append(line[2:]); exp.append([])
|
||||||
|
elif line.startswith(("< ", "<= ", "<! ")) and reqs:
|
||||||
|
k, _, t = line.partition(" "); exp[-1].append((k, t))
|
||||||
|
p = subprocess.run([sys.argv[2]], input="\n".join(reqs) + "\n", capture_output=True, text=True, errors="replace", timeout=60)
|
||||||
|
out = p.stdout.splitlines()
|
||||||
|
replies, cur = [], []
|
||||||
|
for l in out:
|
||||||
|
cur.append(l)
|
||||||
|
if l == "ok" or l.startswith("ok ") or l.startswith("fail"):
|
||||||
|
replies.append(cur); cur = []
|
||||||
|
bad = 0
|
||||||
|
print(f"{len(reqs)} requests, {len(replies)} replies, exit {p.returncode}")
|
||||||
|
for i, r in enumerate(reqs):
|
||||||
|
rep = replies[i] if i < len(replies) else []
|
||||||
|
pos = 0
|
||||||
|
for k, t in exp[i]:
|
||||||
|
ok = True
|
||||||
|
if k == "<":
|
||||||
|
j = next((j for j in range(pos, len(rep)) if t in rep[j]), None)
|
||||||
|
ok = j is not None; pos = j if ok else pos
|
||||||
|
elif k == "<=": ok = bool(rep) and rep[-1] == t
|
||||||
|
elif k == "<!": ok = not any(t in x for x in rep)
|
||||||
|
if not ok:
|
||||||
|
bad += 1; print(f"FAIL request {i+1} `{r[:60]}`: {k} {t!r}\n reply: {rep[-6:]}")
|
||||||
|
print("smoke:", "OK" if bad == 0 else f"{bad} expectation(s) failed")
|
||||||
|
if p.stderr.strip(): print("stderr:", p.stderr.strip()[:500])
|
||||||
|
|
@ -103,8 +103,8 @@
|
||||||
> tree
|
> tree
|
||||||
< node 0
|
< node 0
|
||||||
< "root"
|
< "root"
|
||||||
< "go"
|
|
||||||
< "Food"
|
< "Food"
|
||||||
|
< "go"
|
||||||
<= ok
|
<= ok
|
||||||
|
|
||||||
> box label
|
> box label
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue