"""500-1 B05 평면 — 곡선(교각점 · 손잡이 · 호) 누름 = 측점 고름 유지 · 풀림 = 오른쪽 판도 비움 · 임시 횡단 창 단추 = 제목 줄 · 제목 줄 끌기. ./venv/Scripts/python.exe -m pytest resources/tester/test_500_1_curve_keeps_pick.py -q """ from __future__ import annotations from pathlib import Path ROOT = Path(__file__).resolve().parents[2] def _read(*parts: str) -> str: return ROOT.joinpath(*parts).read_text(encoding="utf-8") def _down() -> str: """평면 누름 — 마커 갈래 뒤 ~ 교각점 갈래 앞.""" pointer = _read("B05_Profile", "B05_Profile_UI_RouteEdit_Pointer.ts") start = pointer.index("if (choice.mark && marks.press(px, py)) {") return pointer[start : pointer.index("if (hitNode >= 0) {", start)] # 누름별 — 고름 유지(풂 건너뜀) 조건 한 줄씩 KEEP = { "교각점": '(!!pick && "node" in pick)', "손잡이": "choice.handle !== null", "호(눈금 아님)": '(!(pick && "chainage" in pick) && arcAtScreen(state.curveInfo, toScreen, px, py) >= 0)', } def test_곡선_누름은_고름_유지() -> None: down = _down() for name, cond in KEEP.items(): assert cond in down, name assert "if (!onCurve) marks.deselect();" in down # 그 밖(빈 땅 · 등고선 · 눈금) = 풂 assert down.count("marks.deselect()") == 1 # 무조건 풂 걷힘 def test_차례_마커_다음_교각점_앞() -> None: down = _down() assert down.index("canvas.setPointerCapture(event.pointerId);") < down.index("const onCurve") assert down.index("const onCurve") < down.index("if (!onCurve) marks.deselect();") def test_풀림은_오른쪽_판도_비움() -> None: cross = _read("B05_Profile", "B05_Profile_UI_RouteEdit_Cross.ts") line = "if (from !== PLAN_PICK_FROM || selection.chainageM === null) follow(selection);" assert line in cross follow = cross[cross.index("function follow(") : cross.index(line)] assert "watching = null;" in follow and "current.show(null, interval());" in follow # 풂(값 없음 · 평면 이름)을 내는 곳 = 마커 풂 하나 · Esc 도 같은 길 marks = _read("B05_Profile", "B05_Profile_UI_RouteEdit_StructureMarks.ts") assert marks.count("selectDesign(projectId, NO_SELECTION, { from: PLAN_PICK_FROM });") == 1 assert "!activeMoving(canvas) && deselect()" in marks def test_임시_횡단_단추_제목_줄_오른쪽() -> None: modal = _read("B05_Profile", "B05_Profile_UI_Profile_CrossModal.ts") head = modal[ modal.index('
') : modal.index( '
' ) ] for act in ("add", "remove", "close"): assert f'data-act="{act}"' in head assert head.index("임시 횡단") < head.index("b05-crossmodal__actions") css = _read("B05_Profile", "B05_Profile_UI_Profile_CrossModal.css") actions = css[css.index(".b05-crossmodal__actions {") :] assert "margin-left: auto;" in actions[: actions.index("}")] def test_제목_줄_끌기_화면_안() -> None: modal = _read("B05_Profile", "B05_Profile_UI_Profile_CrossModal.ts") assert 'bindHeadDrag(root, $(".b05-crossmodal__head"))' in modal drag = modal[modal.index("function bindHeadDrag(") : modal.index("interface CrossModal {")] assert '.closest("button")' in drag # 단추 누름은 단추 몫 assert "innerWidth" in drag and "innerHeight" in drag # 화면 밖 안 나감 assert "root.parentElement!.getBoundingClientRect()" in drag # 종단 칸 안 assert "refit();" in modal # 다시 열 때 가둠 def test_500_2_측점선_띠_안_임시_횡단_먼저() -> None: modal = _read("B05_Profile", "B05_Profile_UI_Profile_CrossModal.ts") # 단추 = other 먼저 · 추가 측점선 = plusM · 그 밖 측점선 = station(띠 안이면 임시 횡단) flat = " ".join(modal.split()) assert 'target.closest("button") ? "other" : marker ? "station" : null' in flat logic = _read("B05_Profile", "logic", "B05_Profile_Profile_CrossPick.ts") assert '"station"' in logic and 'input.hit === "other"' in logic # 누름 = 잡는 단계에서 띠 안 측점선의 자기 고름을 막고 임시 횡단을 엶 render = _read("B05_Profile", "B05_Profile_UI_Profile_Render.ts") start = render.index("// 잡는 단계(capture)") click = render[start : render.index("const derived = deriveProfile", start)] assert "event.stopPropagation()" in click and "openCrossModal(" in click assert " ".join(click.split()).endswith("}, true, );")