feat(tests): add generator tester
This commit is contained in:
@@ -2,6 +2,7 @@ import ast
|
|||||||
import shutil
|
import shutil
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from midas.ast.location import Location
|
from midas.ast.location import Location
|
||||||
import midas.ast.python as p
|
import midas.ast.python as p
|
||||||
@@ -44,14 +45,21 @@ class Generator(p.Stmt.Visitor[ast.stmt], p.Expr.Visitor[ast.expr]):
|
|||||||
self._alias_count: int = 0
|
self._alias_count: int = 0
|
||||||
self._scopes: list[Scope] = []
|
self._scopes: list[Scope] = []
|
||||||
|
|
||||||
def generate(self, typed_ast: TypedAST, src_path: Path) -> Path:
|
def generate_ast(self, typed_ast: TypedAST, src_path: Path) -> ast.AST:
|
||||||
self.rel_src_path = src_path.relative_to(self.workdir)
|
self.rel_src_path = src_path.relative_to(self.workdir)
|
||||||
self._typed_ast = typed_ast
|
self._typed_ast = typed_ast
|
||||||
body: list[ast.stmt] = self._visit_body(typed_ast.stmts)
|
body: list[ast.stmt] = self._visit_body(typed_ast.stmts)
|
||||||
module = ast.Module(body=body, type_ignores=[])
|
module = ast.Module(body=body, type_ignores=[])
|
||||||
module = ast.fix_missing_locations(module)
|
module = ast.fix_missing_locations(module)
|
||||||
|
return module
|
||||||
|
|
||||||
|
def generate(
|
||||||
|
self, typed_ast: TypedAST, src_path: Path, out_path: Optional[Path] = None
|
||||||
|
) -> Path:
|
||||||
|
module: ast.AST = self.generate_ast(typed_ast, src_path)
|
||||||
compiled: str = ast.unparse(module)
|
compiled: str = ast.unparse(module)
|
||||||
out_path: Path = (self.build_dir / self.rel_src_path).resolve()
|
if out_path is None:
|
||||||
|
out_path = (self.build_dir / self.rel_src_path).resolve()
|
||||||
try:
|
try:
|
||||||
_ = out_path.relative_to(self.build_dir)
|
_ = out_path.relative_to(self.build_dir)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ class Tester(ABC):
|
|||||||
@abstractmethod
|
@abstractmethod
|
||||||
def namespace(self) -> str: ...
|
def namespace(self) -> str: ...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def extension(self) -> str:
|
||||||
|
return "json"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def base_dir(self) -> Path:
|
def base_dir(self) -> Path:
|
||||||
return self.CASES_DIR / self.namespace
|
return self.CASES_DIR / self.namespace
|
||||||
@@ -99,7 +103,7 @@ class Tester(ABC):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def _result_path(self, test_path: Path) -> Path:
|
def _result_path(self, test_path: Path) -> Path:
|
||||||
return test_path.parent / (test_path.name + ".ref.json")
|
return test_path.parent / (test_path.name + f".ref.{self.extension}")
|
||||||
|
|
||||||
def _print_diff(self, diff: Iterator[str]):
|
def _print_diff(self, diff: Iterator[str]):
|
||||||
for line in diff:
|
for line in diff:
|
||||||
|
|||||||
55
tests/generator.py
Normal file
55
tests/generator.py
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import ast
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from midas.checker.checker import TypeChecker
|
||||||
|
from midas.checker.diagnostic import DiagnosticType
|
||||||
|
from midas.generator.generator import Generator
|
||||||
|
from midas.utils import TypedAST
|
||||||
|
from tests.base import Tester
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class CaseResult:
|
||||||
|
compiled_ast: ast.AST = ast.Module([], [])
|
||||||
|
|
||||||
|
def dumps(self) -> str:
|
||||||
|
return ast.dump(self.compiled_ast, indent=2)
|
||||||
|
|
||||||
|
|
||||||
|
class GeneratorTester(Tester):
|
||||||
|
@property
|
||||||
|
def namespace(self) -> str:
|
||||||
|
return "generator"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def extension(self) -> str:
|
||||||
|
return "txt"
|
||||||
|
|
||||||
|
def _list_tests(self) -> list[Path]:
|
||||||
|
return list(self.base_dir.rglob("*.py"))
|
||||||
|
|
||||||
|
def _exec_case(self, path: Path) -> CaseResult:
|
||||||
|
if not path.exists():
|
||||||
|
raise FileNotFoundError(f"Could not find test '{path}'")
|
||||||
|
if not path.is_file():
|
||||||
|
raise TypeError(f"Test '{path}' is not a file")
|
||||||
|
|
||||||
|
result: CaseResult = CaseResult()
|
||||||
|
|
||||||
|
checker = TypeChecker()
|
||||||
|
types_path: Path = path.with_suffix(".midas")
|
||||||
|
if types_path.exists():
|
||||||
|
checker.import_midas(types_path)
|
||||||
|
|
||||||
|
typed_ast: TypedAST = checker.type_check(path)
|
||||||
|
|
||||||
|
if not any(d.type == DiagnosticType.ERROR for d in checker.diagnostics):
|
||||||
|
generator = Generator(workdir=path.parent)
|
||||||
|
result.compiled_ast = generator.generate_ast(typed_ast, path)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
GeneratorTester.main()
|
||||||
Reference in New Issue
Block a user