aboutsummaryrefslogtreecommitdiff
path: root/tests/drivers/hold_test.py
blob: 1f6ea3924672b8d51b6c396765dc5d3f83880f03 (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
#!/usr/bin/env python3
# hold blocks (spec 4.16): accepted programs print what their first line expects, rejected
# ones report the error their first line names (exit 1), and trapping ones stop with
# exit 2 and the message named.  usage: hold_test.py [VM]
from pathlib import Path
import subprocess, sys
root = Path(__file__).resolve().parents[2]
vm = sys.argv[1] if len(sys.argv) > 1 else 'build/bin/zy'
count = bad = 0
for case in sorted((root / 'tests/hold').glob('*/*.zc')):
    src = case.read_text(); first = src.splitlines()[0]
    p = subprocess.run([str(root / vm) if not Path(vm).is_absolute() else vm], input=src, text=True, capture_output=True, cwd=root, timeout=60)
    out = p.stdout + p.stderr
    if first.startswith('// expect: '):
        ok = p.returncode == 0 and p.stdout.strip() == first[11:].strip()
    elif first.startswith('// error: '):
        ok = p.returncode == 1 and first[10:].strip() in out
    elif first.startswith('// trap: '):
        ok = p.returncode == 2 and first[9:].strip() in out
    else:
        ok = False
    count += 1
    if not ok:
        bad += 1; print(f'FAIL {case.relative_to(root)}: rc={p.returncode} out={out[:300]!r}')
    else:
        print(f'ok   {case.relative_to(root)}')
print(f'{count - bad}/{count} hold fixtures passed')
sys.exit(1 if bad or not count else 0)