- 624-3 도구줄 = 공용 표 「b05」 · 아래 줄 = 공용 겹 줄(띠 · 올린 임도망도 숨김 · 처음 = 등고선 · 하천) · 범례 = 공용 legendRows(상태 글판 위) - 노선 띠 300 m 자르기 = B05 자기 칸(등고선 · 하천 · 1 m)만 · 그 밖 겹 = 안 자르는 둘째 GL 칸(맨 밑 · 켠 겹 있을 때만 · GL 만) · 등고선 끔 = 등고 글도 숨김 - 626-1 추천 보기 = 도구줄 아이콘 + 아래 판(영선 · 토공 최소 · 기울기 최소 · 비중 계산 · 끔) — route_recommend 저장본(지금 설계 지형) 선만 · 다시 셈 · 쓰기 없음 - 지형 칩 → 확인창 → 새 POST /route/design-terrain(설계 지형만 바꿈 · 노선 저장 체인 다시 · 노선 · 초기값 · 추천 저장본 그대로 · 잠금 · 실패 되돌림) - 걷음 — 추천 모달(_Recommend · _Help · _Map · CSS) · 좌측 「노선 추천」 칸 · saveRecommendedRoute · UI_RouteReset(서버 as_initial 길 · 시험은 남김) - 부품 상자 — createPickMenu(아이콘 고르기 메뉴 · 판 = body fixed · ✓) - 낡은 시험 고침 · 지움 — 모달 · 좌측 칸 · [적용] 화면 배선을 보던 시험(283 · 346_3 · 349 · 364_4 · 383_1 · 390_5 · 418 · 421 · 421_2 · 476_2 · 509_2 · 509_5 · 551_2 · 600_3 · b05_routeedit_initial · design_view_parity · modal_top · 133_1 · 133_2) · test_508_2 · helper_283 지움(모달 전용) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
142 lines
6.2 KiB
Python
142 lines
6.2 KiB
Python
"""509-5 분석 지형 고르기 = 추천 노선 창 안 — 지형마다 추천 미리 셈 · 창 지형 바꿈 = 그 지형 저장본 ·
|
|
없으면 안내 + [재계산] · [적용] = 창 지형이 설계 지형 · 평면 고르기 없음.
|
|
|
|
./venv/Scripts/python.exe -m pytest resources/tester/test_509_5_recommend_terrain.py -q
|
|
|
|
가짜 세계(`test_224_3` wired) — 지형마다 다른 격자(수치지형도 = 1 m 높임)라 저장 키가 갈림.
|
|
"""
|
|
|
|
import asyncio
|
|
import json
|
|
from contextlib import asynccontextmanager
|
|
from pathlib import Path
|
|
from uuid import uuid4
|
|
|
|
import pytest
|
|
from test_224_3_recommend_store import STREAMS, _ask, _terrain, wired # noqa: F401 — 픽스처
|
|
|
|
from B05_Profile import B05_Profile_Router_RouteInitial as router
|
|
from B05_Profile import B05_Profile_Router_Terrain as terrain_router
|
|
from B05_Profile.B05_Profile_Engine_RouteInitial_Store import DEFAULT_MODES, store_dir
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
@pytest.fixture
|
|
def two(wired, monkeypatch): # noqa: F811
|
|
"""라이다 설계 · 수치지형도 고를 수 있음 — 지형마다 다른 격자."""
|
|
import B05_Profile.B05_Profile_Engine_RouteInitial as engine
|
|
import common_util.common_util_surface_confirmation as surface
|
|
|
|
async def terrains(_pid, _root):
|
|
return ["las", "sheet"]
|
|
|
|
monkeypatch.setattr(router, "precompute_terrains", terrains)
|
|
monkeypatch.setattr(surface, "analysis_terrain_params", lambda s, t: {**s, "t": t})
|
|
monkeypatch.setattr(
|
|
engine,
|
|
"load_terrain_and_streams",
|
|
lambda _root, selection: (_terrain(1.0 if selection.get("t") == "sheet" else 0.0), STREAMS),
|
|
)
|
|
return wired
|
|
|
|
|
|
def _saved(root: Path) -> list[dict]:
|
|
return [json.loads(p.read_text(encoding="utf-8")) for p in store_dir(root).glob("*.json")]
|
|
|
|
|
|
def test_미리_셈이_지형마다_추천_다섯(two) -> None:
|
|
asyncio.run(router.precompute_defaults(uuid4()))
|
|
assert two.count == 2 * len(DEFAULT_MODES)
|
|
saved = _saved(two.root)
|
|
assert sorted({item["request"]["terrain"] for item in saved}) == ["las", "sheet"]
|
|
assert all(item["default"] for item in saved)
|
|
# 창 지형 바꿈 = 그 지형 저장본(셈 없음) · 두 지형 답이 따로
|
|
for mode in DEFAULT_MODES:
|
|
assert _ask(False, mode=mode, terrain="sheet")["stored"] is True
|
|
assert _ask(False, mode=mode, terrain="las")["stored"] is True
|
|
assert two.count == 2 * len(DEFAULT_MODES)
|
|
|
|
|
|
def test_미리_셈_없는_지형은_안내_재계산은_셈(two) -> None:
|
|
"""기존 프로젝트(수치지형도 미리 셈 없음) — 안내 한 줄 · [재계산]이면 그 자리 셈."""
|
|
missing = _ask(False, mode="gentle", terrain="sheet")
|
|
assert missing.status_code == 409
|
|
message = json.loads(missing.body)["message"]
|
|
assert "전처리를 다시 하면" in message and "[재계산]" in message
|
|
assert two.count == 0
|
|
assert _ask(False, mode="gentle", terrain="sheet", recompute=True)["stored"] is False
|
|
assert two.count == 1
|
|
assert _ask(False, mode="gentle", terrain="sheet")["stored"] is True
|
|
|
|
|
|
def test_미리_셈_지형_차례_설계_먼저(monkeypatch) -> None:
|
|
import common_util.common_util_surface_confirmation as surface
|
|
|
|
class _Pool:
|
|
@asynccontextmanager
|
|
async def acquire(self):
|
|
yield None
|
|
|
|
async def params(_c, _pid):
|
|
return {"source_filter": surface.SHEET_ANALYSIS_FILTER}
|
|
|
|
async def choosable(_c, _pid, _params, _dir):
|
|
return ["las", "sheet"]
|
|
|
|
monkeypatch.setattr(router, "get_db_pool", lambda: _Pool())
|
|
monkeypatch.setattr(surface, "get_surface_confirmation_params", params)
|
|
monkeypatch.setattr(terrain_router, "choosable_terrains", choosable)
|
|
assert asyncio.run(router.precompute_terrains(uuid4(), ROOT)) == ["sheet", "las"]
|
|
|
|
|
|
def test_고를_지형은_DB_모델_있을_때만(tmp_path, monkeypatch) -> None:
|
|
import B04_PreProcess.B04_PreProcess_Service as service
|
|
from common_util.common_util_surface_confirmation import SHEET_ANALYSIS_FILTER
|
|
|
|
(tmp_path / f"dtm_{SHEET_ANALYSIS_FILTER}.npz").write_bytes(b"")
|
|
params = {"source_filter": "classification", "method": "dtm", "smooth": False}
|
|
found: list[str] = []
|
|
|
|
async def missing(_c, _pid, selection):
|
|
found.append(selection["source_filter"])
|
|
raise LookupError
|
|
|
|
async def present(_c, _pid, _selection):
|
|
return 7
|
|
|
|
monkeypatch.setattr(service, "find_surface_model_for_selection", missing)
|
|
pick = terrain_router.choosable_terrains
|
|
assert asyncio.run(pick(None, uuid4(), params, tmp_path)) == ["las"]
|
|
assert found == [SHEET_ANALYSIS_FILTER]
|
|
monkeypatch.setattr(service, "find_surface_model_for_selection", present)
|
|
assert asyncio.run(pick(None, uuid4(), params, tmp_path)) == ["las", "sheet"]
|
|
|
|
|
|
def test_지형_바꿈은_추천_적용만_초기값_다시_세움() -> None:
|
|
replan = (ROOT / "B05_Profile/B05_Profile_Router_Replan.py").read_text(encoding="utf-8")
|
|
save = replan.split("async def _save_route(", 1)[1]
|
|
assert "request.terrain if as_initial else None," in save # 손 [저장]은 지형 안 바꿈
|
|
assert save.index("await _recompute(") < save.index("refresh_initial_snapshot(project_id")
|
|
recompute = replan.split("async def _recompute(", 1)[1].split("\nasync def ")[0]
|
|
assert "switch_design_terrain(connection, project_id, terrain)" in recompute
|
|
|
|
|
|
def _ts(name: str) -> str:
|
|
return (ROOT / "B05_Profile" / name).read_text(encoding="utf-8")
|
|
|
|
|
|
def test_평면_지형_고르기_없음_이름만() -> None:
|
|
chrome = _ts("B05_Profile_UI_RouteEdit_Chrome.ts")
|
|
main = _ts("B05_Profile_UI_RouteEdit.ts")
|
|
# 626-1 — 평면 도구줄 지형 칩(공용) · 바꾸기 = 확인창 → 설계 지형(`_Terrain`)
|
|
assert "terrain: terrain.root" in chrome and 'data-slot="terrain-name"' not in chrome
|
|
assert "chrome.terrain.load(sources);" in main
|
|
assert "terrainSelect" not in main and "setAnalysisTerrain" not in main
|
|
assert "routeedit-terrain" not in (ROOT / "A00_Common/b_page_state.ts").read_text(
|
|
encoding="utf-8"
|
|
)
|
|
pipeline = (ROOT / "A00_Common/design/design_pipeline_page.ts").read_text(encoding="utf-8")
|
|
assert "terrain: null }; // 설계 지형(509-5)" in pipeline
|
|
assert len(pipeline.splitlines()) <= 700 and len(main.splitlines()) <= 700
|