- run_preprocess_chain: WF1 자동 확정 · 서피스 바꿈 체인이 부름 · 다른 지형 없음 · 실패 = 한 벌 + meta.json 까닭 · 예상노선(공유)은 설계 지형 벌이 씀 - 자동 체인 배수 refresh=True — 저장분이 노선 바뀐 줄 모르던 틈 막음 - purge_output_folders 가 design_sets 도 지움 - run_redesign_chain(앱에서 부르는 곳 0) 걷음 — 시험 정리: test_342_2 의 그 함수 시험 셋 지움(함수 없음) · test_763_3 · test_351_1 은 두 벌 체인으로 · test_74 · test_user_values_survive 의 이월 차례 검사는 살아 있는 자리(B05_Profile_Route_Save)로 옮김 - 시험 test_765_design_sets 에 체인 차례 · 한 벌 · 다른 벌 실패 · 비우기 넷 덧 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
80 lines
3.1 KiB
Python
80 lines
3.1 KiB
Python
"""노선 [확인] 체인 이월 · 균형 종단 반영(PLAN 74-3 · 74-4).
|
|
|
|
./venv/Scripts/python.exe -m pytest resources/tester/test_74_route_confirm_initial.py -q
|
|
"""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from B05_Profile.B05_Profile_Router_Replan import RouteReplanRequest
|
|
from B05_Profile.B05_Profile_Router_RouteInitial import _set_base_pvi
|
|
from B06_Section.B06_Section_Router_Design import CARRY_INPUT_KEYS
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def test_이월은_사용자_입력만() -> None:
|
|
for result_key in (
|
|
"design_elevation_m",
|
|
"cut_area_m2",
|
|
"fill_area_m2",
|
|
"design_line",
|
|
"road_edges",
|
|
"slope_unclosed",
|
|
"section_mode",
|
|
"ditch_side",
|
|
):
|
|
assert result_key not in CARRY_INPUT_KEYS
|
|
assert {"ground_type", "ditch_choice", "cut_slope_ratio_user"} <= set(CARRY_INPUT_KEYS)
|
|
assert "paved" not in CARRY_INPUT_KEYS # 포장 = 노면공 범위로 새로 정함(138-1)
|
|
|
|
|
|
def test_체인이_옛_설계를_통째로_옮기지_않는다() -> None:
|
|
# 노선 저장 체인(`run_route_save_chain`)이 이월 자리 — 옛 재확정 체인은 걷음(765-3)
|
|
source = (ROOT / "B05_Profile" / "B05_Profile_Route_Save.py").read_text(encoding="utf-8")
|
|
assert 'record["design"])' not in source # 옛 (누가거리, design 통째) 이월
|
|
assert "compute_default_designs, project_root, relative, chainages, standard, inputs" in (
|
|
" ".join(source.split())
|
|
)
|
|
|
|
|
|
def test_변화점_계획고를_균형_종단으로(tmp_path: Path) -> None:
|
|
path = tmp_path / "longitudinal.json"
|
|
base = [{"chainage_m": s, "elevation_m": 100.0} for s in (0.0, 20.0, 30.0, 40.0)]
|
|
alignment = {"base_pvi": base, "policy": {}}
|
|
path.write_text(json.dumps({"profile_alignment": alignment}), encoding="utf-8")
|
|
assert _set_base_pvi(path, [0.0, 20.0, 40.0], [10.0, 12.0, 14.0]) == 4
|
|
got = [
|
|
p["elevation_m"]
|
|
for p in json.loads(path.read_text("utf-8"))["profile_alignment"]["base_pvi"]
|
|
]
|
|
# 구조물 측점(30 m)은 직선 보간 · 상한 누를 때 반올림 여유 0.1 mm 몫(419-3)
|
|
assert got == pytest.approx([10.0, 12.0, 13.0, 14.0], abs=5e-4)
|
|
|
|
|
|
def test_확인_요청_기본은_끔() -> None:
|
|
assert RouteReplanRequest().balanced_profile is False
|
|
assert RouteReplanRequest(balanced_profile=True).balanced_profile is True
|
|
|
|
|
|
def test_종단곡선이_있어도_측점마다_목표를_지난다() -> None:
|
|
import numpy as np
|
|
|
|
from B05_Profile.B05_Profile_Engine_Grade_Alignment import (
|
|
AlignmentPolicy,
|
|
build_curves,
|
|
evaluate,
|
|
)
|
|
from B05_Profile.B05_Profile_Engine_Grade_Profile import pass_through
|
|
|
|
base_s = np.array([0.0, 20.0, 40.0, 60.0, 80.0])
|
|
target = np.array([100.0, 102.4, 102.0, 104.6, 103.0]) # 대수차가 커 곡선이 들어감
|
|
policy = AlignmentPolicy.from_dict({})
|
|
curves, _ = build_curves(base_s, target, policy)
|
|
assert curves # 맞춤이 없으면 측점에서 뜸
|
|
base_z = pass_through(base_s, target, policy)
|
|
got = evaluate(base_s, base_z, build_curves(base_s, base_z, policy)[0], base_s)
|
|
assert np.max(np.abs(got - target)) < 1e-3
|