Files
Aislo/resources/tester/test_116_right_click_add.py
T
eomsangdonandClaude Opus 5.5 157111a094 feat(B05): 우클릭 세월교 · 물넘이포장도 바로 추가 · 빈 월류 높이는 재계산 유량이 오면 그 항목에 채움(126-1)
- 우클릭 바로 추가에서 세월교 · 물넘이포장을 폼만 갈래에서 뺌 · 추가 뒤 그 측점 관 고름 + 알림 한 줄
- 배수유역 패널 — 바로 놓은 빈 높이 측점을 기다렸다가 응답 유량으로 필요 수심 채움(`fordHeightM` · 서버 `ford_height_m` 짝) · 손 값은 안 덮음 · 유량 전엔 빈칸 · 채우면 세션 초안에 다시 담음
- 세부유역 요청은 최신 응답만 채택(requestSeq)
- 시험 test_126_ford_right_click(헬퍼 helper_126_ford_fill) · test_116 기대값 고침

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

115 lines
4.3 KiB
Python

# -*- coding: utf-8 -*-
"""116-1 종단 우클릭 → 종류 고름 = 「[추가]까지 끝난 상태」.
못박는 것
- 필수 빈칸 없는 종류 = 그 측점에 바로 추가(캐시) + 새 항목을 고른 채(구조물 = 임시 id · A군 = 측점).
- 필수 빈칸 남는 종류 · 노면공(확인창) = 폼만 · 세월교 · 물넘이포장은 바로 추가(126-1 · test_126).
- [추가]가 거절하면 아무것도 안 듦 · 고르지 않음.
- 새로 놓기에서 시작 — 옛 집계 항목 · 그룹 잇기 · 메모가 새 항목에 안 실림.
- 세 길(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 True and once["fordPavement"] is True # 126-1
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