공용 common_util_view_window(viewOf · frameOf) 신설. design_profile rebuild · 접기 · render, Heights 높이 맞춤, 표 · 유토곡선 크기 끌기, 유토곡선 세로창 미끄러짐, 끌기 뒤 그리기, ▲▼ · 방향키 길게 누르기, 배수유역도, 구조물 말풍선 — 메인 창 전역 틀 · 시계 대신 요소가 놓인 창 것. 새 시험 test_230_2_popout_frames(메인 창 틀 멈춤 흉내 · 새 창 패널 코드 훑기). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F3mdb91125mPoC6tpsQx4P
106 lines
3.8 KiB
Python
106 lines
3.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""종단 새 창 최대화 — 같은 꼴 나머지(계획서 230-2) 회귀검증.
|
|
|
|
230-1 과 같은 까닭 — 메인 창 전역 화면 틀 · 시계는 새 창 최대화로 메인 창이 가려지면 멈추거나
|
|
늦게 돎. 새 창으로 가는 종단 패널(종단도 · 표 · 유토곡선 · 배수유역도)의 틀 · 시계는 공용
|
|
`viewOf` · `frameOf`(common_util_view_window) 로 그 요소가 놓인 창에서 받음.
|
|
|
|
`helper_230_2_popout_frames.cjs` 가 메인 창을 「가려짐」(틀 · 시계 멈춤)으로 두고 실제 함수 본문을 돌림.
|
|
옛 코드로는 아래 다시 그리기가 모두 0 번.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import re
|
|
import subprocess
|
|
|
|
import pytest
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
ROOT = os.path.dirname(os.path.dirname(HERE))
|
|
|
|
# 새 창으로 가는 종단 패널의 화면 코드
|
|
POPOUT_FILES = [
|
|
"A00_Common/design/design_profile.ts",
|
|
"A00_Common/design/design_profile_viewport.ts",
|
|
"B05_Profile/B05_Profile_UI_Profile_Wheel.ts",
|
|
"B05_Profile/B05_Profile_UI_Profile_Heights.ts",
|
|
"B05_Profile/B05_Profile_UI_Profile_MassHaul.ts",
|
|
"B05_Profile/B05_Profile_UI_Profile_TableOverlay.ts",
|
|
"B05_Profile/B05_Profile_UI_Profile_Drag.ts",
|
|
"B05_Profile/B05_Profile_UI_Profile_Edit.ts",
|
|
"B05_Profile/B05_Profile_UI_Profile_Panel_Tools.ts",
|
|
"B05_Profile/B05_Profile_UI_Drainage_Panel.ts",
|
|
"B05_Profile/B05_Profile_UI_Structures_Marks.ts",
|
|
"common_util/common_util_mass_haul_view.ts",
|
|
]
|
|
# 메인 창 전역 틀 · 시계 — `x.requestAnimationFrame` 처럼 창을 짚은 것은 제외
|
|
MAIN_WINDOW_CLOCK = re.compile(
|
|
r"(?<![.\w])(?:window\.)?(requestAnimationFrame|cancelAnimationFrame|setTimeout|setInterval)\("
|
|
)
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def r():
|
|
proc = subprocess.run(
|
|
["node", os.path.join(HERE, "helper_230_2_popout_frames.cjs")],
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
timeout=60,
|
|
)
|
|
assert proc.returncode == 0, proc.stderr
|
|
return json.loads(proc.stdout)
|
|
|
|
|
|
def test_공용_함수_놓인_창(r):
|
|
assert r["viewOf"] == {"popup": "popup", "detached": "main", "none": "main"}
|
|
|
|
|
|
def test_계획고_편집_뒤_다시_그림(r):
|
|
assert r["rebuild"] == {"draws": 1, "previews": 2, "mainTimers": 0} # 두 번 불러도 한 번
|
|
|
|
|
|
def test_높이_맞춤(r):
|
|
assert r["heights"] == {"syncs": 1, "mainTimers": 0}
|
|
|
|
|
|
def test_표_유토곡선_크기_끌기_다시_그림(r):
|
|
assert r["table"] == {"changed": 1, "handles": 2, "mainTimers": 0}
|
|
assert r["massHaul"] == {"changed": 1, "handles": 2, "mainTimers": 0}
|
|
|
|
|
|
def test_유토곡선_세로창_미끄러짐(r):
|
|
assert r["settle"] == {"redraws": 1, "frame": 0, "view": "popup", "mainTimers": 0}
|
|
|
|
|
|
def test_끌기_뒤_다시_그림(r):
|
|
assert r["drag"] == {"draws": 1, "mainTimers": 0}
|
|
|
|
|
|
def test_길게_누르기_새_창_시계(r):
|
|
# 0.5초 뒤부터 0.1초마다 — 1초 동안 5번 · 멈춘 뒤 더 안 돎
|
|
assert r["hold"] == {"acts": 5, "afterStop": 5, "mainTimers": 0, "popupTimers": 0}
|
|
|
|
|
|
def test_배수유역도_다시_그림(r):
|
|
assert r["drainage"] == {"draws": 1, "mainTimers": 0}
|
|
|
|
|
|
def test_새_창_패널_코드에_메인_창_틀_시계_없음():
|
|
found = []
|
|
for rel in POPOUT_FILES:
|
|
with open(os.path.join(ROOT, rel), encoding="utf-8") as f:
|
|
for no, line in enumerate(f, 1):
|
|
code = line.split("//")[0]
|
|
if code.lstrip().startswith("*"):
|
|
continue
|
|
if MAIN_WINDOW_CLOCK.search(code):
|
|
found.append(f"{rel}:{no}: {line.strip()}")
|
|
assert found == []
|
|
|
|
|
|
def test_design_profile_700줄_안():
|
|
with open(os.path.join(ROOT, "A00_Common/design/design_profile.ts"), encoding="utf-8") as f:
|
|
assert sum(1 for _ in f) <= 700
|