#! /usr/bin/python3 import re import sys import glob import os.path import subprocess from PIL import Image from PIL import ImageChops def imgequal(ref, out): ref = Image.open(ref).convert("1") out = Image.open(out).convert("1") diff = ImageChops.difference(ref, out) return diff.getbbox() is None def readable_cmd(cmd): result = "" for arg in cmd: if " " not in arg and "'" not in arg and '"' not in arg: a = arg elif "'" not in arg: a = "'" + arg + "'" else: a = a.replace(" ", "\\ ").replace("'", "\\'").replace('"', '\\"') result += " " + arg return result.strip() def indent(str, n): return re.subn(r"^", " " * n, str, flags=re.MULTILINE)[0] def runtest(program, refout=None, refimg=None, kind="script"): kind = "-u" if kind == "url" else "-s" cmd = "./fx92.py --quiet --save=/tmp/fx92-test.bmp".split() \ + [kind, program] st = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Retrieve standard error stderr = "" if st.stderr: stderr = st.stderr.decode().strip("\n") stderr = indent(stderr, 4) if st.returncode != 0: print("\x1b[41;1mFAILED\x1b[0m", program) print(" " + readable_cmd(cmd)) if stderr: print(" Standard error:") print(stderr) else: print(" Nothing on standard error") print("") return False success = True status = { "out": None, "img": None } if refout is not None: with open(refout, "rb") as fp: refout = fp.read() if st.stdout == refout: status["out"] = True else: status["out"] = (st.stdout, refout) success = False if refimg is not None: if imgequal(refimg, "/tmp/fx92-test.bmp"): status["img"] = True else: status["img"] = False success = False if status["out"] is None and status["img"] is None: print("PASSED", program) elif success: print("\x1b[43;1mPASSED\x1b[0m", program) else: print("\x1b[41;1mFAILED\x1b[0m", program) if status["out"] is None: print(" (No reference output)") elif status["out"] == True: print(" Output is correct.") else: print(" Incorrect output, got:") print(indent(status["out"][0], 4)) print(" Expected:") print(indent(status["out"][1], 4)) if status["img"] is None: print(" (No reference image)") elif status["img"] == True: print(" Image is correct.") else: print(" Image is incorrect!") if stderr: print(" Standard error:") print(stderr) print("") return success def main(): p1 = glob.glob("tests/*.txt") p2 = glob.glob("tests/contest2019/*.txt") paths = sorted(p1) + sorted(p2) print("Found {} tests.".format(len(paths))) total = 0 passed = 0 for t in paths: refout = t[:-4] + ".out" refout = refout if os.path.isfile(refout) else None refimg = t[:-4] + ".png" refimg = refimg if os.path.isfile(refimg) else None kind = "url" if t.startswith("tests/contest2019/") else "script" passed += runtest(t, refout=refout, refimg=refimg, kind=kind) total += 1 if passed < total: print("\nWarning, some tests failed!") return 1 return 0 if __name__ == "__main__": sys.exit(main())