Files
Aislo/resources/tester/test_116_right_click_add.py
T
eomsangdonandClaude Opus 5.5 d87d6eec43 feat(B05): 종단 우클릭 → [추가]까지 끝난 상태 — 필수 빈칸 없는 종류 바로 추가 + 고른 채 · 패널 폄 · 옛 잇기 비움(116-1)
- 패널 addAt(B05 종단 · B06 종단 · 3D 공용) = 새로 놓기(startNew)에서 시작 · 좌측 패널 열고 「구조물 배치」 폄
- 필수 빈칸 없는 종류 = [추가] 대신 누름 + 새 항목 고름(구조물 = 임시 id · A군 = 그 측점 관)
- 필수 빈칸 · 노면공(확인창) · 세월교 · 물넘이포장(월류 높이 = 유량 뒤) = 폼만 · A군 임시 배치 그대로
- 시험 test_116_right_click_add(헬퍼 helper_116_right_click_add.cjs)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UoSr2sqvYtBf1dtQdus88s
2026-10-08 18:28:51 +09:00

115 lines
4.3 KiB
Python

# -*- coding: utf-8 -*-
"""116-1 종단 우클릭 → 종류 고름 = 「[추가]까지 끝난 상태」.
못박는 것
- 필수 빈칸 없는 종류 = 그 측점에 바로 추가(캐시) + 새 항목을 고른 채(구조물 = 임시 id · A군 = 측점).
- 필수 빈칸 남는 종류 · 노면공(확인창) · 세월교 · 물넘이포장(월류 높이 = 유량 뒤) = 폼만.
- [추가]가 거절하면 아무것도 안 듦 · 고르지 않음.
- 새로 놓기에서 시작 — 옛 집계 항목 · 그룹 잇기 · 메모가 새 항목에 안 실림.
- 세 길(B05 종단 · B06 종단 · 3D)이 모두 패널 `addAt` 한 곳 · 패널을 열고 「구조물 배치」를 폄.
Node 헬퍼 `helper_116_right_click_add.cjs` 가 판정 · 끝맺음 · `loadForm(null)` 을 돌림. 화면은 사용자 확인.
"""
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, "..", ".."))
def _read(*parts: str) -> str:
with open(os.path.join(ROOT, *parts), encoding="utf-8") as f:
return f.read()
@pytest.fixture(scope="module")
def out():
proc = subprocess.run(
["node", os.path.join(HERE, "helper_116_right_click_add.cjs")],
capture_output=True,
text=True,
encoding="utf-8",
timeout=60,
)
assert proc.returncode == 0, proc.stderr
return json.loads(proc.stdout)
def test_필수_빈칸_없는_종류만_바로_추가(out):
once = out["once"]
assert once["noRequired"] is True
assert once["pipe"] is True and once["box"] is True
assert once["requiredEmpty"] is False
def test_노면공_세월교_물넘이포장은_폼만(out):
once = out["once"]
assert once["pavement"] is False
assert once["fordBridge"] is False and once["fordPavement"] is False
def test_구조물은_목록에_들고_새_임시_id로_고른_채(out):
s = out["structure"]
assert s["done"] is True and s["commits"] == 1 and s["count"] == 2
assert s["picked"] == [["id", "local1"]] # 옛 항목(old1)이 아니라 새 항목
def test_추가가_거절하면_고르지_않고_폼만(out):
r = out["refused"]
assert r["done"] is False and r["count"] == 1 and r["picked"] == []
def test_A군은_추가_뒤_그_측점_관을_고름(out):
p = out["pipe"]
assert p["done"] is True and p["commits"] == 1
assert p["picked"] == [["pipe", 120]]
def test_새로_놓기가_옛_집계_항목_그룹_잇기를_비움(out):
c = out["cleared"]
assert c["summary"] is None and c["groups"] == {} and c["memo"] == ""
def _add_at_body() -> str:
src = _read("B05_Profile", "B05_Profile_UI_Structures_Panel.ts")
start = src.index(" addAt(chainageM, typeId) {")
return src[start : src.index(" moveById(", start)]
def test_addAt_은_새로_놓기_패널_폄_후_판정():
body = _add_at_body()
order = [
body.index("startNew(type.group, typeId)"),
body.index("callbacks.onReveal?.()"),
body.index('root.classList.remove("is-collapsed")'),
body.index("addsAtOnce(type, optionInputs)"),
body.index("finishAdd("),
body.index("commitTempPipe()"), # 폼만 갈래 — A군 임시 배치 그대로
]
assert order == sorted(order)
assert "DEFAULT_INTERVAL_LENGTH_M" in body # 구간형 기본 15 m 그대로
events = _read("B05_Profile", "B05_Profile_UI_Structures_Panel_Events.ts")
new = events[
events.index("function startNew(") : events.index("ctx.groupSelect.addEventListener")
]
assert "ctx.resetForm()" in new and "onListRelease" in new
assert "return { startNew }" in events
def test_세_길이_모두_패널_addAt_한_곳():
profile = _read("A00_Common", "design", "design_view_profile.ts")
assert re.search(
r"onStructureTypeAdd: \(chainage, typeId\) => panel\.structures\.addAt\(", profile
)
cross = _read("A00_Common", "design", "design_view_cross.ts")
assert "structuresPanel.addStructureAt(chainageM, typeId)" in cross
b06 = _read("B06_Section", "B06_Section_UI_Page_Structures_Panel.ts")
assert "addStructureAt: (chainageM, typeId) => section.addAt(chainageM, typeId)" in b06
viewer = _read("B05_Profile", "B05_Profile_UI_Page_Structures.ts")
assert "onPick: (chainage, typeId) => deps.panel().structures.addAt(chainage, typeId)" in viewer