"""추천 「종단 반영」 켜기 · 끄기(PLAN 64-1) — 점수 분기 시험. ./venv/Scripts/python.exe -m pytest resources/tester/test_64_1_profile_toggle.py -q 켬(기본) = 후보마다 균형 종단을 세워 토공 점수를 그것으로(63-4) · 끔 = 종단 없이 원지반 가늠 (절 + 성). 끈 요청은 켠 요청이 묶음 캐시에 남긴 종단을 걷어 내고 처음부터 끈 것과 같아야 한다. """ import numpy as np import pytest from B05_Profile.B05_Profile_Engine_RouteInitial import Terrain, generate_initial_route from B05_Profile.B05_Profile_Engine_RouteInitial_Metrics import COST_EARTH_M3 from B05_Profile.B05_Profile_Engine_RouteInitial_Pool import GOALS from B05_Profile.B05_Profile_Engine_RouteInitial_Profile import profile_earth from B05_Profile.B05_Profile_Router_Replan import RouteInitialRequest GRADE = 0.14 RADIUS = 12.0 @pytest.fixture(scope="module") def hill() -> Terrain: x = np.arange(0.0, 802.0, 2.0) y = np.arange(0.0, 402.0, 2.0) xx, yy = np.meshgrid(x, y) z = 40.0 * np.exp(-((xx - 400.0) ** 2 + (yy - 200.0) ** 2) / 90.0**2) return Terrain(x, y, z, np.ones(xx.shape, dtype=bool)) def _run(terrain: Terrain, mode: str, with_profile: bool) -> dict: expected = [(float(x), 200.0) for x in np.arange(50.0, 752.0, 4.0)] return generate_initial_route( expected, terrain, [], mode=mode, weights=None, max_grade=GRADE, min_radius_m=RADIUS, with_profile=with_profile, ) @pytest.mark.parametrize("mode", ["earthwork", "cost", "follow"]) def test_켬은_종단_끔은_원지반(hill: Terrain, mode: str) -> None: on = _run(hill, mode, True) off = _run(hill, mode, False) assert on["with_profile"] is True and off["with_profile"] is False assert "error" not in on["metrics"]["profile"] assert "profile" not in off["metrics"] and "earth_estimate_m3" not in off["metrics"] # 끔 점수 = 절 + 성 · 켬 점수 = 균형 종단 토공 assert GOALS["earthwork"](off["metrics"]) == ( off["metrics"]["cut_m3"] + off["metrics"]["fill_m3"], ) assert GOALS["earthwork"](on["metrics"]) == (profile_earth(on["metrics"]["profile"]),) # 공사비 어림 = 켬은 토공 몫을 종단 점수로 바꾼 값(고른 노선이 달라도 그 노선의 처음 값 기준) metrics = on["metrics"] shift = COST_EARTH_M3 * (profile_earth(metrics["profile"]) - metrics["earth_estimate_m3"]) assert metrics["cost_index"] == pytest.approx(metrics["cost_index_base"] + shift, abs=1.0) def test_끈_요청은_묶음_캐시의_종단을_걷어_낸다(hill: Terrain) -> None: first = _run(hill, "cost", False) _run(hill, "cost", True) # 같은 묶음 캐시에 종단을 붙임 again = _run(hill, "cost", False) assert again["metrics"] == first["metrics"] and again["planned"] == first["planned"] assert "profile" not in again["metrics"] def test_요청_기본은_켬이고_끔을_받는다() -> None: assert RouteInitialRequest(mode="earthwork").with_profile is True assert RouteInitialRequest(mode="earthwork", with_profile=False).with_profile is False