Files
Aislo/resources/tester/test_532_1_source_robust.py
T
eomsangdonandClaude Opus 5.5 f2c3aefae2 fix(532-1): E01 복사본 읽기 — 횡단 경로 null · 파일 없음 · 옛 꼴도 B06 이름 규칙으로 찾음 · 없으면 그 측점만 건너뜀 · 생성 복사 경고(요구 351)
- Source.stations · cross_section: 경로 칸 null · 파일 없음 · 절대 경로 · 옛 정수 m 이름이면 find_cross_file 로 찾음 · 그래도 없으면 「횡단 없음」(stations 에서 빠짐 · cross_section KeyError) · missing_stations 추가
- copy_stability: 같은 검사 → manifest missing_cross_chainages · warnings · E01 생성 응답 warnings
- 실측: 검증 프로젝트 14 복사 모두 stations 성공 · 검증_브레인232 null 1 행(359 m) 살림

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 21:05:14 +09:00

122 lines
4.6 KiB
Python

"""532-1 덧 · 요구 351 — E01 복사본 읽기가 횡단 경로 null · 파일 없음 · 옛 꼴에서도 돎.
- 경로 null · 경로 파일 없음 → B06 이름 규칙(`find_cross_file`)으로 찾음
- 옛 꼴 — 절대 경로(원본 쪽을 읽지 않음) · 소수 측점의 옛 정수 m 이름 · data 없음
- 어디에도 없으면 그 측점만 빠짐(`missing_stations`) · cross_section 은 KeyError
- 생성 복사(`copy_stability`)가 같은 검사 → manifest `missing_cross_chainages` · `warnings`
"""
import asyncio
import json
import sys
from pathlib import Path
import pytest
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
from common_util import common_util_project_copy as cp # noqa: E402
from E01_StabRegister import E01_StabRegister_Source as src # noqa: E402
CROSS = "B06_Section/cross_sections"
def _cross(root: Path, name: str, label: str) -> None:
path = root / CROSS / name
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps({"label": label, "samples": [{"offset_m": 0}]}), encoding="utf-8")
def _row(chainage, path, data=..., seq=0):
design = {"design": {"ground_type": "soil"}}
return {
"chainage_m": chainage,
"sequence_num": seq,
"cross_section_file_path": path,
"data": json.dumps(design) if data is ... else data,
}
@pytest.fixture
def root(tmp_path):
outside = tmp_path / "original" / CROSS / "cross_00040m.json"
outside.parent.mkdir(parents=True)
outside.write_text(json.dumps({"label": "원본"}), encoding="utf-8")
copy = tmp_path / "copy"
_cross(copy, "cross_00000m.json", "정상")
_cross(copy, "cross_00020m.json", "null")
_cross(copy, "cross_00030m.json", "경로 틀림")
_cross(copy, "cross_00040m.json", "절대")
_cross(copy, "cross_00050m.json", "옛 정수") # 49.8 m 측점의 옛 이름
rows = [
_row(0.0, f"{CROSS}/cross_00000m.json"),
_row(20.0, None, seq=None),
_row(30.0, f"{CROSS}/cross_gone.json"),
_row(40.0, str(outside)),
_row(49.8, None, data=None),
_row(60.0, None), # 어디에도 없음
_row(None, None), # 누가거리 없는 행 — 측점 아님
]
(copy / src.STABILITY_DB_NAME).write_text(
json.dumps({"cross_sections": rows}), encoding="utf-8"
)
(copy / src.MANIFEST_NAME).write_text("{}", encoding="utf-8")
return copy
def test_stations_skip_only_missing(root):
got = src.stations(root)
assert [s["chainage_m"] for s in got] == [0.0, 20.0, 30.0, 40.0, 49.8]
assert [s["label"] for s in got] == ["정상", "null", "경로 틀림", "절대", "옛 정수"]
assert got[0]["ground_type"] == "soil" and got[4]["ground_type"] is None
assert src.missing_stations(root) == [60.0]
def test_cross_section(root):
assert src.cross_section(root, 20.0)["label"] == "null"
assert src.cross_section(root, 40.0)["label"] == "절대" # 원본 쪽 파일 아님
assert src.cross_section(root, 49.8)["design"] == {}
with pytest.raises(KeyError, match="횡단 없음"):
src.cross_section(root, 60.0)
with pytest.raises(KeyError, match="측점 없음"):
src.cross_section(root, 70.0)
def test_normal_copy_has_no_missing(root):
db = json.loads((root / src.STABILITY_DB_NAME).read_text(encoding="utf-8"))
db["cross_sections"] = db["cross_sections"][:1]
(root / src.STABILITY_DB_NAME).write_text(json.dumps(db), encoding="utf-8")
assert [s["label"] for s in src.stations(root)] == ["정상"]
assert src.missing_stations(root) == []
def test_copy_stability_warns(tmp_path, monkeypatch):
source = tmp_path / "source"
_cross(source, "cross_00000m.json", "a")
_cross(source, "cross_00020m.json", "b")
dump = {
"project": {"storage_path": "x"},
"surface_params": {"source_filter": "none"},
"route": None,
"cross_sections": [
_row(0.0, None),
_row(20.0, f"{CROSS}/cross_00020m.json"),
_row(35.5, None),
],
"route_points": [],
"longitudinal_sections": [],
}
async def fake_rows(connection, source_id):
return dump
monkeypatch.setattr(cp, "_stability_rows", fake_rows)
monkeypatch.setattr(cp, "resolve_stored_project_path", lambda _: str(source))
manifest = asyncio.run(cp.copy_stability(None, "s" * 36, "e" * 36, tmp_path / "e"))
assert manifest["missing_cross_chainages"] == [35.5]
assert manifest["warnings"] == ["횡단 없는 측점 1 개 — 해석에서 빠짐"]
written = json.loads(
(tmp_path / "e" / cp.STABILITY_SOURCE_DIR / cp.MANIFEST_NAME).read_text("utf-8")
)
assert written["missing_cross_chainages"] == [35.5]