ast_tests.py 2.58 KB
Newer Older
1 2
import difflib
import os
Johannes Bechberger's avatar
Johannes Bechberger committed
3
import shutil, logging
4
from typing import Tuple, Dict
Johannes Bechberger's avatar
Johannes Bechberger committed
5
from mjtest.environment import Environment, TestMode, TEST_MODES
6
from mjtest.test.syntax_tests import BasicSyntaxTest
7
from mjtest.test.tests import TestCase, BasicDiffTestResult, BasicTestResult
Johannes Bechberger's avatar
Johannes Bechberger committed
8 9
from os import path

10 11
from mjtest.util.utils import decode

Johannes Bechberger's avatar
Johannes Bechberger committed
12 13 14
_LOG = logging.getLogger("tests")


15
class ASTPrettyPrintTest(BasicSyntaxTest):
Johannes Bechberger's avatar
Johannes Bechberger committed
16

17 18
    FILE_ENDINGS = [".mj", ".valid.mj"]
    INVALID_FILE_ENDINGS = [".invalid.mj"]
Johannes Bechberger's avatar
Johannes Bechberger committed
19

20 21
    def __init__(self, env: Environment, type: str, file: str, preprocessed_file: str, log_file_mode: str):
        super().__init__(env, type, file, preprocessed_file, log_file_mode)
Johannes Bechberger's avatar
Johannes Bechberger committed
22 23
        if type != TestMode.ast and TEST_MODES.index(TestMode.ast) < TEST_MODES.index(type):
            self._should_succeed = True
24 25 26

    def run(self) -> BasicTestResult:
        tmp_file = self.env.create_tmpfile()
27
        rtcode, out, err = self._pretty_print(self.preprocessed_file, tmp_file)
28 29 30 31 32 33 34
        if rtcode > 0:
            os.remove(tmp_file)
            return BasicTestResult(self, rtcode, out, err)
        _file = self.file
        tmp_file2 = self.env.create_tmpfile()
        rtcode, out2, err2 = self._pretty_print(tmp_file, tmp_file2)
        if rtcode > 0:
Johannes Bechberger's avatar
Johannes Bechberger committed
35
            os.remove(tmp_file)
36 37 38 39 40
            os.remove(tmp_file2)
            btr = BasicTestResult(self, rtcode, out2, err2)
            btr.add_additional_text("Prior out", out)
            btr.add_additional_text("Prior err", err)
            return btr
Johannes Bechberger's avatar
Johannes Bechberger committed
41 42 43 44

        #out_lex = self._line_count(out_lex.decode())
        #out_lex2 = self._line_count(out_lex2.decode())
        #comp = self._comp_dicts(out_lex, out_lex2)
45
        incorrect_msg, rtcode = "", 0
Johannes Bechberger's avatar
Johannes Bechberger committed
46
        if out2 != out:
47 48 49 50 51
            incorrect_msg, rtcode = "Not idempotent", 1
        btr = BasicTestResult(self, rtcode, incorrect_msg=incorrect_msg)
        btr.add_additional_text("First round output", out)
        btr.add_additional_text("Second round output", out2)
        btr.add_additional_text("Diff", self._diff(out, out2))
Johannes Bechberger's avatar
Johannes Bechberger committed
52 53
        os.remove(tmp_file)
        os.remove(tmp_file2)
54 55 56 57 58 59 60
        return btr

    def _diff(self, first: str, second: str) -> str:
        return "".join(difflib.Differ().compare(first.splitlines(True), second.splitlines(True)))

    def _pretty_print(self, input_file: str, output_file: str) -> Tuple[int, str, str]:
        out, err, rtcode = self.env.run_mj_command(TestMode.ast, input_file)
61
        with open(output_file, "wb") as f:
62
            f.write(out)
Johannes Bechberger's avatar
Johannes Bechberger committed
63
            f.flush()
64
        return rtcode, decode(out), decode(err)
65

66
TestCase.TEST_CASE_CLASSES["ast"].append(ASTPrettyPrintTest)