sots-engine/tests/mars_text/oracle/compare.py

53 lines
1.5 KiB
Python
Executable file

#!/usr/bin/env python3
"""compare.py <ours.json> <oracle.json> [label]
Structural, type-aware comparison of two dump files (bool != int != float,
str != list). Prints OK or the first few differences; exit 1 on any
difference.
"""
import json
import sys
MAX_DIFFS = 8
def walk(a, b, path, diffs):
if len(diffs) >= MAX_DIFFS:
return
if type(a) is not type(b):
diffs.append(f"{path}: type {type(a).__name__} != {type(b).__name__} ({a!r} vs {b!r})")
return
if isinstance(a, dict):
for k in sorted(set(a) | set(b)):
if k not in a:
diffs.append(f"{path}.{k}: missing in ours")
elif k not in b:
diffs.append(f"{path}.{k}: extra in ours")
else:
walk(a[k], b[k], f"{path}.{k}", diffs)
elif isinstance(a, list):
if len(a) != len(b):
diffs.append(f"{path}: length {len(a)} != {len(b)}")
for i, (x, y) in enumerate(zip(a, b)):
walk(x, y, f"{path}[{i}]", diffs)
elif a != b:
diffs.append(f"{path}: {a!r} != {b!r}")
def main(argv):
ours = json.load(open(argv[1], encoding="ascii"))
oracle = json.load(open(argv[2], encoding="ascii"))
label = argv[3] if len(argv) > 3 else argv[1]
diffs = []
walk(ours, oracle, "$", diffs)
if diffs:
print(f"DIFF {label}")
for d in diffs:
print(" ", d)
return 1
print(f"OK {label}")
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))