From 967be9e750221ab2ab783f95df79bb26d290a45e Mon Sep 17 00:00:00 2001 From: Martial Simon Date: Mon, 15 Sep 2025 01:07:58 +0200 Subject: add: added projects --- tiger-compiler/tests/python/pytest.ini | 3 + .../tests/python/tests/setup/__init__.py | 4 ++ .../tests/python/tests/setup/load_files.py | 14 +++++ .../tests/python/tests/setup/load_testsuite.py | 35 +++++++++++ .../tests/python/tests/setup/project_settings.py | 23 +++++++ tiger-compiler/tests/python/tests/setup/run_tc.py | 72 ++++++++++++++++++++++ tiger-compiler/tests/python/tests/test_assert.py | 27 ++++++++ tiger-compiler/tests/python/tests/test_bind.py | 18 ++++++ tiger-compiler/tests/python/tests/test_desugar.py | 14 +++++ tiger-compiler/tests/python/tests/test_escapes.py | 14 +++++ .../tests/python/tests/test_llvmtranslate.py | 18 ++++++ tiger-compiler/tests/python/tests/test_object.py | 30 +++++++++ tiger-compiler/tests/python/tests/test_syntax.py | 16 +++++ .../tests/python/tests/test_testsuite.py | 19 ++++++ tiger-compiler/tests/python/tests/test_type.py | 16 +++++ 15 files changed, 323 insertions(+) create mode 100644 tiger-compiler/tests/python/pytest.ini create mode 100644 tiger-compiler/tests/python/tests/setup/__init__.py create mode 100644 tiger-compiler/tests/python/tests/setup/load_files.py create mode 100644 tiger-compiler/tests/python/tests/setup/load_testsuite.py create mode 100644 tiger-compiler/tests/python/tests/setup/project_settings.py create mode 100644 tiger-compiler/tests/python/tests/setup/run_tc.py create mode 100644 tiger-compiler/tests/python/tests/test_assert.py create mode 100644 tiger-compiler/tests/python/tests/test_bind.py create mode 100644 tiger-compiler/tests/python/tests/test_desugar.py create mode 100644 tiger-compiler/tests/python/tests/test_escapes.py create mode 100644 tiger-compiler/tests/python/tests/test_llvmtranslate.py create mode 100644 tiger-compiler/tests/python/tests/test_object.py create mode 100644 tiger-compiler/tests/python/tests/test_syntax.py create mode 100644 tiger-compiler/tests/python/tests/test_testsuite.py create mode 100644 tiger-compiler/tests/python/tests/test_type.py (limited to 'tiger-compiler/tests/python') diff --git a/tiger-compiler/tests/python/pytest.ini b/tiger-compiler/tests/python/pytest.ini new file mode 100644 index 0000000..884f5de --- /dev/null +++ b/tiger-compiler/tests/python/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tests +norecursedirs = tests/setup diff --git a/tiger-compiler/tests/python/tests/setup/__init__.py b/tiger-compiler/tests/python/tests/setup/__init__.py new file mode 100644 index 0000000..e24ca8e --- /dev/null +++ b/tiger-compiler/tests/python/tests/setup/__init__.py @@ -0,0 +1,4 @@ +from .load_files import load_files +from .load_testsuite import load_testsuite, Testsuite +from .project_settings import get_project_root, get_tests_root +from .run_tc import locate_tc, run_tc, run_tc_assert, run_tc_object diff --git a/tiger-compiler/tests/python/tests/setup/load_files.py b/tiger-compiler/tests/python/tests/setup/load_files.py new file mode 100644 index 0000000..b71f1bb --- /dev/null +++ b/tiger-compiler/tests/python/tests/setup/load_files.py @@ -0,0 +1,14 @@ +from pathlib import Path +from typing import Generator + +from .project_settings import get_project_root + + +def load_files(directory: Path | str) -> Generator[Path, None, None]: + """Returns a generator which iterates over all the files at the root of the + specified directory. + + :return Generator which iterates over all the files at the root of the + specified directory + """ + return (get_project_root() / directory).iterdir() diff --git a/tiger-compiler/tests/python/tests/setup/load_testsuite.py b/tiger-compiler/tests/python/tests/setup/load_testsuite.py new file mode 100644 index 0000000..07ed322 --- /dev/null +++ b/tiger-compiler/tests/python/tests/setup/load_testsuite.py @@ -0,0 +1,35 @@ +from enum import Enum +from pathlib import Path +from typing import Generator + +from .project_settings import get_tests_root + +def load_testsuite(directory: Path | str) -> Generator[Path, None, None]: + """Load the testsuite with the specified name within the project tests + directory. + + :return Generator which iterates over all the files at the root of the + directory with the specified name at the project test folder root + """ + for file in (get_tests_root() / directory).iterdir(): + if file.name.endswith(".tig"): + yield file + + +class Testsuite(Enum): + """All the functional testing files regrouped as an enum of sets""" + __test__ = False + GOOD: list[Path, ...] = list(load_testsuite("good")) + SYNTAX: list[Path, ...] = list(load_testsuite("syntax")) + BIND: list[Path, ...] = list(load_testsuite("bind")) + TYPE: list[Path, ...] = list(load_testsuite("type")) + DESUGAR_GOOD: list[Path, ...] = list(load_testsuite("desugar")) + LLVMTRANSLATE: list[Path, ...] = list(load_testsuite("llvmtranslate")) + OBJECT_GOOD: list[Path, ...] = list(load_testsuite("object/good")) + OBJECT_BIND: list[Path, ...] = list(load_testsuite("object/bind")) + OBJECT_TYPE: list[Path, ...] = list(load_testsuite("object/type")) + ASSERT_GOOD: list[Path, ...] = list(load_testsuite("assert/good")) + ASSERT_PARSE: list[Path, ...] = list(load_testsuite("assert/parse")) + ASSERT_BIND: list[Path, ...] = list(load_testsuite("assert/bind")) + ASSERT_TYPE: list[Path, ...] = list(load_testsuite("assert/type")) + TESTSUITE_GOOD: list[Path, ...] = list(load_testsuite("testsuite/good")) diff --git a/tiger-compiler/tests/python/tests/setup/project_settings.py b/tiger-compiler/tests/python/tests/setup/project_settings.py new file mode 100644 index 0000000..139947e --- /dev/null +++ b/tiger-compiler/tests/python/tests/setup/project_settings.py @@ -0,0 +1,23 @@ +from pathlib import Path + + +project_root: Path = Path(__file__).parent.parent.parent.parent.parent + + +def get_project_root() -> Path: + """Return the absolute path of the project according to the program. + :return Path of the project root as absolute path + """ + return project_root.absolute() + + +tests_root: Path = get_project_root() / "tests" + + +def get_tests_root() -> Path: + """Return the absolute path of the project tests folder according to the + program. + + :return Path of the project root as absolute path + """ + return tests_root.absolute() diff --git a/tiger-compiler/tests/python/tests/setup/run_tc.py b/tiger-compiler/tests/python/tests/setup/run_tc.py new file mode 100644 index 0000000..f547b56 --- /dev/null +++ b/tiger-compiler/tests/python/tests/setup/run_tc.py @@ -0,0 +1,72 @@ +import subprocess +import sys + +from pathlib import Path + +from .project_settings import get_project_root + + +tc_executable = get_project_root() / "src" / "tc" + +assert tc_executable.is_file() + +def locate_tc() -> Path: + """Return the location of the Tiger Compiler executable. + + :return Path leading to the tc executable used by the program. + """ + return tc_executable.absolute() + +def run_tc(file: Path | str, + *args: str, + object: bool = False, + assert_ext: bool = False, + print_errors: bool = False) -> int: + """Run the Tiger Compiler executable. It tries to compile the .tig file at + the specified file with the provided arguments. The resulting return code is + returned by the function afterward. + + :param file File to run the Tiger Compiler on + :param args Any additional argument to provide to the call + :param object If true, turn on POO extension in TC executable + :param assert_ext If true, turn on assert extension in TC executable + :param print_errors If true, redirects all error output from the Tiger + Compiler executable on the program actual standard error output + :return Return code of the call + """ + arguments = [*args] + + if assert_ext: + arguments.insert(0, "--assert") + + if object: + arguments.insert(0, "--object") + + return subprocess.call( + [tc_executable, file, *arguments], + stdout=None, + stderr=None if not print_errors else sys.stderr.fileno(), + timeout=10 + ) + +def run_tc_object(file: Path | str, *args: str, + print_errors: bool = False) -> int: + """Run the Tiger compiler executable with POO extension activated. + :param file File to run the Tiger Compiler on + :param args Any additional argument to provide to the call + :param print_errors If true, redirects all error output from the Tiger + Compiler executable on the program actual standard error output + :return Return code of the call + """ + return run_tc(file, *args, object=True, print_errors=print_errors) + +def run_tc_assert(file: Path | str, *args: str, + print_errors: bool = False) -> int: + """Run the Tiger compiler executable with assert extension activated. + :param file File to run the Tiger Compiler on + :param args Any additional argument to provide to the call + :param print_errors If true, redirects all error output from the Tiger + Compiler executable on the program actual standard error output + :return Return code of the call + """ + return run_tc(file, *args, assert_ext=True, print_errors=print_errors) diff --git a/tiger-compiler/tests/python/tests/test_assert.py b/tiger-compiler/tests/python/tests/test_assert.py new file mode 100644 index 0000000..bf33002 --- /dev/null +++ b/tiger-compiler/tests/python/tests/test_assert.py @@ -0,0 +1,27 @@ +import pytest + +from setup import Testsuite, run_tc, run_tc_assert + + +class TestAssert: + + @pytest.mark.parametrize("file", Testsuite.ASSERT_GOOD.value) + def test_assert_good(self, file: str): + assert run_tc_assert(file, "--assert-desugar", "--llvm-compute") == 0 + + @pytest.mark.parametrize("file", Testsuite.ASSERT_GOOD.value) + def test_assert_parse_no_flag(self, file: str): + assert run_tc(file, "--parse", assert_ext=False) == 2 + + @pytest.mark.parametrize("file", Testsuite.ASSERT_PARSE.value) + def test_assert_parse_flag(self, file: str): + assert run_tc_assert(file, "--assert-parse") == 3 + + @pytest.mark.parametrize("file", Testsuite.ASSERT_BIND.value) + def test_assert_bind(self, file: str): + assert run_tc_assert(file, "--assert-bindings-compute") == 4 + + @pytest.mark.parametrize("file", Testsuite.ASSERT_TYPE.value) + def test_assert_type(self, file: str): + assert run_tc_assert(file, "--assert-types-compute") == 5 + diff --git a/tiger-compiler/tests/python/tests/test_bind.py b/tiger-compiler/tests/python/tests/test_bind.py new file mode 100644 index 0000000..4d3a446 --- /dev/null +++ b/tiger-compiler/tests/python/tests/test_bind.py @@ -0,0 +1,18 @@ +import pytest + +from setup import Testsuite, run_tc + + +def run_tc_bind(file: str) -> int: + return run_tc(file, "--bound") + + +class TestBind: + + @pytest.mark.parametrize("file", Testsuite.GOOD.value) + def test_bind_good(self, file: str): + assert run_tc_bind(file) == 0 + + @pytest.mark.parametrize("file", Testsuite.BIND.value) + def test_bind_error(self, file: str): + assert run_tc_bind(file) == 4 diff --git a/tiger-compiler/tests/python/tests/test_desugar.py b/tiger-compiler/tests/python/tests/test_desugar.py new file mode 100644 index 0000000..3302f32 --- /dev/null +++ b/tiger-compiler/tests/python/tests/test_desugar.py @@ -0,0 +1,14 @@ +import pytest + +from setup import Testsuite, run_tc + + +def run_tc_desugar(file: str) -> int: + return run_tc(file, "--desugar") + + +class TestDesugar: + + @pytest.mark.parametrize("file", Testsuite.DESUGAR_GOOD.value) + def test_desugar_good(self, file: str): + assert run_tc_desugar(file) == 0 diff --git a/tiger-compiler/tests/python/tests/test_escapes.py b/tiger-compiler/tests/python/tests/test_escapes.py new file mode 100644 index 0000000..977b484 --- /dev/null +++ b/tiger-compiler/tests/python/tests/test_escapes.py @@ -0,0 +1,14 @@ +import pytest + +from setup import Testsuite, run_tc + + +def run_tc_escapes(file: str) -> int: + return run_tc(file, "--escapes-compute") + + +class TestEscapes: + + @pytest.mark.parametrize("file", Testsuite.GOOD.value) + def test_escapes_good(self, file: str): + assert run_tc_escapes(file) == 0 diff --git a/tiger-compiler/tests/python/tests/test_llvmtranslate.py b/tiger-compiler/tests/python/tests/test_llvmtranslate.py new file mode 100644 index 0000000..e11fd62 --- /dev/null +++ b/tiger-compiler/tests/python/tests/test_llvmtranslate.py @@ -0,0 +1,18 @@ +import pytest + +from setup import Testsuite, run_tc + + +def run_tc_llvmtranslate(file: str) -> int: + return run_tc(file, "--llvm-compute") + + +class TestLLVMTranslate: + + @pytest.mark.parametrize("file", Testsuite.GOOD.value) + def test_llvmtranslate_good(self, file: str): + assert run_tc_llvmtranslate(file) == 0 + + @pytest.mark.parametrize("file", Testsuite.LLVMTRANSLATE.value) + def test_llvmtranslate_simple(self, file: str): + assert run_tc_llvmtranslate(file) == 0 diff --git a/tiger-compiler/tests/python/tests/test_object.py b/tiger-compiler/tests/python/tests/test_object.py new file mode 100644 index 0000000..0f3d224 --- /dev/null +++ b/tiger-compiler/tests/python/tests/test_object.py @@ -0,0 +1,30 @@ +import pytest + +from setup import Testsuite, run_tc_object + + +def run_tc_object_all(file: str) -> int: + return run_tc_object(file, "--object-desugar") + + +def run_tc_object_bind(file: str) -> int: + return run_tc_object(file, "--object-bindings-compute") + + +def run_tc_object_type(file: str) -> int: + return run_tc_object(file, "--object-types-compute") + + +class TestObject: + + @pytest.mark.parametrize("file", Testsuite.OBJECT_GOOD.value) + def test_object_good(self, file: str): + assert run_tc_object_all(file) == 0 + + @pytest.mark.parametrize("file", Testsuite.OBJECT_BIND.value) + def test_object_bind_error(self, file: str): + assert run_tc_object_bind(file) == 4 + + @pytest.mark.parametrize("file", Testsuite.OBJECT_TYPE.value) + def test_object_type_error(self, file: str): + assert run_tc_object_type(file) == 5 diff --git a/tiger-compiler/tests/python/tests/test_syntax.py b/tiger-compiler/tests/python/tests/test_syntax.py new file mode 100644 index 0000000..2c9edd2 --- /dev/null +++ b/tiger-compiler/tests/python/tests/test_syntax.py @@ -0,0 +1,16 @@ +import pytest + +from setup import Testsuite, run_tc + + +def run_tc_parse(file: str) -> int: + return run_tc(file, "--parse") + +class TestSyntax: + @pytest.mark.parametrize("file", Testsuite.GOOD.value) + def test_syntax_good(self, file: str): + assert run_tc_parse(file) == 0 + + @pytest.mark.parametrize("file", Testsuite.SYNTAX.value) + def test_syntax_error(self, file: str): + assert run_tc_parse(file) == 3 diff --git a/tiger-compiler/tests/python/tests/test_testsuite.py b/tiger-compiler/tests/python/tests/test_testsuite.py new file mode 100644 index 0000000..f00ff2d --- /dev/null +++ b/tiger-compiler/tests/python/tests/test_testsuite.py @@ -0,0 +1,19 @@ +import pytest + +from setup import Testsuite, run_tc_assert + + +def run_tc_testsuite(file: str, *args: str) -> int: + return run_tc_assert(file, "--testsuite", *args) + + +class TestAssert: + + @pytest.mark.parametrize("file", Testsuite.TESTSUITE_GOOD.value) + def test_testsuite_good(self, file: str): + assert run_tc_testsuite(file, "--assert-desugar", "--llvm-compute") == 0 + + @pytest.mark.parametrize("file", Testsuite.TESTSUITE_GOOD.value) + def test_testsuite_good_parse(self, file: str): + assert run_tc_testsuite(file) == 0 + diff --git a/tiger-compiler/tests/python/tests/test_type.py b/tiger-compiler/tests/python/tests/test_type.py new file mode 100644 index 0000000..9528842 --- /dev/null +++ b/tiger-compiler/tests/python/tests/test_type.py @@ -0,0 +1,16 @@ +import pytest + +from setup import Testsuite, run_tc + + +def run_tc_type(file: str) -> int: + return run_tc(file, "--typed") + +class TestType: + @pytest.mark.parametrize("file", Testsuite.GOOD.value) + def test_type_good(self, file: str): + assert run_tc_type(file) == 0 + + @pytest.mark.parametrize("file", Testsuite.TYPE.value) + def test_type_error(self, file: str): + assert run_tc_type(file) == 5 -- cgit v1.2.3