Reject oncology, cancer, drug, and target imports in the UI.
CONTENT-WP-0002-T07 checks every import statement and the navigation labels of both fixtures. Assistant: grok Assistant-Session: 01a1346c-fdff-7741-b1af-b7283661554b
This commit is contained in:
parent
08a9a787a7
commit
f434773fd0
4 changed files with 116 additions and 21 deletions
64
tests/test_ui_boundary.py
Normal file
64
tests/test_ui_boundary.py
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
"""The generic UI must not import oncology, cancer, drug, or target modules."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import json
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
EXAMPLES = ROOT / "examples" / "dataspaces"
|
||||
FORBIDDEN = r"\b(?:oncology|cancers?|drugs?|targets?)"
|
||||
|
||||
spec = importlib.util.spec_from_file_location("check_ui_boundary", ROOT / "scripts" / "check_ui_boundary.py")
|
||||
boundary = importlib.util.module_from_spec(spec)
|
||||
assert spec.loader is not None
|
||||
spec.loader.exec_module(boundary)
|
||||
|
||||
|
||||
class UiBoundary(unittest.TestCase):
|
||||
def test_rejects_domain_imports(self) -> None:
|
||||
samples = [
|
||||
'import { CancerIcon } from "@/components/icons";',
|
||||
'import {\n drug\n} from "@/lib/rows";',
|
||||
'const rows = import("./targets/list");',
|
||||
'@import "oncology.css";',
|
||||
]
|
||||
for sample in samples:
|
||||
with self.subTest(sample=sample):
|
||||
self.assertTrue(boundary.import_problems(sample, "sample"))
|
||||
|
||||
def test_allows_generic_imports_and_event_target(self) -> None:
|
||||
sample = """
|
||||
import { findKind } from "@/lib/catalog";
|
||||
const node = event.target;
|
||||
// cancer stays out of the module graph
|
||||
"""
|
||||
self.assertEqual(boundary.import_problems(sample, "sample"), [])
|
||||
|
||||
def test_shipped_ui_has_no_domain_imports(self) -> None:
|
||||
self.assertEqual(boundary.tree_problems(), [])
|
||||
|
||||
def test_navigation_labels_are_not_domain_terms(self) -> None:
|
||||
import re
|
||||
|
||||
forbidden = re.compile(FORBIDDEN, re.IGNORECASE)
|
||||
names = sorted(path.name for path in EXAMPLES.iterdir() if (path / "snapshot.json").is_file())
|
||||
self.assertGreaterEqual(len(names), 2)
|
||||
for name in names:
|
||||
snapshot = json.loads((EXAMPLES / name / "snapshot.json").read_text(encoding="utf-8"))
|
||||
manifest = json.loads((EXAMPLES / name / "manifest.json").read_text(encoding="utf-8"))
|
||||
labels = [snapshot["dataspace"]["title"]]
|
||||
labels.extend(kind["id"] for kind in snapshot["kinds"])
|
||||
labels.extend(kind["label"] for kind in snapshot["kinds"])
|
||||
labels.extend(kind["plural"] for kind in snapshot["kinds"])
|
||||
for section in manifest.get("navigation", []):
|
||||
labels.append(section["label"])
|
||||
for label in labels:
|
||||
with self.subTest(dataspace=name, label=label):
|
||||
self.assertIsNone(forbidden.search(label))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue