# -*- coding: utf-8 -*- """508-2 ③ 노선 편집 평면 도엽 등고선 — 편집 중 노선을 범위(저장 노선 띠 300 + 여유 300 m) 밖으로 끌어 놓으면 잠잠 뒤 그 초안 노선 범위로 서버에 잘린 등고선을 다시 받아 바꿔 끼움(통째 사본 안 받음). - 서버 `bbox`(route 만 · 사업지 m) = 저장 노선 대신 그 bbox 로 범위 · 열쇠 = 사본 지문 + 범위 · 같은 범위 = 다시 안 셈 - 화면 `createSheetFollow` — 범위 안 = 안 받음 · 밖 = 잠잠 뒤 한 번 · 지금 노선 범위 · 떠난 뒤 = 안 받음 - 배수유역도 범위(509-6)는 그대로(bbox 안 받음) 임시 폴더 사업지(509-1 과 같음) — 공유 storage · DB 안 씀. ./venv/Scripts/python.exe -m pytest resources/tester/test_508_2_sheet_follow.py -q """ import json import subprocess from pathlib import Path import pytest from test_509_1_sheet_clip_route import META, project # noqa: F401 — 같은 사업지 from B04_PreProcess import B04_PreProcess_Engine_SheetClip as clip HERE = Path(__file__).resolve().parent ROOT = HERE.parents[1] def test_bbox_읽기() -> None: assert clip.parse_route_bbox("6200,5000,6700,5200") == (6200, 5000, 6700, 5200) for bad in (None, "", "1,2,3", "a,b,c,d", "5,0,1,0", "nan,0,1,1", "0,0,inf,1"): assert clip.parse_route_bbox(bad) is None def test_편집_노선_범위로_자름_같은_범위_다시_안_셈(project) -> None: # noqa: F811 root, source = project saved = clip.clipped_sheet(root, source, "route") moved = clip.clipped_sheet(root, source, "route", (6200, 5000, 6700, 5200)) assert moved != saved and moved.parent == saved.parent data = json.loads(moved.read_text(encoding="utf-8")) assert data["clip_lonlat"] == pytest.approx([127.056, 37.044, 127.073, 37.058]) stamp = moved.stat().st_mtime_ns again = clip.clipped_sheet(root, source, "route", (6210, 5010, 6690, 5190)) # 같은 눈금 assert again == moved and again.stat().st_mtime_ns == stamp # 저장 노선 bbox 를 그대로 보내면 저장 노선 범위와 같은 저장본 assert clip.clipped_sheet(root, source, "route", (5000, 5000, 5500, 5200)) == saved def test_라우터_bbox_는_route_만() -> None: text = (ROOT / "B04_PreProcess" / "B04_PreProcess_Router_GIS.py").read_text(encoding="utf-8") assert 'bounds = parse_route_bbox(bbox) if scope == "route" else None' in text assert "clipped_sheet, project_root, display, scope, bounds" in text def test_화면_놓은_뒤_다시_받음() -> None: proc = subprocess.run( ["node", str(HERE / "helper_508_2_sheet_follow.cjs")], capture_output=True, text=True, encoding="utf-8", timeout=60, ) assert proc.returncode == 0, proc.stderr out = json.loads(proc.stdout.strip().splitlines()[-1]) assert out["bbox"] == "5000,4950,5500,5200" # 50 m 눈금 바깥 맞춤 assert out["insideCalls"] == 0 # 범위 안 끌기 = 안 받음 assert out["beforeQuiet"] == 0 # 끄는 동안 = 안 받음 assert out["outsideCalls"] == [{"scope": "route", "bbox": "6200,5000,6700,5200"}] # 한 번 assert out["swaps"] == 1 and out["swappedCovers"] is True and out["lineKept"] is True assert out["againCalls"] == 1 and out["coveringSame"] is True assert out["disposedCalls"] == 1 def test_여는_때도_통째_사본_안_받음() -> None: ts = (ROOT / "B05_Profile" / "B05_Profile_UI_RouteEdit_Contour.ts").read_text(encoding="utf-8") assert "fetchDrainageLayers(projectId, () => {}, null)" not in ts edit = (ROOT / "B05_Profile" / "B05_Profile_UI_RouteEdit.ts").read_text(encoding="utf-8") assert len(edit.splitlines()) <= 700 assert "sheetFollow?.poke();" in edit and "sheetFollow?.dispose();" in edit