Files
Aislo/resources/tester/test_189_1_pave_pick.py
T
eomsangdonandClaude Opus 5.5 9e69bec512 fix(B06·B05): 노면공 고름 세 갈래 · 형상 누름 = 목록 고름 · 카드 하나 = 그 측점(189-1)
- ② 카드 안 노면공 포장층 누름 = 목록 고름과 같은 길(범위 카드 전부 · 포장층 강조) — 카드 고름보다 먼저 가로챔
- ③ 카드 하나 누름 = 연 노면공 · 범위 강조 풂 · 그 카드 하나(165-1 노면공 지킴 · 167-3 재누름 그대로 없앰)
- 카드 고름 세션 = 그 측점(구조물 id 는 목록 · 알약 · 넘김이 고른 것만)
- 종단: 구조물 넘김이면 측점선 · 3D 띠 안 켬
- 새 시험 test_189_1_pave_pick · test_165 · test_188_1 기대값 41번 규칙으로

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STqEqztUthVFBmEP18wBSz
2026-10-10 13:21:23 +09:00

131 lines
4.2 KiB
Python

# -*- coding: utf-8 -*-
"""PLAN 189-1 — 노면공(여러 측점 구간) 고름 세 갈래 · 종단 측점선(사용자 41번).
못박는 것
① 좌측 목록 노면공 = 범위 카드 전부 테두리 + 포장층 강조 · 카드 하나 안 고름 · 종단 측점선 없음.
② 카드 안 노면공 형상 누름 = ① 과 같음(고른 카드도 풂 · 카드 고름 리스너 안 돎).
③ 카드 하나 누름(형상 밖) = 목록 고름 · 범위 강조 풂 · 그 카드 하나 · 종단 측점선 = 그 카드 · 세션 sid 없음.
같은 카드 재누름 = 풂 · 관 자리 카드 = 관.
상태는 `helper_165_pavement_flow.cjs`(진짜 SPN) · 형상 → 노면공 찾기는 `helper_189_1_pave_shape.cjs`.
"""
import json
import os
import re
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 _node(name: str) -> dict:
proc = subprocess.run( # noqa: S603 — 고정 실행 파일
["node", os.path.join(HERE, name)],
capture_output=True,
text=True,
encoding="utf-8",
timeout=60,
)
assert proc.returncode == 0, proc.stderr
return json.loads(proc.stdout)
@pytest.fixture(scope="module")
def flow() -> dict:
return _node("helper_165_pavement_flow.cjs")
@pytest.fixture(scope="module")
def shape() -> dict:
return _node("helper_189_1_pave_shape.cjs")
def _read(*parts: str) -> str:
with open(os.path.join(ROOT, *parts), encoding="utf-8") as handle:
return handle.read()
PAVE = {
"form": "pave",
"pill": "pave",
"paveLayer": "pave",
"paveCards": 12,
"card": None,
"sid": "pave",
"line": None,
}
def _card(at):
return {
"form": None,
"pill": None,
"paveLayer": None,
"paveCards": 0,
"card": at,
"sid": None,
"line": None if at is None else f"s{at}",
}
def test_1_목록_고름은_범위_카드_전부_종단_선_없음(flow) -> None:
assert flow["r1"] == PAVE
def test_2_형상_누름은_목록_고름과_같음(flow) -> None:
assert flow["r2first"] == PAVE # 처음부터 형상
assert flow["r2"] == PAVE # 카드 하나 고른 뒤 형상 = 옛 카드 풂
assert flow["r2reveal"] == "s40"
def test_3_카드_하나는_목록_고름과_범위_강조를_풂(flow) -> None:
assert flow["r3"] == _card(140)
assert flow["r3b"] == _card(100)
assert flow["r3re"] == _card(None) # 같은 카드 재누름 = 풂
pipe = flow["r3pipe"]
assert (pipe["form"], pipe["pill"], pipe["paveCards"], pipe["sid"]) == (
"pipe-80.17",
"pipe-80.17",
0,
None,
)
def test_누른_포장층은_범위_표식으로_그_노면공(shape) -> None:
assert shape["pave"] == "pave"
assert shape["pave2"] == "pave2" # 겹친 노면공 = 누른 층
for key in ("plainLayer", "outside", "noTarget", "unknown"):
assert shape[key] is None, key
def test_배선() -> None:
view = _read("B06_Section", "B06_Section_UI_Section_View.ts")
# 형상 누름은 카드 고름보다 먼저 가로챔(잡기 단계 · 전파 멈춤)
body = re.search(
r"const pave = pavementAt\(event\.target, spanMarks\);(.*?)true,\n", view, re.S
)
assert body, "형상 누름 배선 없음"
assert "event.stopPropagation();" in body.group(1)
assert "pavementSelectListener?.(pave.structure_id);" in body.group(1)
cross = _read("A00_Common", "design", "design_view_cross.ts")
assert (
"sectionView.setPavementSelectListener((id) => structuresPanel.selectStructure(id));"
in cross
)
# 카드 하나 고름 = 그 측점(구조물 id 는 목록 · 알약 · 넘김만)
assert "const preferred = structuresPanel.preferred() !== null;" in cross
assert (
"const picked = preferred ? opened : { chainageM: opened.chainageM, structureId: null };"
in cross
)
profile = _read("A00_Common", "design", "design_view_profile.ts")
assert "const structurePick = !!readSelection(activeProjectId)?.structureId;" in profile