json-parser-prolog-lisp/test_parsing_accuracy.py

114 lines
3.4 KiB
Python
Executable file

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import os
from pathlib import Path
import subprocess
import traceback
def json_parse_prolog(json_file_path):
cmdline = [
"swipl",
"-s", "Prolog/jsonparse.pl",
"-g", "jsonread('{}', J), jsonparse(JS, J), write(JS)".format(json_file_path),
"-t", "halt"
]
try:
p = subprocess.run(cmdline, check=False, capture_output=True)
# print(p.stdout.decode("utf-8"))
return json.loads(p.stdout.decode("utf-8"))
except Exception:
print("Prolog error:")
print(p.stdout.decode("utf-8"))
print(p.stderr.decode("utf-8"))
traceback.print_exc()
return {}
def json_parse_lisp(json_file_path):
cmdline = [
"sbcl",
"--noinform",
"--disable-ldb",
"--lose-on-corruption",
"--non-interactive",
"--no-userinit",
"--load", "Lisp/jsonparse.lisp",
"--eval", "(format t (concatenate 'string \"--CUT HERE--\" '(#\\newline)))",
"--eval", "(format t \"~A\" (jsonserialize (jsonread \"{}\")))".format(json_file_path),
"--eval", "(quit)"
]
try:
p = subprocess.run(cmdline, check=False, capture_output=True)
# print(p.stdout.decode("utf-8").split("--CUT HERE--")[1])
return json.loads(p.stdout.decode("utf-8").split("--CUT HERE--")[1])
except Exception:
print("Lisp error:")
print(str(cmdline).replace(",", "")[1:-1])
print(p.stdout.decode("utf-8"))
print(p.stderr.decode("utf-8"))
traceback.print_exc()
return {}
def json_parse_python(json_file_path):
with open(json_file_path, "r") as f:
return json.load(f)
ignore_tests = [
"y_string_pi.json",
"y_number_real_fraction_exponent.json",
"y_object_escaped_null_in_key.json",
"y_string_escaped_control_character.json",
"y_string_escaped_noncharacter.json",
"y_string_nbsp_uescaped.json",
"y_string_null_escape.json",
"y_string_uEscape.json",
"y_string_uescaped_newline.json",
]
def main():
failed = {
"Prolog": [],
"Lisp": [],
}
for fname in os.listdir("JSONTestSuite/test_parsing"):
if fname.endswith(".json") and fname.startswith("y_"):
if (
"unicode" in fname.lower() or
"utf" in fname.lower() or
"u+" in fname.lower() or
"surrogate" in fname.lower()
):
continue
if fname in ignore_tests:
continue
print(f"Testing file {fname}")
json_file_path = Path("JSONTestSuite/test_parsing") / fname
prolog = json_parse_prolog(json_file_path)
lisp = json_parse_lisp(json_file_path)
python = json_parse_python(json_file_path)
if prolog != lisp or prolog != python:
print(
f"File {fname} failed; Prolog: {prolog == python} Lisp: {lisp == python}")
if prolog != python:
failed["Prolog"].append(fname)
if lisp != python:
failed["Lisp"].append(fname)
print()
print(f"Failed tests:")
for k, failed in failed.items():
print(f"{k}:")
for fname in failed:
path = Path("JSONTestSuite/test_parsing") / fname
print(f" {path}")
if __name__ == "__main__":
main()