⚠ **뿌리** — `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>
74 lines
3.0 KiB
Python
74 lines
3.0 KiB
Python
"""새 자료로 갈아 끼울 때 「지우고 진행할까?」를 먼저 묻는지.
|
|
|
|
왜 있나(2026-09-08) — 업로드 하나가 그 프로젝트의 설계 산출물·초기값 스냅숏을
|
|
**되돌릴 수 없게** 지운다. 창 넷이 한 프로젝트를 볼 수 있어 말없이 지우면 남의 작업이
|
|
사라진다. 사람이 올리는 갈래만 묻고, 자동 절차는 안 막는다.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from B03_FileInput.B03_FileInput_Router_Helpers import (
|
|
OutputsWouldBeDiscarded,
|
|
_confirm_replace_response,
|
|
describe_existing_outputs,
|
|
)
|
|
|
|
|
|
def test_산출물이_없으면_묻지_않는다(tmp_path: Path) -> None:
|
|
(tmp_path / "B03_FileInput" / "input").mkdir(parents=True)
|
|
(tmp_path / "B03_FileInput" / "input" / "a.las").write_text("x", encoding="utf-8")
|
|
assert describe_existing_outputs(tmp_path) == []
|
|
|
|
|
|
def test_설계_산출물과_초기값을_사람_말로_알린다(tmp_path: Path) -> None:
|
|
(tmp_path / "B05_Profile" / "route").mkdir(parents=True)
|
|
(tmp_path / "B05_Profile" / "route" / "route.json").write_text("{}", encoding="utf-8")
|
|
(tmp_path / "B06_Section").mkdir()
|
|
(tmp_path / "B06_Section" / "cross.json").write_text("{}", encoding="utf-8")
|
|
(tmp_path / "initial_snapshot").mkdir()
|
|
|
|
targets = describe_existing_outputs(tmp_path)
|
|
|
|
assert "노선·종단 설계" in targets
|
|
assert "횡단 설계" in targets
|
|
assert any("초기값" in item for item in targets)
|
|
# B03 입력은 「지워지는 것」이 아니다 — 새 자료가 얹히는 자리다.
|
|
assert all("입력" not in item for item in targets)
|
|
|
|
|
|
def test_빈_폴더만_있으면_지울_것이_없다(tmp_path: Path) -> None:
|
|
(tmp_path / "B05_Profile" / "route").mkdir(parents=True)
|
|
(tmp_path / "B08_Quantity").mkdir()
|
|
assert describe_existing_outputs(tmp_path) == []
|
|
|
|
|
|
def test_확인_응답은_409_이고_무엇이_지워지는지_담는다() -> None:
|
|
response = _confirm_replace_response(OutputsWouldBeDiscarded(["횡단 설계", "수량 산출"]))
|
|
body = response.body.decode("utf-8")
|
|
|
|
assert response.status_code == 409
|
|
assert "replace_outputs" in body
|
|
assert "\\ub418\\ub3cc\\ub9b4" in body or "되돌릴" in body # 문구에 「되돌릴 수 없」
|
|
assert "\\ud6a1\\ub2e8" in body or "횡단" in body
|
|
|
|
|
|
def test_자동_절차는_기본으로_안_묻는다() -> None:
|
|
"""`confirm_replace` 기본이 True 여야 체인·스크립트가 물음에 안 걸린다."""
|
|
import inspect
|
|
|
|
from B03_FileInput.B03_FileInput_Router_Helpers import _complete_file_input_if_ready
|
|
|
|
default = inspect.signature(_complete_file_input_if_ready).parameters["confirm_replace"].default
|
|
assert default is True
|
|
|
|
|
|
@pytest.mark.parametrize("stage", ["B04_PreProcess", "B07_DesignDetail", "B09_Estimation"])
|
|
def test_모든_산출물_단계를_본다(tmp_path: Path, stage: str) -> None:
|
|
(tmp_path / stage).mkdir(parents=True)
|
|
(tmp_path / stage / "out.json").write_text("{}", encoding="utf-8")
|
|
assert describe_existing_outputs(tmp_path), stage
|