Files
Aislo/resources/tester/test_b05_routeedit_chrome_modal.py
T

142 lines
7.9 KiB
Python

"""계획노선 편집 겉틀 — 345-3 부터 모달이 아니라 종단 보기 가운데 위 본문(PLAN 127-1 의 공용 모달 조각은 걷음).
· 덮개(`ui-modal__backdrop`) · 전체 화면 · 닫기 단추 없음 · 부모를 받아 붙음(`document.body` 아님)
· [저장 전으로] 없음(352-2) · ↶ ↷ 는 기호 단추 · 머리 끝 `tools` 자리([3D])
· 오른쪽 횡단 미리보기 = 접는 칸 · 재계산 대기 막은 화면 전체(fixed) · R 라벨은 칸 안 절대 위치
· 바깥 누름 · Esc 로 안 닫힘(모달 아님)
"""
from __future__ import annotations
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
PAGE = ROOT / "B05_Profile"
def _block(css: str, selector: str) -> str:
found = re.search(rf"^{re.escape(selector)} \{{([^}}]*)\}}", css, re.M)
assert found, selector
return found.group(1)
def _read(name: str) -> str:
return (PAGE / name).read_text(encoding="utf-8")
def test_겉틀은_본문_칸():
chrome = _read("B05_Profile_UI_RouteEdit_Chrome.ts")
assert "ui-modal" not in chrome
assert "document.body.append" not in chrome
assert "parent.append(overlay);" in chrome
assert 'overlay.className = "b05-routeedit";' in chrome
assert "b05-routeedit__close" not in chrome and 'data-slot="close"' not in chrome
assert '"tools"' in chrome and "replaceWith(...tools)" in chrome
# 346-3 — [노선 반영] 없앰(노선은 페이지 [저장]이 맨 앞에서 보냄) · 352-2 — [저장 전으로] 없앰
assert 'data-act="apply"' not in chrome and 'data-act="cancel"' not in chrome
assert ">저장 전으로</button>" not in chrome and "노선 반영</button>" not in chrome
assert ">취소</button>" not in chrome and ">확인</button>" not in chrome
# 352-2 — 되돌리기 · 다시하기 = 글 없이 기호 + aria-label · title(단축키)
# 381-1 — 곧은 꼬리 + 갈고리 SVG(회전 반 바퀴 그림과 헷갈리지 않게)
assert 'aria-label="되돌리기" disabled>${HISTORY_ICON.undo}</button>' in chrome
assert 'aria-label="다시하기" disabled>${HISTORY_ICON.redo}</button>' in chrome
assert ">↶</button>" not in chrome and ">↷</button>" not in chrome
tools = _read("B05_Profile_UI_Profile_Tools.ts")
assert "undo.innerHTML = HISTORY_ICON.undo;" in tools
assert "redo.innerHTML = HISTORY_ICON.redo;" in tools
assert 'title="되돌리기 (Ctrl+Z)"' in chrome and 'title="다시하기 (Ctrl+Y)"' in chrome
# 시험 · 배선이 집는 자리는 남김
assert "b05-routeedit__measure-close" in chrome
# 382-1 — 오른쪽 횡단 판 = 패널 양식(손잡이 · 머리 · 폭 끌기 · 열림 · 폭 기억) · 칸 높이를 채움
assert "createSidePanels({" in chrome and 'prefKey: "b05-routeedit-cross-v2"' in chrome
assert "follow: false" in chrome and 'data-act="side-toggle"' not in chrome
def test_393_1_횡단_판_기본_접힘_자동_열림은_기억_안_함():
chrome = _read("B05_Profile_UI_RouteEdit_Chrome.ts")
assert "defaultOpen: null," in chrome and "innerWidth >= 1500" not in chrome
# 측점 눈금 → 열되 기억 안 함 · 손잡이(누름)만 기억
cross = _read("B05_Profile_UI_RouteEdit_Cross.ts")
assert 'panels.open("cross", false)' in cross
side = (ROOT / "ui_template" / "ui_template_side_panels.ts").read_text(encoding="utf-8")
assert "function open(id: string | null, remember = true): void {" in side
assert "JSON.stringify({ open: kept, width })" in side
assert "if (remember) {\n kept = next;\n save();" in side
def test_CSS_덮개_걷음_대기막은_전체():
css = _read("B05_Profile_UI_Style_RouteEdit.css")
root = _block(css, ".b05-routeedit")
assert "position: relative;" in root and "flex: 1 1 auto;" in root
assert "z-index" not in root and "background" not in root
busy = _block(css, ".b05-routeedit__busy")
assert "position: fixed;" in busy and "z-index: var(--z-modal, 1000);" in busy
label = _block(css, ".b05-routeedit__label")
assert "position: absolute;" in label and "position: fixed" not in label
# 382-1 — 자체 [횡단] 단추 · 접기 걷음(접기는 양식 손잡이)
assert "b05-routeedit__side-toggle" not in css and "is-side-open" not in css
assert "@media (width < 1500px)" not in css # 접기는 단추로(처음만 폭으로)
def test_352_1_머리줄_상자_없음_도구는_뜬_단추_횡단은_우측_덮개():
chrome = _read("B05_Profile_UI_RouteEdit_Chrome.ts")
for gone in ("b05-routeedit__box", "b05-routeedit__head", "b05-routeedit__actions", "<h3>"):
assert gone not in chrome
# 도구줄 = 3D 와 같은 떠 있는 유리 단추 · 구분선도 3D 것
assert 'class="b05-route__view-controls b05-routeedit__tools"' in chrome
assert "ui-btn--ghost" not in chrome.split("<aside", 1)[0]
# 도구줄은 지도 칸 안 · [?] 는 도구줄 뒤
wrap = chrome.index("b05-routeedit__canvas-wrap")
assert wrap < chrome.index("b05-routeedit__tools") < chrome.index("b05-routeedit__hint")
assert chrome.index("b05-routeedit__side-wrap") > chrome.index("b05-routeedit__busy")
css = _read("B05_Profile_UI_Style_RouteEdit.css")
for gone in (".b05-routeedit__box", ".b05-routeedit__head", ".b05-routeedit__actions"):
assert gone not in css
root = _block(css, ".b05-routeedit")
assert "padding" not in root and "gap" not in root
side = _block(css, ".b05-routeedit__side-wrap")
assert "position: absolute;" in side and "right: var(--spacing-12);" in side
z = int(re.search(r"z-index: (\d+);", side).group(1))
assert z < 3 # 아래 종단 판(z 3)이 위
style = _read("B05_Profile_UI_Style.css")
assert "z-index: 3;" in _block(style, ".b05-route-profile")
# 회전 단추 · 잰 값 창은 펴진 횡단 판을 비킴
assert "right: var(--spacing-12);" in _block(css, ".b05-routeedit__spin") # 도구줄 줄 오른쪽
assert "34px" in side # 횡단 판은 도구줄 줄 아래에서 시작
assert "var(--b05-side-open)" in _block(css, ".b05-routeedit__measure")
assert '"--b05-side-open"' in chrome # 판 폭(손잡이 포함)을 적음
glass = _block(css, ".b05-routeedit__terrain")
assert "backdrop-filter: blur(6px);" in glass and "background:" in glass
def test_페이지_수명_닫기_없음():
main = _read("B05_Profile_UI_RouteEdit.ts")
assert "openModal" not in main and "Escape" not in main
assert "openRouteEditModal" not in main
assert "export async function mountRouteEditor(" in main
assert 'window.addEventListener("resize"' not in main # 칸 크기는 ResizeObserver
assert "new ResizeObserver(" in main
assert "host.onDispose(dispose);" in main
assert "historyControls.listen(host.visible());" in main
assert "history?.reset()" not in main # 352-2 — [저장 전으로] 지움
hist = _read("B05_Profile_UI_RouteEdit_History.ts")
assert "reset" not in hist.split("export interface RouteEditHistory", 1)[1].split("}", 1)[0]
assert len(main.splitlines()) <= 700
label = _read("B05_Profile_UI_RouteEdit_Label.ts")
assert "document.body.append" not in label and "container.append(root);" in label
assert '"곡선 삭제" : "곡선 추가"' in label # 352-5 — 버튼 이름은 명사형
assert "container: overlay," in main
apply = _read("B05_Profile_UI_RouteEdit_Apply.ts")
assert "close" not in apply.split("export function bindRouteApply", 1)[1]
def test_393_5_접힌_손잡이는_지도_오른쪽_끝에_붙음():
css = _read("B05_Profile_UI_Style_RouteEdit.css")
flush = _block(css, ".b05-routeedit__side-wrap:has(.ui-side-panels.is-collapsed)")
assert "right: 0;" in flush
# 펼친 판은 그대로 띄움
assert "right: var(--spacing-12);" in _block(css, ".b05-routeedit__side-wrap")
side = (ROOT / "ui_template" / "ui_template_side_panels.ts").read_text(encoding="utf-8")
assert 'root.classList.toggle("is-collapsed", now === null);' in side