Commit dfc94ae0 authored by Johannes Bechberger's avatar Johannes Bechberger
Browse files

Add JavaCompileTest test type

parent 0918ee9d
...@@ -22,6 +22,7 @@ The default directory that contains all test folders is `tests`. ...@@ -22,6 +22,7 @@ The default directory that contains all test folders is `tests`.
The different types a test cases are differentiated by their file endings. The different types a test cases are differentiated by their file endings.
Side note: An error code greater than 0 should result in an errror message on error output containing the word `error`.
Test types for the syntax mode Test types for the syntax mode
------------------------------ ------------------------------
...@@ -36,9 +37,13 @@ Test types for the syntax mode ...@@ -36,9 +37,13 @@ Test types for the syntax mode
<td><code>.invalid.mj</code> <td><code>.invalid.mj</code>
<td>Return code is <code>&gt; 0</code> and the error output contains the word <code>error</code></td> <td>Return code is <code>&gt; 0</code> and the error output contains the word <code>error</code></td>
</tr> </tr>
<tr>
<td><code>.java</code>
<td>If <code>javac</code> accepts the syntax (and semantic) of the file then the MiniJava compiler
should accept its syntax too.</td>
</tr>
</table> </table>
Test runner Test runner
----------- -----------
......
...@@ -68,7 +68,12 @@ class Environment: ...@@ -68,7 +68,12 @@ class Environment:
logging.basicConfig(level=self.LOG_LEVELS[log_level]) logging.basicConfig(level=self.LOG_LEVELS[log_level])
def create_tmpfile(self) -> str: def create_tmpfile(self) -> str:
return os.path.join(self.tmp_dir, os.times()) return os.path.join(self.tmp_dir, str(os.times()))
def create_tmpdir(self) -> str:
dir = self.create_tmpfile()
os.mkdir(dir)
return dir
def clean_up(self): def clean_up(self):
if not self.own_tmp_dir: if not self.own_tmp_dir:
...@@ -82,4 +87,12 @@ class Environment: ...@@ -82,4 +87,12 @@ class Environment:
:return: (out, err, return code) :return: (out, err, return code)
""" """
cmd = [self.mj_run_cmd] + list(args) cmd = [self.mj_run_cmd] + list(args)
return execute(cmd, timeout=self.timeout) return execute(cmd, timeout=self.timeout)
\ No newline at end of file
def run_command(self, cmd: str, *args: Tuple[str]) -> Tuple[bytes, bytes, int]:
"""
Execute the passend command with its arguments
:return: (out, err, return code)
"""
return execute([cmd] + list(args), timeout=self.timeout)
\ No newline at end of file
from mjtest.environment import Environment, TestMode from mjtest.environment import Environment, TestMode
from mjtest.test.tests import TestCase, TestResult, BasicTestResult from mjtest.test.tests import TestCase, TestResult, BasicTestResult
from os import path from os import path
from mjtest.util.shell import execute
class BasicSyntaxTest(TestCase): class BasicSyntaxTest(TestCase):
...@@ -17,9 +18,35 @@ class BasicSyntaxTest(TestCase): ...@@ -17,9 +18,35 @@ class BasicSyntaxTest(TestCase):
def short_name(self) -> str: def short_name(self) -> str:
return path.basename(self.file)[:-3] return path.basename(self.file)[:-3]
def run(self) -> TestResult: def run(self) -> BasicTestResult:
out, err, rtcode = self.env.run_mj_command("--parsetest ", self.file) out, err, rtcode = self.env.run_mj_command("--parsetest ", self.file)
return BasicTestResult(self, rtcode, out.decode(), err.decode()) return BasicTestResult(self, rtcode, out.decode(), err.decode())
TestCase.TEST_CASE_CLASSES[TestMode.syntax].append(BasicSyntaxTest) TestCase.TEST_CASE_CLASSES[TestMode.syntax].append(BasicSyntaxTest)
class JavaCompileTest(BasicSyntaxTest):
"""
The MiniJava compiler should behave the same as javac
"""
FILE_ENDINGS = [".java"]
def __init__(self, env: Environment, type: str, file: str):
super().__init__(env, type, file)
tmp_dir = self.env.create_tmpdir()
_, self.javac_err, self.javac_rtcode = \
self.env.run_command("javac", file, "-d", tmp_dir)
self._should_succeed = self.javac_rtcode == 0
def short_name(self) -> str:
return path.basename(self.file)
def run(self) -> BasicTestResult:
ret = super().run()
ret.add_additional_text("javac error output", str(self.javac_err))
ret.add_additional_text_line("javac return code", str(self.javac_rtcode))
return ret
TestCase.TEST_CASE_CLASSES[TestMode.syntax].append(JavaCompileTest)
TestCase.TEST_CASE_CLASSES[TestMode.semantic].append(JavaCompileTest)
from collections import namedtuple from collections import namedtuple
import shutil import shutil
from typing import Optional, List, Tuple, T, Union from typing import Optional, List, Tuple, T, Union, Dict
from mjtest.environment import Environment, TestMode, TEST_MODES from mjtest.environment import Environment, TestMode, TEST_MODES
from os.path import join, exists, basename from os.path import join, exists, basename
import logging import logging
...@@ -160,7 +160,8 @@ class TestCase: ...@@ -160,7 +160,8 @@ class TestCase:
""" """
TEST_CASE_CLASSES = { TEST_CASE_CLASSES = {
TestMode.syntax: [] TestMode.syntax: [],
TestMode.semantic: []
} }
FILE_ENDINGS = [] FILE_ENDINGS = []
...@@ -242,6 +243,7 @@ class BasicTestResult(TestResult): ...@@ -242,6 +243,7 @@ class BasicTestResult(TestResult):
self._contains_error_str = "error" in error_output self._contains_error_str = "error" in error_output
self.error_output = error_output self.error_output = error_output
self.output = output self.output = output
self.other_texts = [] # type: List[Tuple[str, str, bool]]
def is_correct(self): def is_correct(self):
if self.succeeded(): if self.succeeded():
...@@ -261,6 +263,17 @@ class BasicTestResult(TestResult): ...@@ -261,6 +263,17 @@ class BasicTestResult(TestResult):
file_content = "" file_content = ""
with open(self.test_case.file, "r") as f: with open(self.test_case.file, "r") as f:
file_content = f.readlines() file_content = f.readlines()
others = []
for title, content, long_text in self.other_texts:
if long_text:
others.append("""
{}:
{}
""".format(title, self._ident(content)))
else:
others.append("""{}: {}\n""".format(title, content))
return """{} return """{}
Source file: Source file:
...@@ -276,8 +289,17 @@ Error output: ...@@ -276,8 +289,17 @@ Error output:
{} {}
Return code: {} Return code: {}
{}
""".format(self.short_message().capitalize(), self._ident(file_content), """.format(self.short_message().capitalize(), self._ident(file_content),
self._ident(self.output), self._ident(self.error_output), self.error_code) self._ident(self.output), self._ident(self.error_output), self.error_code,
"\n".join(others))
def add_additional_text(self, title: str, content: str):
self.other_texts.append((title, content, True))
def add_additional_text_line(self, title: str, content: str):
self.other_texts.append((title, content, False))
def _ident(self, text: Union[str,List[str]]) -> str: def _ident(self, text: Union[str,List[str]]) -> str:
arr = text if isinstance(text, list) else text.split("\n") arr = text if isinstance(text, list) else text.split("\n")
......
import logging import logging
from os import path from os import path
import sys import sys
from typing import Tuple
def get_mjtest_basedir() -> str: def get_mjtest_basedir() -> str:
return path.dirname(path.dirname(path.dirname(path.realpath(__file__)))) return path.dirname(path.dirname(path.dirname(path.realpath(__file__))))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment