aboutsummaryrefslogtreecommitdiff
path: root/tests/drivers/compiler_contract_test.py
blob: 63e476c29659b3fa2088e771330947f7d22c7751 (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
29
30
#!/usr/bin/env python3
"""accept/reject contracts, selectable in small groups before implementation."""
import argparse
import json
import re
import subprocess
from pathlib import Path

parser = argparse.ArgumentParser()
parser.add_argument('host')
parser.add_argument('--group')
parser.add_argument('--case')
args = parser.parse_args()
cases = json.loads(Path('tests/spec/compiler_contracts.json').read_text())
cases = [c for c in cases if (not args.group or c['group'] == args.group) and (not args.case or args.case in c['name'])]
assert cases, 'no selected contracts'
failures = []
for c in cases:
    source = ('typecheck on;\n' + c['source']).encode()
    r = subprocess.run([args.host], input=source, capture_output=True, timeout=10)
    text = (r.stdout + r.stderr).decode(errors='replace')
    error = bool(re.search(r'(zc:|zc0:|error:|undefined|not defined)', text)) or r.returncode != 0
    valid = (not error) == c['accept'] and r.returncode >= 0
    if valid and 'output' in c:
        valid = r.returncode == 0 and r.stdout.decode() == c['output']
    print(('ok   ' if valid else 'FAIL ') + c['group'] + ': ' + c['name'])
    if not valid:
        failures.append(c['name'])
        print(text.strip()[:1000])
raise SystemExit(1 if failures else 0)