⚠ **뿌리** — `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>
110 lines
4.4 KiB
Python
110 lines
4.4 KiB
Python
"""포장 구간 재계산이 **사용자 값을 지우지 않는지**.
|
|
|
|
왜 (실사고 `b6941bd2`) — 포장 구간·세월교 측점은 저장 때 서버가 횡단을 **다시 계산해
|
|
통째로 갈아 끼운다**. 계산이 만들지 않는 값(구조물 조정·다단 구간값 등)은 그 자리에서
|
|
따로 베껴 넣어야 살아남는데, `extra_spans` 가 목록에서 빠져 조용히 사라졌다.
|
|
|
|
이 시험이 보는 것은 **베껴 넣는 그 자리**다. 지형·계획고는 시험 대상이 아니므로 가짜로
|
|
바꿔 끼운다(그 둘은 각자 시험이 있다). 목록 자체가 갈리는 것은
|
|
`test_b06_user_touched_keys.py`, 새 사용자 값이 목록에서 새는 것은
|
|
`test_b06_design_key_split.py` 가 지킨다.
|
|
"""
|
|
|
|
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 import B06_Section_Router_Design as design_mod # noqa: E402
|
|
|
|
USER_VALUES = {
|
|
"display_half_width_m": 12.5,
|
|
"inlet_structure": "L",
|
|
"basin_adjust": {"innerWidthM": 1.5, "innerHeightM": 1.5, "lateralM": 0.5, "slopeM": 0.2},
|
|
"revet_adjust": {"outlet": {"x": 2.0, "d": 0.5, "h": None, "m": None}},
|
|
"ford_adjust": {"inlet": {"heightM": None, "lateralM": 1.0, "slopeM": 0.0}},
|
|
"box_adjust": {"left": {"lengthM": 2.0, "riseM": 0.0}},
|
|
"extra_wall_counts": {"outlet": 2, "basin": 0},
|
|
"extra_spans": {"extra0": {"length_m": 15.0, "before_m": 8.0, "after_m": 7.0}},
|
|
"revet_link_detached": True,
|
|
"revet_follow_grade": False,
|
|
}
|
|
|
|
#: 재계산 인자로 되먹여 살아남는 갈래 — 결과에 그대로 나와야 한다.
|
|
FED_BACK = {
|
|
"ground_type": "soil",
|
|
"section_mode": "right_cut",
|
|
"ditch_side": "left",
|
|
"ditch_type": "l_type",
|
|
"two_stage_slope": False,
|
|
"rock_boundary_offset_m": -1.5,
|
|
}
|
|
|
|
|
|
def _section() -> dict:
|
|
design = {
|
|
"paved": False,
|
|
"status": "ok",
|
|
"pavement_suggested": True,
|
|
**USER_VALUES,
|
|
**FED_BACK,
|
|
}
|
|
return {"chainage_m": 100.0, "samples": [], "design": design}
|
|
|
|
|
|
def _install_fakes(monkeypatch) -> dict:
|
|
"""지형·계획고·포장구간을 가짜로 — 이 시험의 대상은 「값을 베껴 넣는 자리」다."""
|
|
seen: dict = {}
|
|
|
|
def fake_compute(samples, elevation, **kwargs):
|
|
seen.update(kwargs)
|
|
# 계산이 내는 값만 담은 새 설계 — 사용자 값은 하나도 없다(실제 엔진과 같다).
|
|
return {
|
|
"paved": True,
|
|
"cut_area_m2": 1.0,
|
|
"fill_area_m2": 2.0,
|
|
**{
|
|
key: kwargs[key]
|
|
for key in (
|
|
"ground_type",
|
|
"section_mode",
|
|
"ditch_side",
|
|
"ditch_type",
|
|
"two_stage_slope",
|
|
"rock_boundary_offset_m",
|
|
)
|
|
if key in kwargs
|
|
},
|
|
}
|
|
|
|
monkeypatch.setattr(design_mod, "pavement_ranges", lambda root: [(0.0, 200.0)])
|
|
monkeypatch.setattr(design_mod, "compute_cross_design", fake_compute)
|
|
monkeypatch.setattr(design_mod, "design_elevation_from_longitudinal", lambda lon, ch: 100.0)
|
|
monkeypatch.setattr(design_mod, "curve_widening_args", lambda section: {})
|
|
return seen
|
|
|
|
|
|
def test_포장_재계산_뒤에도_사용자_값이_남는다(monkeypatch):
|
|
_install_fakes(monkeypatch)
|
|
sections = [_section()]
|
|
changed = design_mod.enforce_pavement_ranges({}, sections, Path("."), None)
|
|
assert changed == 1, "재계산이 아예 안 돌았음 — 시험 전제가 깨짐"
|
|
result = sections[0]["design"]
|
|
for key, value in USER_VALUES.items():
|
|
assert result.get(key) == value, f"{key} 가 재계산에서 사라짐"
|
|
assert result["status"] == "ok"
|
|
assert result["pavement_suggested"] is True
|
|
assert result["paved"] is True, "포장 구간인데 포장으로 안 바뀜"
|
|
|
|
|
|
def test_되먹임_값이_인자로_실제로_들어간다(monkeypatch):
|
|
"""①갈래는 「인자로 넣어」 지킨다 — 안 넣으면 기본값으로 되돌아간다."""
|
|
seen = _install_fakes(monkeypatch)
|
|
sections = [_section()]
|
|
design_mod.enforce_pavement_ranges({}, sections, Path("."), None)
|
|
for key, value in FED_BACK.items():
|
|
assert seen.get(key) == value, f"{key} 가 재계산 인자로 안 들어감(넘긴 값: {seen.get(key)})"
|
|
assert seen.get("paved") is True, "포장 구간 재계산은 포장으로 켜야 함"
|