test: define Guanghan topology contract
Co-Authored-By: Codex <noreply@openai.com>
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
HTML_PATH = ROOT / "data" / "wiki" / "guanghan_topology_demo.html"
|
||||
TIMELINE_PATH = ROOT / "user_input" / "广寒计划" / "Timeline.md"
|
||||
|
||||
CLICKABLE_MODULES = {
|
||||
"core",
|
||||
"habitat-1",
|
||||
"habitat-2",
|
||||
"greenhouse",
|
||||
"laboratory",
|
||||
"power-node",
|
||||
"power-north",
|
||||
"power-east",
|
||||
"power-south",
|
||||
"power-west",
|
||||
"wugang-2",
|
||||
"binglun-1",
|
||||
"binglun-2",
|
||||
"binglun-3",
|
||||
}
|
||||
|
||||
|
||||
class GuanghanTopologySourceTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
cls.html = HTML_PATH.read_text(encoding="utf-8")
|
||||
timeline = TIMELINE_PATH.read_text(encoding="utf-8")
|
||||
cls.ghc05 = timeline.split("GHC-05任务", 1)[1].split("JC-02任务", 1)[0]
|
||||
|
||||
def test_clickable_module_inventory_is_exact(self) -> None:
|
||||
found = set(re.findall(r'data-module="([^"]+)"', self.html))
|
||||
self.assertEqual(found, CLICKABLE_MODULES)
|
||||
|
||||
def test_connection_inventory_matches_approved_topology(self) -> None:
|
||||
self.assertEqual(self.html.count('data-connection="pressurized"'), 2)
|
||||
self.assertIn('data-link="wugang-2--greenhouse"', self.html)
|
||||
self.assertIn('data-link="habitat-1--power-north"', self.html)
|
||||
self.assertNotIn("perimeter-corridor", self.html)
|
||||
|
||||
def test_walkways_and_radiators_are_not_clickable(self) -> None:
|
||||
self.assertNotRegex(
|
||||
self.html,
|
||||
r'<(?:line|path|rect)[^>]+data-connection="pressurized"[^>]+data-module=',
|
||||
)
|
||||
self.assertNotRegex(
|
||||
self.html,
|
||||
r'<(?:g|rect)[^>]+class="[^"]*radiator[^"]*"[^>]+data-module=',
|
||||
)
|
||||
|
||||
def test_future_extensions_exist_only_as_source_comments(self) -> None:
|
||||
comments = "\n".join(re.findall(r"<!--(.*?)-->", self.html, flags=re.S))
|
||||
visible_source = re.sub(r"<!--.*?-->", "", self.html, flags=re.S)
|
||||
for direction in ("north", "east", "west"):
|
||||
self.assertIn(f"FUTURE_EXPANSION_ANCHOR:{direction}", comments)
|
||||
self.assertNotIn("未来北部十字结构", visible_source)
|
||||
self.assertNotIn("未来东部十字结构", visible_source)
|
||||
self.assertNotIn("未来西部十字结构", visible_source)
|
||||
|
||||
def test_every_clickable_module_has_dimensions_field(self) -> None:
|
||||
for module_id in CLICKABLE_MODULES:
|
||||
self.assertRegex(
|
||||
self.html,
|
||||
rf'"{re.escape(module_id)}"\s*:\s*\{{.*?dimensions\s*:',
|
||||
msg=f"{module_id} is missing dimensions",
|
||||
)
|
||||
|
||||
def test_timeline_contains_only_the_two_real_corridors(self) -> None:
|
||||
for incorrect in (
|
||||
"4段加压走道",
|
||||
"居住舱#1↔居住舱#2",
|
||||
"居住舱#2↔实验舱",
|
||||
"实验舱↔温室",
|
||||
"温室↔居住舱#1",
|
||||
"环形加压通路",
|
||||
"8个对接面",
|
||||
"4段加压走道48小时",
|
||||
):
|
||||
self.assertNotIn(incorrect, self.ghc05)
|
||||
self.assertIn("居住舱#1远端对接口", self.ghc05)
|
||||
self.assertIn("电力模块北部", self.ghc05)
|
||||
self.assertIn("温室远端对接口", self.ghc05)
|
||||
self.assertIn("吴刚#2", self.ghc05)
|
||||
self.assertIn("从温室模块远端接口断开", self.ghc05)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user