js/tests/js_test_suite.py

104 lines
3.0 KiB
Python

from typing import List, Optional
import os
from pathlib import Path
import difflib
from jasminesnake.js_stream import JSStringStream
import jasminesnake.ast as js_ast
class JSTest:
_test_name: str
_test_file: str
_result_file: Optional[str]
@property
def name(self):
return self._test_name
def __init__(self, name: str, test_file: str, result_file: Optional[str]):
self._test_name = name
self._test_file = test_file
self._result_file = result_file
def run(self, must_fail: bool = False):
payload = Path(self._test_file).read_text()
jst = JSStringStream(payload)
tree = jst.parse()
ast_tree = None
try:
ast_tree = js_ast.from_parse_tree(tree)
except NotImplementedError as e:
print("Seems like some nodes are not implemented :^)")
print("Error message: ")
if hasattr(e, "message"):
print(e.message)
else:
print(e)
return must_fail
expected = None
if self._result_file is not None:
expected = Path(self._result_file).read_text()
got = js_ast.to_ascii_tree(ast_tree, ast_format="short")
del jst
del tree
del ast_tree
if expected is not None:
if expected == got:
print("Test {} OK...".format(self._test_name))
else:
print(
"Error in test `{}':\nExpected:\n```{}```\nGot:\n```{}```".format(
self._test_name, expected, got
)
)
# for i, s in enumerate(difflib.ndiff(expected, got)):
# if s[0] != " ":
# print(s[0], ord(s[-1]), "at", i)
return False
else:
print("Test {} has no result file!\nGot:\n{}".format(self._test_name, got))
return False
return True
class JSTestCollection:
tests: List[JSTest]
def __init__(self, module_path: str):
self.tests = []
basedir = os.path.abspath(module_path)
tests_dir = os.path.join(basedir, "t")
results_dir = os.path.join(basedir, "r")
# Collect tests
test_files = [
os.path.join(tests_dir, f)
for f in os.listdir(tests_dir)
if os.path.isfile(os.path.join(tests_dir, f))
]
test_names = [
os.path.splitext(os.path.basename(path))[0] for path in test_files
]
for (test_name, test_file) in zip(test_names, test_files):
result_file = os.path.join(results_dir, test_name) + ".ast"
print(test_name, test_file, result_file)
if not os.path.isfile(result_file):
result_file = None
test_case = JSTest(test_name, test_file, result_file)
self.tests.append(test_case)
def run_all(self, must_fail: bool = False):
for test in self.tests:
if not test.run(must_fail):
return False
return True