53 lines
1.5 KiB
Python
Executable file
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))
|