Files
Aislo/resources/tester/test_b06_culvert_set.py
T
eomsangdonandClaude Opus 5 8eb1189b4f fix(b05,b06,b08): 기슭막이 벽 높이를 관경 기준 한 값으로 · 폼은 기본값을 값으로 안 보냄
- 한 벽을 두고 값이 셋(등록부·표 H2.5 · 구조물도 H2.5 · 횡단도 관경 기준)이던 결함 — 근거 있는 관경 기준으로 맞춤
- 관 벽 높이 안 적으면 관경 + 여유 0.5 를 0.1m 로 올리고 근입 0.5 더함(Ø800 1.8 · Ø1000 2.0 · Ø1500 2.5)
- 파이썬(B06 엔진)·TS(세트 스펙·횡단 상수) 거울 시험 · 등록부 기본 2.5 걷고 empty_means
- 최소값이라 미확정·금액 밖은 그대로
- B05 벽 칸(관 유입·유출 · 독립 기슭막이)은 비워 두고 회색 제안값 · [제안값 넣기] 누른 때만 값 — 저장 한 번에 미확정이 확정으로 바뀌던 길을 막음
- 전체 시험: 받은 덤프 적재 커밋 몫 2개만 빨강(보고함)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
2026-09-14 09:10:47 +09:00

128 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""B06 배수관 세트(배관·기슭막이·보호공) 엔진 검증.
정본(`pipe_points.json`) + 레지스트리 기본값 조합이 계획서(3-0 근거 표)대로
나오는지, 배관 외 시설(BOX암거 등)이 이번 범위에서 빠지는지 확인한다.
"""
import json
import sys
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parents[2]
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
from B06_Section.B06_Section_Engine_Culvert import ( # noqa: E402
APRON_LENGTH_FACTOR,
APRON_THICKNESS_M,
MIN_PIPE_COVER_M,
REVET_FACE_SLOPE,
_culvert_set,
attach_culvert_sets,
pipe_points_file,
)
def test_cross_reference_constants_match_plan():
"""계획서 3-0 표 값 — 토피 0.5m·보호공 길이 2배·두께 0.45m(사용자 확정)·전면 1:0.3."""
assert MIN_PIPE_COVER_M == 0.5
assert APRON_LENGTH_FACTOR == 2.0
assert APRON_THICKNESS_M == 0.45
assert REVET_FACE_SLOPE == 0.3
# 배관은 수평도 가능 — 세트에 경사 강제값을 싣지 않는다(2026-08-20 사용자 확정).
assert "min_slope" not in _culvert_set(None)
def test_empty_options_fall_back_to_registry_defaults():
"""옵션이 빈 저장분은 레지스트리 기본값(Ø1000·L10)으로 채운다.
높이는 2026-09-14 브레인 판정으로 **관경 기준 최소 높이**(Ø1000 → 1.5 + 근입 0.5 = 2.0) —
횡단도가 그리는 그 높이. 옛 기본 2.5 는 횡단도가 안 쓰던 값이라 걷음.
"""
spec = _culvert_set(None)
assert spec["type"] == "pipe"
assert spec["diameter_m"] == 1.0
assert spec["min_cover_m"] == MIN_PIPE_COVER_M
for side in ("inlet", "outlet"):
part = spec[side]
assert part["structure"] == "기슭막이"
assert part["revet_height_m"] == 2.0
assert part["revet_length_m"] == 10
assert part["face_slope"] == REVET_FACE_SLOPE
# 보호공 = 낙차고(2.0) × 2 = 4.0m, 두께 0.45m(사용자 확정).
assert part["apron_length_m"] == 4.0
assert part["apron_thickness_m"] == 0.45
# 레지스트리 기본 형태: 유입 찰 / 유출 메.
assert spec["inlet"]["revet_form"] == "돌쌓기(찰)"
assert spec["outlet"]["revet_form"] == "돌쌓기(메)"
def test_basin_inlet_skips_revet_and_apron():
"""유입구 = 집수정이면 그쪽 기슭막이·보호공을 만들지 않는다(라벨만)."""
spec = _culvert_set({"inlet_type": "집수정"})
assert spec["inlet"]["structure"] == "집수정"
assert "revet_height_m" not in spec["inlet"]
assert "apron_length_m" not in spec["inlet"]
# 유출측은 그대로 세트를 갖춘다.
assert spec["outlet"]["structure"] == "기슭막이"
assert spec["outlet"]["apron_length_m"] == 4.0 # 관경 기준 높이 2.0 × 2
def test_string_diameter_and_custom_height():
"""관경 문자열 저장분("800")과 사용자 높이 변경이 그대로 반영된다."""
spec = _culvert_set({"pipe_diameter_mm": "800", "outlet_revet_height_m": 1.5})
assert spec["diameter_m"] == 0.8
assert spec["outlet"]["revet_height_m"] == 1.5
assert spec["outlet"]["apron_length_m"] == 3.0 # 1.5 × 2
def test_attach_only_pipe_facilities(tmp_path):
"""배관은 `culvert`, 세월교는 `ford`, BOX암거는 `box` 키로 얹는다.
배관 매칭은 chainage ±0.02m 그대로다. 세월교·BOX암거는 구체 폭만큼 이어져
기준 측점 전후 절반까지 붙는다(2026-08-25 사용자 확정) — 아래 100.0m은
어느 쪽 범위에도 들지 않는다.
"""
target = pipe_points_file(tmp_path)
target.parent.mkdir(parents=True)
target.write_text(
json.dumps(
{
"route_signature": "x",
"points": [
{
"chainage_m": 84.3,
"source": "spacing",
"options": {"pipe_diameter_mm": 1000},
},
{"chainage_m": 149.73, "source": "stream", "facility": "ford_bridge"},
{"chainage_m": 200.92, "source": "spacing", "facility": "box_culvert"},
],
},
ensure_ascii=False,
),
encoding="utf-8",
)
cross_sections = [
{"chainage_m": 84.3, "samples": []},
{"chainage_m": 149.73, "samples": []},
{"chainage_m": 200.92, "samples": []},
{"chainage_m": 100.0, "samples": []},
]
attached = attach_culvert_sets(tmp_path, cross_sections)
assert attached == 3
assert "culvert" in cross_sections[0]
assert cross_sections[0]["culvert"]["diameter_m"] == 1.0
# 세월교·BOX암거는 그림이 달라 키를 나눈다 — 배수관 소비처가 집어가면 안 된다.
assert cross_sections[1]["ford"]["type"] == "ford"
assert cross_sections[2]["box"]["type"] == "box"
assert all("culvert" not in section for section in cross_sections[1:])
assert all("ford" not in section for section in (cross_sections[0], *cross_sections[2:]))
def test_attach_without_file_is_noop(tmp_path):
"""정본 파일이 없으면 아무 것도 얹지 않고 0을 돌려준다."""
sections = [{"chainage_m": 10.0}]
assert attach_culvert_sets(tmp_path, sections) == 0
assert "culvert" not in sections[0]