- 관 판정면(벽 판정면 아래 — 겹친 자리는 벽) · 누르면 관 두 겹 is-active - 고름 전용 키 RevetPick(RevetKey | "pipe") — 조정 함수는 RevetKey 그대로 - 조정창 없음(show "pipe" = 숨김 · side "pipe") · 좌측 fieldset[data-spec-container="pipe"] 강조 + 스크롤 - 좌측 「관」 상자 칸 고침 = 관 고름 · B05 3D pipe 키 → B06 관 고름 - 107-1 벽 · 본체 동시 고름 금지 그대로 · 관 숨긴 카드(링크 · 세월교 · 박스)엔 판정면 없음 - 시험 test_118_pipe_pick(helper_118_pipe_pick.cjs) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013rJwJMVL4EE31y77TB11AP
117 lines
4.6 KiB
Python
117 lines
4.6 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") {' in dock
|
|
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_Panel.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 } | 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): void => {" in view
|
|
assert "if (activeRevet !== null) toggleRevet(activeRevet);" in view
|