⚠ **뿌리** — `tmp/` 는 창 사이에 안 건너감(실측 확인: 상대 창이 놓은 `tmp/_sync_probe.txt` 가 시간을 두고 두 번 봐도 안 보임). 그래서 **정본(등록부 스키마)만 건너가고 그것을 읽는 시험은 안 건너가** 오늘 두 번, 같은 시험이 **연 창은 통과·받은 창은 실패**가 됐음. - `tmp/tests/*` 를 `resources/tester/` 로 **복사**(127 파일). 내용은 **한 줄도 안 고침** - `tmp/tests` 는 **남겨 둠** — 되돌릴 자리(사용자 지시) - 실행: `./venv/Scripts/python.exe -m pytest resources/tester/ -q` 옮기기 전과 **같은 수**: 617 통과 / 22 건너뜀 / 실패 0 ⇒ 이제 시험·예외·까닭이 **정본과 함께** 움직임. 오늘 세운 「예외는 정본 스키마에」와 짝임. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
111 lines
4.2 KiB
Python
111 lines
4.2 KiB
Python
"""측구터파기 단면적을 토사/암으로 가르는 규칙 (2026-09-09).
|
||
|
||
별표2 Ⅰ.1.나.(5) 「측구터파기 단면적」이 횡단도 표의 법정 칸이라 반만 채워 나가면 안 된다.
|
||
⚠ **새 입력을 만들지 않는다** — 절토 분리와 같은 근거(지반 유형 + 암반 경계선)를 쓰고,
|
||
근거가 없으면 **나누지 않고 사유를 낸다**. 절반을 임의로 가르는 것이 가장 나쁘다.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
import pytest
|
||
|
||
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_Areas import _split_ditch_area # noqa: E402
|
||
from B06_Section.B06_Section_Engine_Design import compute_cross_design # noqa: E402
|
||
|
||
_STANDARD = {"type": "standard", "top_width_m": 0.9, "bottom_width_m": 0.3, "depth_m": 0.3}
|
||
_L_TYPE = {"type": "l_type", "width_m": 0.6, "depth_m": 0.3}
|
||
_TOTAL_STANDARD = (0.9 + 0.3) / 2 * 0.3
|
||
|
||
|
||
def test_경계선이_바닥보다_깊으면_전량_토사() -> None:
|
||
soil, rock = _split_ditch_area(_STANDARD, 5.0)
|
||
assert soil == pytest.approx(_TOTAL_STANDARD)
|
||
assert rock == pytest.approx(0.0)
|
||
|
||
|
||
def test_경계선이_상단_위면_전량_암() -> None:
|
||
soil, rock = _split_ditch_area(_STANDARD, -1.0)
|
||
assert soil == pytest.approx(0.0)
|
||
assert rock == pytest.approx(_TOTAL_STANDARD)
|
||
|
||
|
||
def test_중간이면_사다리꼴을_가로로_가른다() -> None:
|
||
"""깊이 절반 지점 — 위쪽이 넓어 토사분이 절반보다 크다."""
|
||
soil, rock = _split_ditch_area(_STANDARD, 0.15)
|
||
assert soil + rock == pytest.approx(_TOTAL_STANDARD)
|
||
assert soil > _TOTAL_STANDARD / 2 # 위가 넓다
|
||
# 폭 W(d) = 0.9 − 2·d 를 0~0.15 적분: 0.9·0.15 − 2·0.15²/2
|
||
assert soil == pytest.approx(0.9 * 0.15 - (0.9 - 0.3) * 0.15**2 / (2 * 0.3))
|
||
|
||
|
||
def test_L형도_합이_보존된다() -> None:
|
||
total = 0.6 * 0.3 / 2
|
||
for depth in (0.0, 0.1, 0.2, 0.3, 1.0):
|
||
soil, rock = _split_ditch_area(_L_TYPE, depth)
|
||
assert soil + rock == pytest.approx(total), depth
|
||
|
||
|
||
def test_측구가_없으면_둘_다_0() -> None:
|
||
assert _split_ditch_area({"type": "none"}, 0.2) == (0.0, 0.0)
|
||
|
||
|
||
def _ground(slope: float = 0.5) -> list[dict]:
|
||
return [
|
||
{"offset_m": offset / 2.0, "elevation_m": 100.0 - (offset / 2.0) * slope}
|
||
for offset in range(-24, 25)
|
||
]
|
||
|
||
|
||
def test_토사_지반은_전량_토사이고_사유가_남는다() -> None:
|
||
result = compute_cross_design(_ground(), 100.0, ground_type="soil", section_mode="left_cut")
|
||
assert result["ditch_split_basis"] in {"soil_ground", "no_ditch"}
|
||
assert result["ditch_rock_area_m2"] == 0.0
|
||
assert result["ditch_soil_area_m2"] + result["ditch_rock_area_m2"] == pytest.approx(
|
||
result["ditch_area_m2"]
|
||
)
|
||
|
||
|
||
def test_암_지반에_경계선이_없으면_전량_암() -> None:
|
||
result = compute_cross_design(
|
||
_ground(),
|
||
100.0,
|
||
ground_type="ripping_rock",
|
||
section_mode="left_cut",
|
||
rock_boundary_offset_m=None,
|
||
ditch_enabled=True,
|
||
)
|
||
if result["ditch_split_basis"] == "no_ditch":
|
||
pytest.skip("이 표본에는 측구가 안 선다")
|
||
assert result["ditch_split_basis"] == "rock_ground_no_boundary"
|
||
assert result["ditch_soil_area_m2"] == 0.0
|
||
|
||
|
||
def test_암_지반에_경계선이_있으면_그것으로_가른다() -> None:
|
||
result = compute_cross_design(
|
||
_ground(),
|
||
100.0,
|
||
ground_type="ripping_rock",
|
||
section_mode="left_cut",
|
||
rock_boundary_offset_m=0.5,
|
||
ditch_enabled=True,
|
||
)
|
||
if result["ditch_split_basis"] == "no_ditch":
|
||
pytest.skip("이 표본에는 측구가 안 선다")
|
||
assert result["ditch_split_basis"] == "rock_boundary"
|
||
assert result["ditch_soil_area_m2"] + result["ditch_rock_area_m2"] == pytest.approx(
|
||
result["ditch_area_m2"]
|
||
)
|
||
|
||
|
||
def test_합계_키는_그대로_남는다() -> None:
|
||
"""B08 이 읽는 `ditch_area_m2` 를 안 깨뜨린다 — 갈래는 덧붙인 것이다."""
|
||
result = compute_cross_design(_ground(), 100.0, ground_type="soil", section_mode="left_cut")
|
||
assert "ditch_area_m2" in result
|