# -*- coding: utf-8 -*- """233-1 고름 한 칸 = 유일 원천 + 바뀜 알림 · 종단도(측점선 · 알약 · 띠)는 그 값으로 그림(조사 AF (나) ① ②). 까닭: 알림 장치(`subscribeSelection`)는 있었으나 듣는 곳 0 — 화면끼리 손으로 부르는 사슬이라 한 길이 강조를 끄면(저장 뒤 관 폼 닫힘 → 종단 선 · 알약 끔) 값은 그대로인데 종단만 꺼짐 · 관 알약 id(`pipe-`+측점)가 옛 관 자리에 묶여 관이 옮겨지면 끊김. 고침: `design_pick_profile` — 종단 보기가 고름 한 칸을 구독해 값 → 종단 강조(`profilePickOf`) · 목록이 바뀐 뒤 · 폼이 닫힌 뒤에도 같은 값으로 다시 얹음(`paint`) · 숨은 보기는 안 그림 · 떠나면 구독 끊음. 진짜 TS 를 `helper_233_1_profile_pick.cjs` 가 Node 로 돌린다. """ from __future__ import annotations import json import os import subprocess import pytest HERE = os.path.dirname(os.path.abspath(__file__)) ROOT = os.path.abspath(os.path.join(HERE, "..", "..")) pytestmark = pytest.mark.skipif( not os.path.isdir(os.path.join(ROOT, "config", "node_modules")), reason="프론트엔드 의존성 미설치", ) def _read(*parts: str) -> str: with open(os.path.join(ROOT, *parts), encoding="utf-8") as handle: return handle.read() @pytest.fixture(scope="module") def out() -> dict: proc = subprocess.run( # noqa: S603 — 고정 실행 파일 ["node", os.path.join(HERE, "helper_233_1_profile_pick.cjs")], capture_output=True, text=True, encoding="utf-8", timeout=60, ) assert proc.returncode == 0, proc.stderr return json.loads(proc.stdout) def line(station): return {"station": station, "structure": None} def pill(structure): return {"station": None, "structure": structure} def test_측점_값은_그_측점선(out) -> None: assert out["card"] == line("s120") assert out["irregularSign"] == line("irregular:sign") # 구조물 측점(관 아님)도 그대로 assert out["card80"] == line("s80") # 관 80.17 옆 카드 80 은 카드 선 assert out["pipe80"] == line("irregular:p80") def test_측점선_없는_관은_지금_관_목록으로_알약(out) -> None: assert out["pipePill"] == pill("pipe-300.40") assert out["pipeMoved"] == pill("pipe-300.45") # 관이 옮겨져도 끊기지 않음 def test_구조물_값은_그_알약(out) -> None: assert out["structure"] == pill("wall") def test_다른_길이_꺼도_값대로_다시_얹음(out) -> None: assert out["clearedByOther"] == pill(None) assert out["repainted"] == pill("wall") def test_숨은_보기는_안_그리고_보이면_다시_얹음(out) -> None: assert out["hidden"] == pill("wall") assert out["shownAgain"] == line("s140") def test_풂과_구독_끊음(out) -> None: assert out["released"] == line(None) assert out["disposers"] == 2 # 구독 + Esc 듣기(233-3) assert out["paintsAfterDispose"] == 0 def test_종단_보기_배선() -> None: view = _read("A00_Common", "design", "design_view_profile.ts") assert "bindProfilePick(" in view and "{ profile: profilePanel, viewer," in view # 폼이 닫히는 길(저장 뒤 · 관 폼으로)은 종단을 끄지 않고 값대로 다시 얹음 assert "profilePanel.setSelectedStructure(structure?.structure_id ?? null)" not in view assert view.count("profilePick.paint()") >= 3 assert len(view.splitlines()) <= 700