"""Regression tests: deleted types must not be re-introduced.""" import ast from pathlib import Path import cm_inst import tokens PROJECT_ROOT = Path(__file__).resolve().parent.parent DELETED_NAMES = frozenset({ "SysToken", "CfgToken", "IOToken", "LoadInstToken", "RouteSetToken", "CfgOp", }) class TestAC1_DeletedTypesAbsent: """AC1: Old token types and CfgOp must not exist.""" def test_no_sys_token(self): """SysToken must not exist in tokens module.""" assert not hasattr(tokens, 'SysToken') def test_no_cfg_token(self): """CfgToken must not exist in tokens module.""" assert not hasattr(tokens, 'CfgToken') def test_no_io_token(self): """IOToken must not exist in tokens module.""" assert not hasattr(tokens, 'IOToken') def test_no_load_inst_token(self): """LoadInstToken must not exist in tokens module.""" assert not hasattr(tokens, 'LoadInstToken') def test_no_route_set_token(self): """RouteSetToken must not exist in tokens module.""" assert not hasattr(tokens, 'RouteSetToken') def test_no_cfg_op(self): """CfgOp must not exist in cm_inst module.""" assert not hasattr(cm_inst, 'CfgOp') class TestAC1_3NoStaleImports: """AC1.3: No module in the codebase imports any deleted type.""" def test_no_production_code_imports_deleted_types(self): """Scan all production .py files for import statements referencing deleted names.""" violations = [] for py_file in PROJECT_ROOT.rglob("*.py"): if "test" in py_file.name or py_file.is_relative_to(PROJECT_ROOT / "tests"): continue try: tree = ast.parse(py_file.read_text(), filename=str(py_file)) except SyntaxError: continue for node in ast.walk(tree): if isinstance(node, ast.ImportFrom): for alias in node.names: if alias.name in DELETED_NAMES: violations.append(f"{py_file}:{node.lineno} imports {alias.name}") assert violations == [], f"Stale imports found:\n" + "\n".join(violations) class TestAC7_3_FrameRedesignMigration: """AC7.3: Verify frame-based redesign types are correct; legacy types are gone.""" def test_aluinst_not_in_cm_inst(self): """ALUInst should NOT be importable from cm_inst (replaced by Instruction).""" assert not hasattr(cm_inst, 'ALUInst'), \ "ALUInst should not exist in cm_inst (use Instruction instead)" def test_sminst_not_in_cm_inst(self): """SMInst should NOT be importable from cm_inst (replaced by Instruction).""" assert not hasattr(cm_inst, 'SMInst'), \ "SMInst should not exist in cm_inst (use Instruction instead)" def test_addr_not_in_cm_inst(self): """Addr should NOT be importable from cm_inst (replaced by FrameDest).""" assert not hasattr(cm_inst, 'Addr'), \ "Addr should not exist in cm_inst (use FrameDest instead)" def test_iramwritetoken_not_in_tokens(self): """IRAMWriteToken should NOT be importable from tokens (replaced by PELocalWriteToken).""" assert not hasattr(tokens, 'IRAMWriteToken'), \ "IRAMWriteToken should not exist in tokens (use PELocalWriteToken instead)" def test_matchentry_not_in_emu_types(self): """MatchEntry should NOT be importable from emu.types (frame-based PE doesn't use it).""" from emu import types as emu_types assert not hasattr(emu_types, 'MatchEntry'), \ "MatchEntry should not exist in emu.types (frame-based matching doesn't use it)" def test_instruction_importable_from_cm_inst(self): """Instruction should be importable from cm_inst.""" from cm_inst import Instruction assert Instruction is not None def test_outputstyle_importable_from_cm_inst(self): """OutputStyle should be importable from cm_inst.""" from cm_inst import OutputStyle assert OutputStyle is not None def test_framedest_importable_from_cm_inst(self): """FrameDest should be importable from cm_inst.""" from cm_inst import FrameDest assert FrameDest is not None def test_petoken_importable_from_tokens(self): """PEToken should be importable from tokens.""" from tokens import PEToken assert PEToken is not None def test_perlocalwritetoken_importable_from_tokens(self): """PELocalWriteToken should be importable from tokens.""" from tokens import PELocalWriteToken assert PELocalWriteToken is not None def test_framecontroltoken_importable_from_tokens(self): """FrameControlToken should be importable from tokens.""" from tokens import FrameControlToken assert FrameControlToken is not None