diff --git a/tested/languages/typescript/config.py b/tested/languages/typescript/config.py index 4e310bbd..71783984 100644 --- a/tested/languages/typescript/config.py +++ b/tested/languages/typescript/config.py @@ -112,14 +112,16 @@ def compilation(self, files: list[str], directory: Path) -> CallbackResult: # Create a config file to just that extends tsconfig. # This way it will only run tsc on the current file. - config_file = { - "extends": str(Path(__file__).parent / "tsconfig.json"), - "include": [f"{main_file[0]}"], - } - with open(str(directory / "tsconfig-sub.json"), "w") as file: - file.write(json.dumps(config_file, indent=4)) if main_file: + + config_file = { + "extends": str(Path(__file__).parent / "tsconfig.json"), + "include": [f"{main_file[0]}"], + } + with open(str(directory / "tsconfig-sub.json"), "w") as file: + file.write(json.dumps(config_file, indent=4)) + return ( [ "tsc", diff --git a/tests/testTypeScriptAstParserFile.ts b/tests/testTypeScriptAstParserFile.ts new file mode 100644 index 00000000..bae1efab --- /dev/null +++ b/tests/testTypeScriptAstParserFile.ts @@ -0,0 +1,43 @@ +// Test ObjectPattern +const {c, d} = {c: 5, d: 7}; +// Test Array Pattern +let [a, b] = ["alpha", "beta"]; +// Test normal variables +var x = 5, y = 6; +// Test first reassignment +x = y; + +// Test function +function demoFunction() { +} + +// Test simple class +class SimpleClass { + constructor() { + } +} + +// Test class with static variables +class StaticClass extends SimpleClass { + data = ["Static data"]; + constants; +} + +// Test try-catch +function tryCatch() { + try { + let demo = 5; + } catch { + // Do nothing + } +} + +// Test async function +async function asyncFunction() { + return 5; +} + +// Test second Reassignment +x = 5; +// Assignment to not defined var +z = x + y; diff --git a/tests/test_serialisation.py b/tests/test_serialisation.py index bf86a12c..8feec03b 100644 --- a/tests/test_serialisation.py +++ b/tests/test_serialisation.py @@ -62,6 +62,7 @@ "java", "c", "javascript", + "typescript", "kotlin", pytest.param("runhaskell", marks=pytest.mark.haskell), "bash", diff --git a/tests/test_stacktrace_cleaners.py b/tests/test_stacktrace_cleaners.py index 8b284c76..6c1cd844 100644 --- a/tests/test_stacktrace_cleaners.py +++ b/tests/test_stacktrace_cleaners.py @@ -55,6 +55,26 @@ def test_javascript_assertion_error(): actual_cleaned = language_config.cleanup_stacktrace(original) assert actual_cleaned == expected_cleaned +def test_typescript_assertion_error(): + workdir = "/home/bliep/bloep/universal-judge/workdir" + language_config = get_language(workdir, "typescript") + original = f"""AssertionError [ERR_ASSERTION]: ongeldig bericht + at bigram2letter ({workdir}/execution00/submission.ts:86:13) + at {workdir}/execution00/submission.ts:98:32 + at Array.map () + at Codeersleutel.decodeer ({workdir}/execution00/submission.ts:98:18) + at context0 ({workdir}/execution00/execution00.ts:78:31) + at async {workdir}/execution00/execution00.ts:1515:13 +""" + expected_cleaned = f"""AssertionError [ERR_ASSERTION]: ongeldig bericht + at bigram2letter (:86:13) + at :98:32 + at Array.map () + at Codeersleutel.decodeer (:98:18) +""" + actual_cleaned = language_config.cleanup_stacktrace(original) + assert actual_cleaned == expected_cleaned + def test_javascript_type_error(): workdir = "/home/bliep/bloep/universal-judge/workdir" @@ -74,6 +94,24 @@ def test_javascript_type_error(): actual_cleaned = language_config.cleanup_stacktrace(original) assert actual_cleaned == expected_cleaned +def test_typescript_type_error(): + workdir = "/home/bliep/bloep/universal-judge/workdir" + language_config = get_language(workdir, "typescript") + original = f"""TypeError: submission.Codeersleutel is not a constructor + at context0 ({workdir}/execution00/execution00.ts:46:17) + at {workdir}/execution00.ts:1515:19 + at Object. ({workdir}/execution00/execution00.ts:1573:7) + at Module._compile (node:internal/modules/cjs/loader:1254:14) + at Module._extensions..ts (node:internal/modules/cjs/loader:1308:10) + at Module.load (node:internal/modules/cjs/loader:1117:32) + at Module._load (node:internal/modules/cjs/loader:958:12) + at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) + at node:internal/main/run_main_module:23:47 + """ + expected_cleaned = f"TypeError: Codeersleutel is not a constructor\n" + actual_cleaned = language_config.cleanup_stacktrace(original) + assert actual_cleaned == expected_cleaned + @pytest.mark.parametrize("language", ALL_LANGUAGES) def test_empty_stacktrace(language): diff --git a/tests/test_utils.py b/tests/test_utils.py index ea4a00f5..a21fda91 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -44,6 +44,37 @@ def test_javascript_ast_parse(): namings = frozenset(output.stdout.strip().split(", ")) assert namings == expected +def test_typescript_ast_parse(): + expected = frozenset( + [ + "c", + "d", + "a", + "b", + "x", + "y", + "demoFunction", + "SimpleClass", + "StaticClass", + "tryCatch", + "z", + "asyncFunction", + ] + ) + from tested.judge.utils import run_command + + test_dir = Path(__file__).parent + parse_file = test_dir.parent / "tested" / "languages" / "typescript" / "parseAst.js" + demo_file = test_dir / "testTypeScriptAstParserFile.ts" + output = run_command( + demo_file.parent, + timeout=None, + command=["tsx", str(parse_file), str(demo_file.absolute())], + ) + assert output + namings = frozenset(output.stdout.strip().split(", ")) + assert namings == expected + def test_run_doctests_tested_utils(): import doctest