fx92-interpreter/tests.py

137 lines
3.5 KiB
Python
Executable File

#! /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())