- B05 목록 · 구조물 알약 누르기에 3D 강조가 안 따라옴 → 목록 고름 · 관 고름이 3D 도 그 측점으로 - 물넘이포장(측점선 없음) 목록 · 알약 · 카드 고름에 알약이 안 켜짐 → 관 알약 id 로 바로 켬 - B06 정규 측점 · 측점 사이 구조물을 고르면 카드가 켜지며 알약이 꺼짐 → 알약은 카드 뒤에 · 측점선 짝 판정이 규칙 측점 기준점도 봄 - B06 목록에서 다시 눌러 풀어도 알약이 남음 → 풂 = 알약도 끔 - B06 목록에서 푼 뒤 같은 카드 관 알약을 누르면 아무것도 안 골라짐 → 카드 다시 고름 - 알약 번호 · 툴팁 · 벌룬이 기타 손 이름 대신 「기타 N」 → 목록과 같은 이름 - 구조물집계표 기타 열 머리: 빈 이름이 「기타 구조물」 · 빈칸 글 → 「기타」(집계 건 이름과 같게) - [저장] 뒤 고른 구조물 강조가 풀림(다시 열면 되살아나 어긋남) → 같은 id 면 그대로 고름 - 목록 줄 마우스 올림 테두리 - 시험: ui_checks/53-2_목록_강조.js · test_53_2_etc_table_name.py · test_design_page_single 판정 자리 옮김 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013rJwJMVL4EE31y77TB11AP
113 lines
5.8 KiB
Python
113 lines
5.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""한 페이지 뼈대(계획서 24-3a) · 겹친 알약(24-6b) 회귀검증.
|
|
|
|
주소 둘(`#/b05-profile` · `#/b06-section`)이 같은 페이지(`A00_Common/design/design_page.ts`)를
|
|
열고, 같은 페이지 안 이동은 다시 만들지 않고 보기만 바꾸는지, 떠날 때 3D(WebGL 문맥) ·
|
|
종단도 · 횡단을 정리하는지, 숨긴 3D 는 그리기 루프를 멈추는지, 창에 건 키 듣기를 떼는지 본다.
|
|
화면 수치(문맥 수 · 루프 · 같은 노드 · 전환 시간)는 ORCA 로 잰다 — 여기서는 길이 끊기지 않게 잠근다.
|
|
"""
|
|
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent.parent
|
|
|
|
|
|
def _read(relative: str) -> str:
|
|
return (ROOT / relative).read_text(encoding="utf-8")
|
|
|
|
|
|
def test_주소_둘이_같은_페이지():
|
|
router = _read("A00_Common/router.ts")
|
|
assert router.count('(await import("./design/design_page")).renderDesignPage') == 2
|
|
assert "export function showWithinPage(" in router
|
|
# 다른 페이지로 떠나면 정리 · 늦게 끝난 옛 렌더는 버림
|
|
assert "mounted?.dispose();" in router
|
|
assert "if (page && seq !== renderSeq) page.dispose();" in router
|
|
|
|
|
|
def test_같은_페이지면_셸도_다시_안_그림():
|
|
main = _read("A00_Common/main.ts")
|
|
within = main.index("showWithinPage(currentRoute())")
|
|
assert within < main.index("renderShell(appRoot")
|
|
assert "if (within) return;" in main
|
|
|
|
|
|
def test_보기_약속_가운데만():
|
|
"""끝 모습(24-3b) — 보기는 가운데 위 칸만 채우고 좌측 패널 · 단추 · 종단도는 한 벌을 쓴다."""
|
|
page = _read("A00_Common/design/design_page.ts")
|
|
assert "export interface DesignPageView" in page
|
|
assert "mount?: (root" not in page # 보기가 틀을 통째로 그리던 중간 길은 걷음
|
|
assert "mountCenter: (" in page and "shared: DesignPageShared" in page
|
|
assert 'import("./design_view_profile")).mountProfileView' in page
|
|
assert 'import("./design_view_cross")).mountCrossView' in page
|
|
for hook in ("onShow:", "onHide:", "onDispose:"):
|
|
assert hook in page
|
|
# 보기는 처음 보일 때 한 번만 만든다 — 있으면 보이기만.
|
|
assert "if (slot) {\n slot.show();" in page
|
|
|
|
|
|
def test_페이지가_숨김_떠남을_건다():
|
|
life = _read("B05_Profile/B05_Profile_UI_Page_Life.ts")
|
|
assert "deps.viewer.setActive(false)" in life and "deps.viewer.dispose()" in life
|
|
assert "bindProfileViewLife(host," in _read("A00_Common/design/design_view_profile.ts")
|
|
cross = _read("A00_Common/design/design_view_cross.ts")
|
|
assert "sectionView.dispose();" in cross[cross.index("host.onDispose(") :]
|
|
# 종단도는 한 벌 — 보기가 숨어도 그대로 두고, 페이지를 떠날 때 한 번 정리한다.
|
|
assert "shared.profile?.dispose();" in _read("A00_Common/design/design_page.ts")
|
|
|
|
|
|
def test_3D_멈춤과_문맥_놓기():
|
|
viewer = _read("B05_Profile/B05_Profile_UI_Viewer.ts")
|
|
assert "setActive(active)" in viewer
|
|
assert "renderer.forceContextLoss();" in viewer
|
|
# 보관 지형은 다음 뷰어가 쓴다 — 떠날 때 버리지 않는다.
|
|
assert "if (terrain !== cachedTerrain.object) disposeObject(terrain);" in viewer
|
|
assert len(viewer.splitlines()) <= 700
|
|
|
|
|
|
def test_창_키_듣기를_뗌():
|
|
tools = _read("B05_Profile/B05_Profile_UI_Profile_Panel_Tools.ts")
|
|
assert 'window.removeEventListener("keydown", onKeyDown);' in tools
|
|
assert 'window.addEventListener("keydown", (event)' not in tools
|
|
profile = _read("A00_Common/design/design_profile.ts")
|
|
assert "setListening(false);" in profile # dispose
|
|
pick = _read("B05_Profile/B05_Profile_UI_Viewer_Structure_Pick.ts")
|
|
assert "setListening(on)" in pick
|
|
|
|
|
|
def test_겹친_알약은_누른_것을_그대로():
|
|
profile = _read("A00_Common/design/design_profile.ts")
|
|
assert "structureIdKeeping(stationId, selectedStructureId" in profile
|
|
# 판정은 `_Profile_Structures` 로 옮김 — 비정규 측점 짝 · 규칙 측점(B06 카드) 기준점(53-2)
|
|
rule = _read("B05_Profile/B05_Profile_UI_Profile_Structures.ts")
|
|
assert "stationIdAtStructure(selectedId, stations, structures) === stationId" in rule
|
|
assert "Math.abs(structureAnchorM(selected) - at) < SAME_CHAINAGE_M" in rule
|
|
|
|
|
|
def test_진행_단계_두_칸이_보기를_따라감():
|
|
"""종단설계 · 횡단설계 두 칸은 같은 페이지 — 누르면 주소만 바꿔 보기만 바뀐다(계획서 24-3b)."""
|
|
page = _read("A00_Common/design/design_page.ts")
|
|
assert "const VIEW_STEP: Record<DesignView, number> = { profile: 2, cross: 3 };" in page
|
|
assert "layout?.setActiveStep(VIEW_STEP[view]);" in page
|
|
assert "layout?.setTitle(" in page
|
|
click = page[page.index("onStepClick: (stepIndex) => {") :][:260]
|
|
assert "if (designViewOf(route)) navigateTo(route);" in click
|
|
layout = _read("ui_template/ui_template_workflow_layout.ts")
|
|
assert "setActiveStep: (stepIndex) =>" in layout and "setTitle: (title) =>" in layout
|
|
|
|
|
|
def test_초기화_계획노선_편집은_다시_세움():
|
|
"""같은 페이지 안 이동은 보기만 바꾸므로 [초기화] · 계획노선 편집은 페이지를 다시 세운다."""
|
|
router = _read("A00_Common/router.ts")
|
|
assert "export function remountRoute(" in router
|
|
assert "remountRoute(ROUTES.B05_PROFILE)" in _read("A00_Common/design/design_reset.ts")
|
|
assert "remountRoute(ROUTES.B05_PROFILE)" in _read("A00_Common/design/design_view_profile.ts")
|
|
|
|
|
|
def test_종단_보기_확정은_횡단_보기를_숨긴_채_세움():
|
|
page = _read("A00_Common/design/design_page.ts")
|
|
assert "ensureView: (view) => (slots.get(view) ?? mountView(view, false)).ready," in page
|
|
cross = _read("A00_Common/design/design_view_cross.ts")
|
|
# 숨긴 채 섰으면 한 벌 폼은 종단 보기 몫 — 보일 때 싣는다.
|
|
assert "if (host.visible()) void structuresPanel.load()" in cross
|