"""포장 구간 재계산이 **사용자 값을 지우지 않는지**. 왜 (실사고 `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, "포장 구간 재계산은 포장으로 켜야 함"