Files
Aislo/resources/tester/test_haul_state_natural.py
T
eomsangdonandClaude Opus 5 0ef32b5279 chore(tester): 시험을 resources/tester/ 로 옮김 — 창끼리 건너가게
⚠ **뿌리** — `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>
2026-09-09 17:12:30 +09:00

129 lines
4.9 KiB
Python

"""운반 물량의 **상태** — 내역서 수량은 자연상태다 (2026-09-09).
「운반거리의 산정 시에 모든 수량은 다짐상태로 환산하여 계산하고, 내역서에 적용하는
수량은 자연상태로 한다」(설계실무 요령 — `config_system_design` 5-4-3 인용문).
⚠ 이 시험이 잠그는 것은 **방향**이다. 곱하면 토사가 0.9배가 되어 뒤집힌다.
⚠ `L`(1.3·1.35·1.625)을 쓰지 않는다는 것도 함께 잠근다 — 품셈이 `f = 1/L` 을 스스로 곱한다.
"""
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 B08_Quantity.B08_Quantity_Engine_EarthworkSummary import ( # noqa: E402
SummaryInput,
build_table as build_summary,
)
from B08_Quantity.B08_Quantity_Engine_HaulSummary import ( # noqa: E402
build_table,
natural_m3,
summary_input_rows,
)
from config.config_system_design import EARTHWORK_CONVERSION_FACTORS # noqa: E402
_PLAN = {
"blocks": [
{
"bands": [
{
"equipment": "dozer",
"haul_distance_m": 40.0,
"haul_from_m": 0.0,
"haul_to_m": 40.0,
"ea_m3": 90.0,
"rr_m3": 115.0,
"br_m3": 0.0,
},
{
"equipment": "dump_truck",
"haul_distance_m": 300.0,
"haul_from_m": 0.0,
"haul_to_m": 300.0,
"ea_m3": 0.0,
"rr_m3": 0.0,
"br_m3": 130.0,
},
]
}
],
"transfers": [],
}
def _row(table: dict, equipment: str, ground: str) -> dict:
return next(
row for row in table["rows"] if row["equipment"] == equipment and row["ground"] == ground
)
def test_나누기다_곱하기가_아니다() -> None:
for ground, kind in (("토사", "soil"), ("리핑암", "ripping_rock"), ("발파암", "blasting_rock")):
factor = EARTHWORK_CONVERSION_FACTORS[kind]["compacted"]
assert natural_m3(100.0, ground) == pytest.approx(100.0 / factor)
# 방향이 뒤집히면 이 줄이 잡는다.
assert natural_m3(100.0, ground) != pytest.approx(100.0 * factor)
# 토사는 늘고(÷0.9) 암은 준다(÷1.15·÷1.30) — 부호가 갈래마다 다르다.
assert natural_m3(100.0, "토사") > 100.0
assert natural_m3(100.0, "리핑암") < 100.0
assert natural_m3(100.0, "발파암") < 100.0
def test_L_은_쓰지_않는다() -> None:
"""품셈 10-11·10-12 가 `f = 1/L` 을 스스로 곱하므로 우리가 또 들면 두 번 환산이다."""
for ground, loose in (("토사", 1.3), ("리핑암", 1.35), ("발파암", 1.625)):
assert natural_m3(100.0, ground) != pytest.approx(100.0 / loose)
def test_갈래를_모르면_환산하지_않는다() -> None:
assert natural_m3(100.0, "지반모름") is None
assert natural_m3(100.0, "") is None
def test_네_줄이_두_상태를_함께_낸다() -> None:
table = build_table(_PLAN)
dozer_soil = _row(table, "dozer", "토사")
assert dozer_soil["volume_m3"] == pytest.approx(90.0)
assert dozer_soil["volume_basis"] == "compacted"
assert dozer_soil["natural_m3"] == pytest.approx(100.0) # 90 ÷ 0.90
assert dozer_soil["conversion_c"] == pytest.approx(0.90)
assert _row(table, "dozer", "리핑암")["natural_m3"] == pytest.approx(100.0) # 115 ÷ 1.15
assert _row(table, "dump_truck", "발파암")["natural_m3"] == pytest.approx(100.0) # 130 ÷ 1.30
# 거리는 다짐 기준 그대로 — 환산이 거리를 건드리면 안 된다.
assert dozer_soil["average_distance_m"] == pytest.approx(40.0)
def test_집계표는_자연상태로_싣는다() -> None:
haul = build_table(_PLAN)
summary = build_summary(
SummaryInput(
earthwork_totals={},
slope_totals={},
haul_rows=summary_input_rows(haul),
rock_classes=[],
rock_ratios_pct={},
application_ratios={},
)
)
rows = [row for row in summary["rows"] if row["group"] in ("도자운반", "덤프운반")]
assert rows, "운반 줄이 서야 한다"
for row in rows:
assert row["amount"] == pytest.approx(100.0), row
assert "자연상태 환산" in row["note"]
def test_검산은_다짐상태끼리_한다() -> None:
"""환산값으로 검산하면 늘 어긋난다 — 계획이 다짐이기 때문이다."""
from B08_Quantity.B08_Quantity_Engine_HaulSummary import check_against_plan
plan = dict(_PLAN, hauled_m3=335.0, transferred_m3=0.0)
check = check_against_plan(build_table(plan), plan)
assert check.difference_m3 == pytest.approx(0.0)