diff options
author | 2021-02-24 12:07:13 +0100 | |
---|---|---|
committer | 2021-02-24 12:07:13 +0100 | |
commit | d931810f51f27e55455be7e8a87c5a27a04d431d (patch) | |
tree | 306c5e1995107f32870c81dda7bab56434b41c50 /resources | |
parent | Add unittests to the schema (diff) |
Add unittest template
Diffstat (limited to 'resources')
-rw-r--r-- | resources/unittest_template.py | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/resources/unittest_template.py b/resources/unittest_template.py new file mode 100644 index 0000000..7e21b97 --- /dev/null +++ b/resources/unittest_template.py @@ -0,0 +1,81 @@ +import ast +import io +import os +import sys +import traceback +import unittest +from itertools import chain +from types import ModuleType, SimpleNamespace +from typing import NoReturn +from unittest import mock + +### USER CODE + + +class RunnerTestCase(unittest.TestCase): +### UNIT CODE + + +# Fake file object not writing anything +DEVNULL = SimpleNamespace(write=lambda *_: None, flush=lambda *_: None) + +RESULT = io.StringIO() +ORIGINAL_STDOUT = sys.stdout + +sys.stdout = DEVNULL +sys.stderr = DEVNULL + + +def _exit_sandbox(code: int) -> NoReturn: + """ + Codes: + - 0: Executed with success + - 5: Syntax error while parsing user code + - 99: Internal error + """ + result_content = RESULT.getvalue() + + print( + f"{result_content}", + file=ORIGINAL_STDOUT + ) + sys.exit(code) + + +def _load_user_module() -> ModuleType: + try: + ast.parse(USER_CODE, "<input>") + except SyntaxError: + RESULT.write("".join(traceback.format_exception(*sys.exc_info(), limit=0))) + _exit_sandbox(5) + + _module = ModuleType("module") + exec(USER_CODE, _module.__dict__) + + return _module + + +def _main() -> None: + suite = unittest.defaultTestLoader.loadTestsFromTestCase(RunnerTestCase) + result = suite.run(unittest.TestResult()) + + RESULT.write(str(int(result.wasSuccessful()))) + + if not result.wasSuccessful(): + RESULT.write( + ";".join(chain( + (error[0]._testMethodName.lstrip("test_") for error in result.errors), + (failure[0]._testMethodName.lstrip("test_") for failure in result.failures) + )) + ) + + _exit_sandbox(0) + + +try: + module = _load_user_module() + _main() +except Exception: + print("Uncaught exception:\n", file=RESULT) + traceback.print_exc(file=RESULT) + _exit_sandbox(99) |