"""토량환산계수를 「고를 수 있는 값」으로 연 자리 검사 (오솔길 대조 06절 3번). 못 박는 것 셋 ① **기본값이 안 바뀐다** — 안 고른 프로젝트는 정본 그대로 선다. ② 고른 값은 **토적표·운반표가 같이** 읽는다(계수 정의처는 여전히 한 곳). ③ 품셈 범위 **밖도 막지 않는다** — 사유와 함께 선다. """ from __future__ import annotations import sys from pathlib import Path import pytest ROOT = Path(__file__).resolve().parents[2] sys.path.insert(0, str(ROOT)) from B08_Quantity.B08_Quantity_Engine_EarthworkTable import ( # noqa: E402 StationArea, build_rows, ) from B08_Quantity.B08_Quantity_Engine_HaulSummary import natural_m3 # noqa: E402 from common_util.common_util_project_settings import ( # noqa: E402 default_settings, earthwork_conversion_choices, earthwork_conversion_factors, ) from config.config_system_design import ( # noqa: E402 EARTHWORK_CONVERSION_C_RANGES, EARTHWORK_CONVERSION_FACTORS, ) def test_안_고르면_기본값이_그대로() -> None: """빈 설정·기본 설정 둘 다 정본과 한 글자도 달라지지 않아야 한다.""" assert earthwork_conversion_factors({}) == EARTHWORK_CONVERSION_FACTORS assert earthwork_conversion_factors(default_settings()["quantity"]) == ( EARTHWORK_CONVERSION_FACTORS ) def test_고른_갈래만_갈아_끼움() -> None: settings = {"conversion_factors_override": {"ripping_rock": {"compacted": 1.0}}} resolved = earthwork_conversion_factors(settings) assert resolved["ripping_rock"]["compacted"] == pytest.approx(1.0) # 나머지 갈래는 정본 그대로다. assert resolved["soil"] == EARTHWORK_CONVERSION_FACTORS["soil"] assert resolved["blasting_rock"] == EARTHWORK_CONVERSION_FACTORS["blasting_rock"] # ⚠ 정본 dict 를 건드리지 않았는가 — 얕은 복사였다면 여기서 걸린다. assert EARTHWORK_CONVERSION_FACTORS["ripping_rock"]["compacted"] == pytest.approx(1.15) def test_모르는_갈래와_말이_안_되는_값은_버림() -> None: settings = { "conversion_factors_override": { "unknown_rock": {"compacted": 2.0}, "soil": {"compacted": 0}, "blasting_rock": {"compacted": "많이"}, } } assert earthwork_conversion_factors(settings) == EARTHWORK_CONVERSION_FACTORS def test_토적표가_고른_계수로_섬() -> None: """오솔길처럼 암 계수 1.0 을 고르면 보정량이 그 값으로 선다.""" stations = [ StationArea(chainage_m=0.0), StationArea(chainage_m=10.0, cut_rock_area_m2=2.0, cut_rock_kind="ripping_rock"), ] factors = earthwork_conversion_factors( {"conversion_factors_override": {"ripping_rock": {"compacted": 1.0}}} ) row = build_rows(stations, factors)[1] assert row.cut_rock_volume_m3 == pytest.approx(10.0) assert row.cut_rock_adjusted_m3 == pytest.approx(10.0) # 기본값 1.15 였다면 11.5 # 안 주면 기본값 — 같은 측점이 11.5 로 선다. assert build_rows(stations)[1].cut_rock_adjusted_m3 == pytest.approx(11.5) def test_운반표도_같은_계수를_씀() -> None: """다짐 → 자연 되돌리기(÷C)도 고른 값으로 돌아야 표끼리 안 갈린다.""" factors = earthwork_conversion_factors( {"conversion_factors_override": {"ripping_rock": {"compacted": 1.0}}} ) assert natural_m3(11.5, "리핑암", factors) == pytest.approx(11.5) assert natural_m3(11.5, "리핑암") == pytest.approx(11.5 / 1.15) def test_범위_밖도_막지_않고_사유와_함께_섬() -> None: low, _high = EARTHWORK_CONVERSION_C_RANGES["blasting_rock"] settings = { "conversion_factors_override": { "blasting_rock": {"compacted": low - 0.5, "reason": "토질시험 값"} } } resolved = earthwork_conversion_factors(settings) assert resolved["blasting_rock"]["compacted"] == pytest.approx(low - 0.5) choice = earthwork_conversion_choices(settings)["blasting_rock"] assert choice["chosen"] is True assert choice["in_range"] is False # 밖이라고 말은 하되 값은 그대로 선다. assert choice["reason"] == "토질시험 값" def test_선택_상태는_기본값과_범위를_함께_냄() -> None: choice = earthwork_conversion_choices({})["ripping_rock"] assert choice["chosen"] is False assert choice["in_range"] is True assert choice["default"] == pytest.approx(1.15) assert choice["range"] == [1.00, 1.30]