Files
Aislo/resources/tester/test_411_b_pipe_id_pairing.py
T
eomsangdonandClaude Opus 5.5 274a0f892e fix(B06 측점 열쇠): 옛 자리 관 측점 헛 세션 id 걷음 · 헛 id 정리 (411-E)
- 관 계획을 아는 동안(초안 · 관 주인 있음) 계획에 없는 관 같은 측점 = 옮겨 간 옛 자리 — pipeIdAt 대신 pipeIdNear(안 지음) · 장부에 없으면 at: 열쇠
- 초안 없음 = 옛 갈래 그대로(지음)
- 화면 관 목록 맞춤 때 지금 관 자리 근처에 없는 기록 정리(prunePipeIds)
- 시험 test_411_b 덧붙임(헛 id 0 · 옛 갈래 · 정리)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TteK8mfYZetk5P3bEZkyVZ
2026-10-18 09:59:12 +09:00

126 lines
4.4 KiB
Python

# -*- 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"}