- 조정창(오버레이): 읽기 줄 · 줄 이름 · 머리줄 집수정 ↺ 지움 · 끄는 중 미리 보기 글만 · 좌측 사본 그대로 - 끌기: 벽 · 집수정 · 세월교 = 수평 + 1:1.2 사면 · 다단 · 독립 벽 = 수평 + 수직 · BOX = 길이 + 표고 - 한계(±10 m · 노견 안쪽 · 노면 위 · 다단 선반 · BOX 길이 0)면 가장 가까운 허용 자리 · 반영 한 번 - 시험 test_108_drag_box_hit(끌기 · 걸음 · 미리 보기 = placePipeWall 결과 · 한계 · BOX 판정면) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYJJRCfHfdCGNhmXTjQKV7
125 lines
5.2 KiB
Python
125 lines
5.2 KiB
Python
"""PLAN 108 — 횡단도 안 조정창 끌기 두 축 · 패널 걸음 맞춤 · 미리 보기 = 결과 · BOX 끝 판정면.
|
|
|
|
짝: `B06_Section/B06_Section_UI_Cross_Panel_Base.ts`(`snapAxisDrag` · `bindDragHandle`) ·
|
|
`_Cross_Structure_Panel.ts` · `_Cross_View_Structure.ts`(벽 · 집수정 축 · 한계) · `_Cross_Box_Panel.ts` ·
|
|
`_Cross_Box.ts`(`boxHitBands`). 실제 TS 를 `helper_108_drag_box_hit.cjs` 가 Node 로 돌린다.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
|
|
import pytest
|
|
|
|
HERE = os.path.dirname(__file__)
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def out() -> dict:
|
|
proc = subprocess.run( # noqa: S603 — 고정 실행 파일
|
|
["node", os.path.join(HERE, "helper_108_drag_box_hit.cjs")],
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
timeout=60,
|
|
)
|
|
assert proc.returncode == 0, proc.stderr
|
|
return json.loads(proc.stdout)
|
|
|
|
|
|
@pytest.mark.parametrize("side", ["diag1", "diag-1"])
|
|
def test_대각_끌기는_두_축이_함께_걸음_배수로(out, side) -> None:
|
|
"""배관 기준벽(1 m 걸음) — 사면 d 두 칸 + 수평 x 한 칸이 한 번에 · 값은 걸음 배수."""
|
|
case = out["wall"][side]
|
|
assert case["update"] == {"role": "outlet", "x": 1, "d": 4}
|
|
assert "◀" in case["snap"]["text"] or "▶" in case["snap"]["text"]
|
|
assert "▼ 2.0m" in case["snap"]["text"]
|
|
|
|
|
|
@pytest.mark.parametrize("side", ["diag1", "diag-1"])
|
|
def test_미리보기_자리는_놓은_뒤_자리와_같다(out, side) -> None:
|
|
"""미리 보기 이동 = `placePipeWall` 로 다시 푼 벽 자리 이동(화면 왼쪽 · 아래)."""
|
|
case = out["wall"][side]
|
|
assert case["snap"]["leftM"] == case["result"]["leftM"]
|
|
assert case["snap"]["downM"] == case["result"]["downM"]
|
|
|
|
|
|
def test_한계면_가장_가까운_허용_자리(out) -> None:
|
|
"""사면 위로 · 안쪽으로 넘겨 끌면 d 0 · x 0 에서 멈춤 — 원래 자리로 돌아가지 않음."""
|
|
case = out["wall"]["limit"]
|
|
assert case["update"] == {"role": "outlet", "x": 0, "d": 0}
|
|
assert case["snap"] == {"leftM": -1, "downM": -0.417, "text": "▶ 0.5m · ▲ 0.5m"}
|
|
|
|
|
|
def test_흙막이는_안쪽도_되고_10m_에서_멈춘다(out) -> None:
|
|
assert out["wall"]["guard"]["update"] == {"role": "outlet", "x": -10, "d": 0}
|
|
assert out["wall"]["guard"]["snap"]["leftM"] == -10
|
|
|
|
|
|
def test_다단_벽은_순수_수직_선반이_따라_나감(out) -> None:
|
|
"""다단 ▲▼ = 수직 하강 · x ≥ 1.2·d(선반) — 미리 보기도 그 자리."""
|
|
case = out["wall"]["extra"]
|
|
assert case["update"] == {"role": "extra0", "x": 1.2, "d": 1}
|
|
assert case["snap"]["leftM"] == 1.2 and case["snap"]["downM"] == 1
|
|
|
|
|
|
def test_집수정은_사면_축_0_1_걸음(out) -> None:
|
|
case = out["wall"]["basin"]
|
|
assert case["update"]["basin"]["lateralM"] == 0.9
|
|
assert case["update"]["basin"]["slopeM"] == 0.3
|
|
assert case["snap"] == {"leftM": -0.9, "downM": 0.25, "text": "▶ 0.6m · ▼ 0.3m"}
|
|
|
|
|
|
def test_걸음_반도_안_끌면_반영_없음(out) -> None:
|
|
assert out["wall"]["basinNone"] == {
|
|
"snap": {"leftM": 0, "downM": 0, "text": ""},
|
|
"update": None,
|
|
}
|
|
|
|
|
|
def test_BOX_끌기는_길이_표고_함께(out) -> None:
|
|
assert out["box"]["left"]["move"] == {"role": "left", "screen": 0.5, "rise": -0.3}
|
|
assert out["box"]["left"]["snap"]["leftM"] == 0.5
|
|
assert out["box"]["right"]["move"] == {"role": "right", "screen": -0.5, "rise": 0.2}
|
|
|
|
|
|
def test_BOX_한계_길이_0_표고_10(out) -> None:
|
|
"""안으로 줄이면 길이 0 에서 · 표고는 +10 m 에서 멈춤."""
|
|
assert out["box"]["shorten"]["move"] == {"role": "left", "screen": -0.2, "rise": 0.1}
|
|
|
|
|
|
def test_세월교_끌기는_좌우_사면_함께(out) -> None:
|
|
"""사면 d 0.3 · 좌우 0.2(0.1 걸음) — 미리 보기 = 좌 0.2 + 0.3 · 아래 0.3/1.2."""
|
|
case = out["ford"]["diag"]
|
|
assert case["move"] == {"role": "inlet", "screen": 0.2, "slope": 0.3}
|
|
assert case["snap"] == {"leftM": 0.5, "downM": 0.25, "text": "◀ 0.2m · ▼ 0.3m"}
|
|
|
|
|
|
def test_세월교_노견_안쪽은_0_에서_멈춤(out) -> None:
|
|
"""좌우 0.2 에서 안쪽으로 0.9 끌어도 0 까지만(가장 가까운 허용 자리)."""
|
|
case = out["ford"]["inward"]
|
|
assert case["move"] == {"role": "inlet", "screen": 0.2, "slope": 0}
|
|
assert case["snap"]["leftM"] == 0.2
|
|
|
|
|
|
def test_조정창은_제목과_단추만(out) -> None:
|
|
"""머리줄 = 제목 · 닫기(집수정 ↺ 없음) · BOX 오버레이 읽기 줄 = 끄는 중 미리 보기 하나."""
|
|
assert out["wall"]["diag1"]["overlayHead"] == [
|
|
"b06-structure-panel__title",
|
|
"b06-structure-panel__btn b06-structure-panel__close",
|
|
]
|
|
assert out["box"]["left"]["value"] == ["b06-structure-panel__drag"]
|
|
assert out["ford"]["diag"]["value"] == ["b06-structure-panel__drag"]
|
|
|
|
|
|
def test_BOX_끝_판정면은_본체로_안_넘어감(out) -> None:
|
|
"""본체 = 두 구체 끝 사이 · 끝 = 구체 끝 ~ 에이프런 바깥 · 날개벽 없는 끝 = 바깥 0.3 m 띠."""
|
|
hit = out["hit"]
|
|
assert hit["body"]["offsets"] == [-4, 4]
|
|
assert hit["left"]["offsets"] == [4, 6]
|
|
assert hit["right"]["offsets"] == [-4.3, -4]
|
|
for role in ("body", "left", "right"):
|
|
assert hit[role]["elevations"] == [96.5, 99]
|