aboutsummaryrefslogtreecommitdiffstats
path: root/resources
diff options
context:
space:
mode:
authorGravatar Matteo Bertucci <[email protected]>2021-02-24 12:07:13 +0100
committerGravatar Matteo Bertucci <[email protected]>2021-02-24 12:07:13 +0100
commitd931810f51f27e55455be7e8a87c5a27a04d431d (patch)
tree306c5e1995107f32870c81dda7bab56434b41c50 /resources
parentAdd unittests to the schema (diff)
Add unittest template
Diffstat (limited to 'resources')
-rw-r--r--resources/unittest_template.py81
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)