"""B06 BOX암거 세트(백엔드) 자체검증 — 2026-08-25. 확인 대상: · `_box_set()`이 정본·레지스트리 기본값으로 제원을 만든다(두께는 세월교 승계). · 날개벽 각도가 저판 편측 연장(길이×cos각)을 만든다 — 세월교와 같은 산식. · `attach_culvert_sets()`가 BOX암거를 **소유 측점 한 곳에만** 붙이고 `box` 키로 실어 배수관·세월교 소비처와 섞이지 않는다. """ from __future__ import annotations import math import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[2] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) from B06_Section.B06_Section_Engine_Culvert import ( # noqa: E402 BOX_COVER_M, FORD_SLAB_THICKNESS_M, FORD_WALL_THICKNESS_M, _box_set, attach_culvert_sets, ) def test_box_set_defaults() -> None: """저장 옵션이 없으면 레지스트리 기본 2.0×2.0에 세월교 두께를 얹는다.""" spec = _box_set(None) assert spec["type"] == "box" assert spec["inner_width_m"] == 2.0 assert spec["inner_height_m"] == 2.0 assert spec["wall_thickness_m"] == FORD_WALL_THICKNESS_M assert spec["slab_thickness_m"] == FORD_SLAB_THICKNESS_M assert spec["top_thickness_m"] == FORD_SLAB_THICKNESS_M assert spec["cover_m"] == BOX_COVER_M # 도로 방향 길이 = 내공 폭 + 측벽 두 장. assert spec["span_m"] == 2.0 + 2 * FORD_WALL_THICKNESS_M def test_box_wing_extends_slab() -> None: """저판 편측 연장 = 날개벽 길이 × cos(각도). 세월교와 같은 산식이다.""" spec = _box_set({"body_width_m": 3, "body_height_m": 3, "wing_in_length_m": 2}) assert spec["span_m"] == 3 + 2 * FORD_WALL_THICKNESS_M assert spec["wing_in"]["slab_extend_m"] == round(2 * math.cos(math.radians(45)), 3) def test_attach_box_only_owner_station(tmp_path: Path) -> None: """BOX암거는 **소유 측점 한 곳에만** `box` 키로 붙는다(2026-08-25 사용자 확정). 구체 폭만큼 옆 측점까지 붙이면 횡단도가 한 벌 더 그려지고 3D 솔리드도 겹친다. """ edits = tmp_path / "B04_PreProcess" / "drainage" / "edits" edits.mkdir(parents=True) (edits / "pipe_points.json").write_text( '{"points": [{"chainage_m": 100.0, "facility": "box_culvert", "options": {}}]}', encoding="utf-8", ) sections = [{"chainage_m": value} for value in (98.5, 99.0, 100.0, 101.0, 101.5)] attached = attach_culvert_sets(tmp_path, sections) assert attached == 1 assert [("box" in section) for section in sections] == [False, False, True, False, False] assert all("culvert" not in section and "ford" not in section for section in sections)