from __future__ import annotations import ast from pathlib import Path import unittest SRC = Path(__file__).resolve().parents[2] / "src" / "cmbuyer_client" SCOPED = tuple((SRC / name) for name in ("core", "remote", "localstate")) class StaticBoundaryTests(unittest.TestCase): def test_scoped_modules_do_not_import_device_pdd_or_unapproved_capabilities(self) -> None: forbidden_modules = ("cmbuyer_client.device", "cmbuyer_client.pdd") forbidden_text = ( "ResultSink", "/events", "/fail", "/submission-fence", "/result", "click_permitted", ) for directory in SCOPED: for path in directory.glob("*.py"): text = path.read_text(encoding="utf-8") tree = ast.parse(text) imports = [] for node in ast.walk(tree): if isinstance(node, ast.Import): imports.extend(alias.name for alias in node.names) elif isinstance(node, ast.ImportFrom) and node.module: imports.append(node.module) for module in forbidden_modules: self.assertFalse(any(name.startswith(module) for name in imports), (path, module)) for value in forbidden_text: self.assertNotIn(value, text, (path, value))