# -*- coding: utf-8 -*- """411-B · 411-D 관 짝 = id — 앞 관을 지나 옮겨도 알약 · 측점 수 · id 그대로 · B06 열쇠 = 계산 묶음과 같음. 사용자 길(요구 252-6): 관 마커를 앞 관을 지나 옮김 → 옛 차례 짝이 이웃 id 를 빼앗고 새 `pipe-sN` 을 지어 새 측점 · 계획고 0 이 생기던 흠. 진짜 TS 를 vite ssr 로 묶어(`helper_411_b_entry.ts`) Node 로 잰다: ① `followPipeReports` 짝 = 관 고정 id ② 세션 id 장부(`movePipeId` 끌기 · `placePipeIds` 화면 맞춤) ③ `followedMarks` ④ 배수 편집기 `followEditorPipes`(410 · 따라간 자리 받음) ⑤ B06 `useStationOwners` · `stationKeysOf`. """ from __future__ import annotations import json import shutil import subprocess from pathlib import Path import pytest HERE = Path(__file__).resolve().parent ROOT = HERE.parents[1] pytestmark = pytest.mark.skipif( not (ROOT / "config" / "node_modules" / "vite").is_dir(), reason="프론트엔드 의존성 미설치", ) @pytest.fixture(scope="module") def out(tmp_path_factory): work = tmp_path_factory.mktemp("b411") build = subprocess.run( # noqa: S603 — 고정 실행 파일 [ "node", str(ROOT / "config" / "node_modules" / "vite" / "bin" / "vite.js"), "build", "--configLoader", "runner", "--ssr", "../resources/tester/helper_411_b_entry.ts", "--outDir", str(work), "--logLevel", "error", ], cwd=ROOT, capture_output=True, text=True, encoding="utf-8", timeout=300, ) assert build.returncode == 0, build.stderr bundle = work / "bundle.mjs" shutil.copy(work / "helper_411_b_entry.js", bundle) proc = subprocess.run( # noqa: S603 — 고정 실행 파일 ["node", str(HERE / "helper_411_b_pipe_id_pairing.mjs"), str(bundle)], cwd=ROOT, capture_output=True, text=True, encoding="utf-8", timeout=120, ) assert proc.returncode == 0, proc.stderr return json.loads(proc.stdout) def test_알림_목록_짝은_id(out): # 옮긴 관(p15000)이 앞 관 자리를 빼앗지 않음 · 구간도 그 관과 함께 밂 assert sorted(out["reports"]) == [["p10000", 100, None], ["p15000", 80, 75]] def test_앞_관_지나_옮겨도_세션_id_그대로(out): ids = out["ids"] assert ids["at80"] == ids["idB"] # 옮긴 관 = 제 id(옛 자리 헛 id 를 안 받음) assert ids["at100"] == ids["idA"] # 이웃 관 = 제 id(새 pipe-sN 아님) def test_되돌려_옛_자리로_가도_그_관_id(out): assert out["back"]["at150"] == out["ids"]["idB"] assert out["back"]["strayAt"] is None # 그 자리 헛 기록은 장부에서 빠짐 def test_따라감이_여럿을_함께_밀어도_기록_안_잃음(out): batch = out["batch"] assert batch["at103"] == batch["q1"] and batch["at106"] == batch["q2"] assert batch["next"] == "pipe-s3" # 헛 id 없음 = 알약 · 측점 수 그대로 def test_알약은_그_관_자리(out): assert out["marks"] == [["pipe-s2", 80], ["pipe-s1", 100], ["st-1", 42]] def test_배수_편집기는_따라간_자리를_받음(out): editor = out["editor"] assert editor["pipes"] == [["p15000", 98, "confirmed"], ["p10000", 103, "stream"]] assert editor["selected"] == "p15000" # 고름도 그 관 assert editor["ford98"] == "ford" and editor["at150"] is None # 시설 속성도 새 자리 assert out["editorSame"] == [98, 103] def test_막_놓은_관은_id_없는_것끼리_차례로_따라감(out): assert out["fresh"] == [ [["p12000", 120], ["p35100", 353]], [["p20000", 204], ["p35100", 353]], ] def test_B06_열쇠는_서버_관_id_도_pipe(out): assert out["keys"] == ["structure:st-1", "pipe:p8017"] assert out["keys"][1] == out["pipelineKey"] # 계산 묶음 측점 열쇠와 같음 assert out["keysNoPipes"][1] == "structure:p8017" # 관 목록을 안 주면 옛 갈래(대조) def test_411_E_옛_자리_관_측점은_헛_id_안_지음(out): assert out["staleKeys"] == ["pipe:p15000", "at:150.00"] assert out["staleBook"] == 1 # 세션 id 표에 헛 id 0 assert out["legacyKey"] == "pipe:pipe-s2" and out["legacyBook"] == 2 # 초안 없음 = 옛 갈래 def test_411_E_헛_id_정리(out): assert out["pruned"] == {"size": 1, "at80": out["pruned"]["e1"], "e1": "pipe-s1"}