Files
Aislo/resources/tester/test_118_pipe_pick.py
T
eomsangdonandClaude Opus 5.5 d3d038349b fix(b06): 고름 강조 정리 — 측점 길은 형상 안 켬 · 연동 관 콘크리트만 · 측점 없는 구조물 스크롤 없음 (307)
- 노면공 포장층 강조 = 포장층을 직접 누른 턴만(paveShapeId) · 알약 · 목록 · 측점선 고름은 범위 테두리만
- 물넘이 콘크리트(pipe-…)는 측점 길 강조(highlightShapes)에서 뺌 — 형상 누름 「관」 고름만 켬 · 맹암거 그대로
- 벽 고름 「관」에 콘크리트 표식(형상 누름 ownerM · 관 없는 카드) · 카드 「관」 setter 를 관 그림 / 콘크리트로 가름(splitPipePick)
- 연동 관 카드 콘크리트 누름 = 관 형상 안 켬 · 콘크리트 ↔ 관 바꿔 누르면 풀지 않고 옮김 · 좌측 하위 컨테이너 켬 그대로
- 측점 없는 구조물 = 카드 고름 · 스크롤 없음(revealStation 스크롤 걷음 · 넘김 focusPicked)
- 시험: test_307_pick_highlight 새로 · 118 · 177_4 · 287 · 294_6 · 294_7 기대값 307 규칙으로

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

120 lines
4.7 KiB
Python

"""PLAN 118-1 — B06 배관 횡단도 관 고름 → 관 두 겹 강조 · 좌측 「관」 상자 강조 · 조정창 없음.
짝: `B06_Section/B06_Section_UI_Cross_Culvert.ts`(관 판정면 · 강조) · `_Cross_Structure_Panel.ts`(show "pipe") ·
`_Adjust_Dock.ts`(side "pipe") · `_Page_Structures_Panel.ts`(`keyOf`) · `_Page_Structure_Pick.ts`(3D pipe 키).
실제 TS 를 `helper_118_pipe_pick.cjs` 가 Node 로 돌린다.
"""
from __future__ import annotations
import json
import os
import subprocess
import pytest
HERE = os.path.dirname(__file__)
ROOT = os.path.join(HERE, "..", "..")
pytestmark = pytest.mark.skipif(
not os.path.isdir(os.path.join(ROOT, "config", "node_modules")),
reason="프론트엔드 의존성 미설치",
)
@pytest.fixture(scope="module")
def out() -> dict:
proc = subprocess.run( # noqa: S603 — 고정 실행 파일
["node", os.path.join(HERE, "helper_118_pipe_pick.cjs")],
capture_output=True,
text=True,
encoding="utf-8",
timeout=60,
)
assert proc.returncode == 0, proc.stderr
return json.loads(proc.stdout)
def _src(rel: str) -> str:
with open(os.path.join(ROOT, rel), encoding="utf-8") as f:
return f.read()
def test_관을_누르면_관을_고름(out) -> None:
overlay = out["overlay"]
assert overlay["firstPicked"] == ["pipe"]
assert overlay["stopped"] is True # 카드 고름으로 안 번짐
assert overlay["hitMatchesOuter"] is True # 판정면 = 외경
def test_관_판정면은_벽_아래(out) -> None:
"""겹친 자리는 벽이 이김 — 관 판정면이 벽 · 집수정 판정면보다 먼저 얹힘."""
order = out["overlay"]["hitOrder"]
assert order[0] == "pipe"
assert order.count("pipe") == 1 and len(order) > 1
def test_관_고름은_관_두_겹만_강조(out) -> None:
overlay = out["overlay"]
assert overlay["pipeCount"] == 2
assert overlay["onPipe"]["pipes"] == [True, True]
assert not any(overlay["onPipe"]["walls"])
# 벽을 고르면 관 강조는 꺼짐 — 동시 강조 없음
assert not any(overlay["onOutlet"]["pipes"]) and any(overlay["onOutlet"]["walls"])
assert not any(overlay["onNone"]["pipes"] + overlay["onNone"]["walls"])
def test_관을_숨긴_카드엔_관_판정면_없음(out) -> None:
"""링크 · 독립 흙막이 · 세월교 · 박스 측점(hidden_pipe) — 관은 세월교 오버레이 몫."""
assert out["hiddenPipe"]["pipes"] == 0
assert "pipe" not in out["hiddenPipe"]["picked"]
def test_관_강조는_주인_측점_카드만(out) -> None:
stands = out["stands"]
assert stands["self"] is True
assert stands["neighbour"] is False
assert stands["outletNeighbour"] is True # 벽 연동은 그대로
def test_3D_관_고름이_B06_으로_이어짐(out) -> None:
assert out["pick"]["pipe"] == [["revet", "pipe"]]
assert out["pick"]["basin"] == []
assert out["pick"]["fordPipe"] == [] # 세월교 측점 = 세월교 창 몫
def test_관은_조정창_없음(out) -> None:
panel = out["panel"]
assert panel["outlet"] == {"hidden": False, "side": "outlet"}
assert panel["pipe"] == {"hidden": True, "side": "pipe", "touched": []}
assert panel["none"] == {"hidden": True, "side": ""}
def test_좌측_관_상자_강조_스크롤() -> None:
dock = _src("B06_Section/B06_Section_UI_Adjust_Dock.ts")
assert 'if (side === "body" || side === "pipe" || side === "chute") {' in dock # 152-4 도수로
assert "'fieldset[data-spec-container=\"pipe\"]'" in dock
assert 'body.classList.add("is-active");' in dock
assert 'if (scroll) body.scrollIntoView({ block: "nearest" });' in dock
# 관 상자 칸을 고치면 관을 고름 — 횡단에서 누른 것과 같은 길
page = _src("B06_Section/B06_Section_UI_Page_Structures_Selection.ts")
assert 'if (id === "inlet" || id === "outlet" || id === "pipe") return id;' in page
css = _src("B06_Section/B06_Section_UI_Style_Cross_Areas.css")
assert ".b06-chart__culvert-pipe.is-active {" in css
def test_벽_본체_동시_고름_금지_그대로() -> None:
"""107-1 — 관도 같은 고름 저장소라 세월교 · 박스 고름과 함께 서지 않음."""
station = _src("B06_Section/B06_Section_UI_Page_Station_Controls.ts")
assert (
"let revetSelection: { at: string; key: RevetPick; shape?: boolean } | null = null;"
in station
)
assert (
"if (key && ford.control.selectedFor(chainageM)) ford.control.select(chainageM, null);"
in station
)
view = _src("B06_Section/B06_Section_UI_Cross_View.ts")
assert "const toggleRevet = (key: RevetPick, ownerM?: number): void => {" in view
assert "if (activeRevet !== null) toggleRevet(activeRevet);" in view