"""구 비정규 측점 이관은 **한 번만** — 2026-08-24 사용자 확정. 원천(종단 정본의 비정규 측점)은 원복용으로 그대로 두고, 옮긴 이력만 구조물 정본에 남긴다. 그래야 사용자가 그 구조물을 지운 뒤 B05에 다시 들어와도 되살아나지 않는다. """ 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_Structures_Repository import ( # noqa: E402 load_migrated_legacy, load_structures, save_structures, ) from B05_Profile.B05_Profile_Structures_Migration import migrate_irregular_stations # noqa: E402 def _key(item) -> str: return f"{item.type_id}@{round(item.anchor_m(), 3)}" def test_history_survives_plain_save(tmp_path): """일반 저장(구조물 편집)이 이력을 지우면 안 된다 — 지우면 삭제분이 되살아난다.""" root = str(tmp_path) revision = save_structures(root, [], base_revision=0, migrated_legacy={"erosion_check@10.0"}) assert load_migrated_legacy(root) == {"erosion_check@10.0"} # 이력 인자 없이 다시 저장해도 남아 있어야 한다. save_structures(root, [], base_revision=revision) assert load_migrated_legacy(root) == {"erosion_check@10.0"} def test_history_accumulates(tmp_path): """여러 번 이관해도 이력은 합쳐진다.""" root = str(tmp_path) revision = save_structures(root, [], base_revision=0, migrated_legacy={"a@1.0"}) save_structures(root, [], base_revision=revision, migrated_legacy={"b@2.0"}) assert load_migrated_legacy(root) == {"a@1.0", "b@2.0"} def test_migration_candidate_keys_are_stable(tmp_path): """이관 후보의 표식이 저장 왕복에도 같아야 한다 — 달라지면 매번 다시 옮긴다.""" stations = [{"chainage_m": 10.0, "structure": "돌쌓기 기슭막이"}] candidates = migrate_irregular_stations(stations).structures if not candidates: # 매핑이 없는 문구면 이 검증은 대상 아님 return root = str(tmp_path) save_structures(root, candidates, base_revision=0) _revision, stored = load_structures(root) assert {_key(item) for item in stored} == {_key(item) for item in candidates} def test_deleted_structure_is_not_recreated(tmp_path): """이관 → 삭제 → 재이관 시도: 이력에 있으므로 다시 만들지 않는다.""" stations = [{"chainage_m": 10.0, "structure": "돌쌓기 기슭막이"}] candidates = migrate_irregular_stations(stations).structures if not candidates: return root = str(tmp_path) history = {_key(item) for item in candidates} revision = save_structures(root, candidates, base_revision=0, migrated_legacy=history) # 사용자가 전부 지운다(일반 저장 경로). revision = save_structures(root, [], base_revision=revision) assert load_structures(root)[1] == [] # 재진입 — 라우터와 같은 판정: 자리도 비었지만 이력에 있으니 후보에서 빠진다. migrated_before = load_migrated_legacy(root) fresh = [item for item in candidates if _key(item) not in migrated_before] assert fresh == []