⚠ **뿌리** — `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>
72 lines
3.0 KiB
Python
72 lines
3.0 KiB
Python
"""측점 없는 구조물 알림 — 조용히 빠지던 것을 드러낸다 (계획서 3-14 ㉯, 2026-09-09).
|
|
|
|
관을 나중에 놓거나 옮기면 그 측점이 안 생긴다 — 측점을 만드는 자리가 B05 노선 [확정]
|
|
한 곳뿐이기 때문이다. 그 관은 횡단도에도 안 서고 수량·금액에서 통째로 빠진다.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
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 B05_Profile.B05_Profile_Router_Confirm import ( # noqa: E402
|
|
load_sampling_snapshot,
|
|
sampling_snapshot_path,
|
|
)
|
|
from B06_Section.B06_Section_Router_Stations import ( # noqa: E402
|
|
STATION_MATCH_TOLERANCE_M,
|
|
_station_chainages,
|
|
router,
|
|
)
|
|
|
|
|
|
def test_두_길이_다_열려_있다() -> None:
|
|
"""점검(GET)과 만들기(POST)가 같은 주소에 선다 — 화면이 하나만 알면 된다."""
|
|
paths = {(route.path, tuple(sorted(route.methods))) for route in router.routes}
|
|
assert ("/api/projects/{project_id}/section/missing-stations", ("GET",)) in paths
|
|
assert ("/api/projects/{project_id}/section/missing-stations", ("POST",)) in paths
|
|
|
|
|
|
def test_종단_정본에서_측점을_읽는다(tmp_path: Path) -> None:
|
|
folder = tmp_path / "B06_Section" / "longitudinal"
|
|
folder.mkdir(parents=True)
|
|
(folder / "longitudinal.json").write_text(
|
|
json.dumps({"stations": [{"chainage_m": 0.0}, {"chainage_m": 85.05}, {"bad": 1}]}),
|
|
encoding="utf-8",
|
|
)
|
|
assert _station_chainages(tmp_path) == [0.0, 85.05]
|
|
|
|
|
|
def test_측점이_없으면_빈_목록(tmp_path: Path) -> None:
|
|
"""파일이 없다고 터지지 않는다 — 이 줄은 덤이라 화면을 막으면 안 된다."""
|
|
assert _station_chainages(tmp_path) == []
|
|
|
|
|
|
def test_같은_자리_판정은_50cm() -> None:
|
|
"""⚠ 스냅 때문이다 — 관 440.241 은 **측점 440.0** 위에 선다(2026-09-09 실측).
|
|
|
|
측점을 만들 때 정수 미터가 같은 격자 측점이 있으면 그리로 스냅하므로(횡단 파일명이
|
|
정수 미터라 두 측점이 한 파일을 덮어쓰는 것을 막는 가드) 최대 어긋남이 0.5m 다.
|
|
0.05m 로 보면 **있는 측점을 없다고 세어** 또 만들라고 한다.
|
|
"""
|
|
assert STATION_MATCH_TOLERANCE_M == 0.5
|
|
|
|
|
|
def test_샘플링_조건이_없으면_None(tmp_path: Path) -> None:
|
|
"""조건을 지어내지 않는다 — 그 측점만 다른 지표에서 뽑히면 지반고가 어긋난다."""
|
|
assert load_sampling_snapshot(tmp_path) is None
|
|
path = sampling_snapshot_path(tmp_path)
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
path.write_text(json.dumps({"filter_key": "", "method": "dtm"}), encoding="utf-8")
|
|
assert load_sampling_snapshot(tmp_path) is None
|
|
path.write_text(
|
|
json.dumps({"filter_key": "csf", "method": "tin", "smooth": True}), encoding="utf-8"
|
|
)
|
|
snapshot = load_sampling_snapshot(tmp_path)
|
|
assert snapshot is not None and snapshot["method"] == "tin" and snapshot["smooth"] is True
|