"""PLAN 472-4 ② C6 (요구 273) — 맹암거 얹기 거울: TS `common_util_structure_underdrain` ↔ 파이썬 `B06_Section_Engine_Tilt.underdrains_from` · `attach_underdrain_specs`. 못박는 것 - 구조물 목록 → 제원(높이 · 경사 · 빈 값 · 0 · 음수 · 글 · 맹암거 아닌 종류) 두 쪽 같음. - 기준 측점(±0.02 m) 얹기 · 얹은 수 같음. - 알려진 차 하나 — 옛 `underdrain` 이 남은 측점: TS 는 걷음 · 파이썬은 둠 (서버 GET = Node `facility.attach` = TS · 파이썬 짝은 Node 못 부를 때만 · 그 길은 정본 파일을 새로 읽어 옛 값 없음). ./venv/Scripts/python.exe -m pytest resources/tester/test_472_4_underdrain_mirror.py -q """ from __future__ import annotations import copy import json import shutil import subprocess from pathlib import Path import pytest from B05_Profile.B05_Profile_Structures_Schema import StructureInstance from B06_Section.B06_Section_Engine_Tilt import attach_underdrain_specs, underdrains_from HERE = Path(__file__).resolve().parent ROOT = HERE.parents[1] pytestmark = pytest.mark.skipif( not (ROOT / "config" / "node_modules" / "vite").is_dir(), reason="프론트엔드 의존성 미설치", ) def _drain(at: float, **options) -> dict: return { "type_id": "cross_underdrain", "placement": "point", "chainage_m": at, "options": options, } STRUCTURES = [ _drain(40.0, culvert_height_m=1.2, culvert_slope_pct=3), _drain(80.0, culvert_height_m="", culvert_slope_pct="2.5"), _drain(120.0, culvert_height_m=0, culvert_slope_pct=-1), _drain(160.0), {"type_id": "berm", "placement": "interval", "start_m": 0.0, "end_m": 50.0, "options": {}}, ] SECTIONS = [ {"chainage_m": 40.01}, {"chainage_m": 79.99}, {"chainage_m": 120.0}, {"chainage_m": 160.03}, # 0.02 밖 {"chainage_m": 200.0, "underdrain": {"chainage_m": 200.0}}, # 옛 값 — 알려진 차 ] @pytest.fixture(scope="module") def ts(tmp_path_factory) -> dict: work = tmp_path_factory.mktemp("u4724") subprocess.run( # noqa: S603 — 고정 실행 파일 [ "node", str(ROOT / "config" / "node_modules" / "vite" / "bin" / "vite.js"), "build", "--configLoader", "runner", "--ssr", "../resources/tester/helper_472_4_underdrain_entry.ts", "--outDir", str(work), "--logLevel", "error", ], cwd=ROOT, check=True, capture_output=True, timeout=300, ) bundle = work / "bundle.mjs" shutil.copy(work / "helper_472_4_underdrain_entry.js", bundle) job = json.dumps({"structures": STRUCTURES, "sections": SECTIONS}) script = ( f"const m = await import({json.dumps(bundle.as_uri())});" f"const job = {job};" "const specs = m.underdrainSpecsFrom(job.structures);" "const count = m.attachUnderdrainSpecs(job.sections, specs);" "console.log(JSON.stringify({specs, count, sections: job.sections}));" ) out = subprocess.run( # noqa: S603 ["node", "--input-type=module", "-e", script], cwd=ROOT, check=True, capture_output=True, text=True, encoding="utf-8", timeout=60, ) return json.loads(out.stdout) def _python() -> tuple[list[dict], int, list[dict]]: specs = underdrains_from([StructureInstance(**item) for item in STRUCTURES]) sections = copy.deepcopy(SECTIONS) return specs, attach_underdrain_specs(sections, specs), sections def test_제원_같음(ts) -> None: specs, _count, _sections = _python() assert ts["specs"] == specs def test_얹기_같음_알려진_차_하나(ts) -> None: _specs, count, sections = _python() assert ts["count"] == count == 3 assert ts["sections"][:4] == sections[:4] # 알려진 차 — 옛 underdrain: TS 걷음 · 파이썬 둠 assert "underdrain" not in ts["sections"][4] and "underdrain" in sections[4]