"""PLAN 190-1 — B06 집수정 고르기 판정면 = 부재 외곽 가상 사각형(세월교 측벽 ㄴ 꼴 · 79-6). 짝: `B06_Section/B06_Section_UI_Cross_Culvert.ts`(집수정 판정면) · `_Cross_Ford.ts`(측벽 판정면) · `_Cross_Culvert_Types.ts`(`outlineBox` 한 벌). [상세] 모달은 카드 그림 복제라 같은 판정면을 가짐. 실제 TS 를 `helper_190_1_basin_pick.cjs` 가 Node 로 돌린다. """ from __future__ import annotations import json import os import subprocess import pytest HERE = os.path.dirname(__file__) ROOT = os.path.join(HERE, "..", "..") pytestmark = pytest.mark.skipif( not os.path.isdir(os.path.join(ROOT, "config", "node_modules")), reason="프론트엔드 의존성 미설치", ) @pytest.fixture(scope="module") def out() -> dict: proc = subprocess.run( # noqa: S603 — 고정 실행 파일 ["node", os.path.join(HERE, "helper_190_1_basin_pick.cjs")], capture_output=True, text=True, encoding="utf-8", timeout=60, ) assert proc.returncode == 0, proc.stderr return json.loads(proc.stdout) def _src(rel: str) -> str: with open(os.path.join(ROOT, rel), encoding="utf-8") as f: return f.read() @pytest.mark.parametrize("shape,parts", [("U", 3), ("L", 2), ("I", 1)]) def test_집수정_판정면은_외곽_사각_하나(out, shape, parts) -> None: case = out[shape] assert case["shape"] == shape and case["parts"] == parts assert case["basinHits"] == 1 # 부재마다가 아니라 한 장 assert case["corners"] == 4 for key in ("minX", "maxX", "minY", "maxY"): assert case["got"][key] == pytest.approx(case["expect"][key], abs=1e-9) @pytest.mark.parametrize("shape", ["U", "L", "I"]) def test_누르면_집수정_고름(out, shape) -> None: case = out[shape] assert case["picked"] == ["inlet"] assert case["stopped"] is True # 카드 고름으로 안 번짐 assert case["lastHitIsBasin"] is True # 맨 위 — 관 판정면보다 위 @pytest.mark.parametrize("shape", ["U", "L", "I"]) def test_그림_모양은_그대로(out, shape) -> None: case = out[shape] assert case["drawnParts"] == case["parts"] assert case["drawnSame"] is True assert case["activeOnInlet"] is True def test_외곽_사각_함수(out) -> None: box = [(p["offset"], p["elevation"]) for p in out["outline"]] assert box == [(1.5, 2.3), (0, 2.3), (0, 0), (1.5, 0)] def test_고름_없으면_판정면_없음(out) -> None: assert out["noSelectHits"] == 0 # B07 등 onSelect 없는 그림 def test_세월교_측벽과_같은_함수() -> None: types = _src("B06_Section/B06_Section_UI_Cross_Culvert_Types.ts") assert "export function outlineBox(points: OffsetPoint[]): OffsetPoint[] {" in types ford = _src("B06_Section/B06_Section_UI_Cross_Ford.ts") assert 'polygon(outlineBox(points), "b06-chart__culvert-revet-hit", "")' in ford assert "Math.max(...elevations)" not in ford # 측벽 외곽 따로 셈 없음 culvert = _src("B06_Section/B06_Section_UI_Cross_Culvert.ts") assert "outlineBox(basinPoints)" in culvert