Files
Aislo/resources/tester/test_588_key_registry.py
T
eomsangdonandClaude Opus 5.5 883a098cd6 feat(설정 마우스): 화면 옮기기 버튼 고르기 — 왼 · 가운데 · 오른 · 지도 · CAD · 종단 · 그림 칸 모두 따름 (PLAN 588-4 · 요구 445 C3)
- ☰ [설정] 마우스 탭 = 휠 방향 + 옮기기 버튼 라디오 · 규칙 글 = 고른 버튼 끌기 옮김(가운데는 늘)
- 끌면 옮김 · 덜 끌고 떼면 그 버튼 제 몫(고름 · 메뉴 · CAD Enter) · 오른쪽 끌기 뒤 메뉴 안 뜸
- 왼쪽 옮김은 페이지가 잡은 누름(B05 노드 · 손잡이 · 마커 · 재기 · D03 겹 · 그림 안 도형)에선 비킴
- 자리: B05 · B06 · D03 노선 지도 · CAD · 공용 SVG 확대 · B04 지도 · 3D(오른쪽만) · B05 배수 · 종단 가로 · B08 이정표 · M02 흐름도 · 노임
- 시험: CAD 오른쪽 끌기 옮김 · 옮기기 자리 배선 대조 · 낡은 헬퍼 둘 새 import 대응

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 19:08:40 +09:00

153 lines
5.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""PLAN 588 — 단축키 등록부 · 겹침 판정 · CAD 리본 묶음 · 찾기 (요구 445 C2 · C3).
· 등록부 = `A00_Common/key_registry.ts` — ☰ [설정] 표가 여기서 그려짐 · 바꿀 수 있는 줄은 코드가 부름
· 키 글 = 한글 자판에서도 자판 자리로(Ctrl+ㅋ = Ctrl+Z) · 바꾼 키만 먹음 · 못 바꾸는 줄은 바꾼 값 무시
· 겹침 = 같은 화면 자리끼리 · 「모든 화면」과 · 브라우저 몫 · CAD 글자 단독 — 다른 화면끼리는 같은 키 됨
· CAD 묶음 = 리본 탭 › 패널 · 154 명령이 꼭 한 묶음 · 기타 여섯(리본에 없음)
짝: `helper_588_key_registry.cjs`(실제 TS 를 Node 로 돌림).
"""
from __future__ import annotations
import json
import os
import subprocess
import pytest
HERE = os.path.dirname(__file__)
ROOT = os.path.join(HERE, "..", "..")
pytestmark = pytest.mark.skipif(
not os.path.isdir(os.path.join(ROOT, "config", "node_modules")),
reason="프론트엔드 의존성 미설치",
)
def _read(rel: str) -> str:
with open(os.path.join(ROOT, rel), encoding="utf-8") as f:
return f.read()
@pytest.fixture(scope="module")
def r() -> dict:
proc = subprocess.run( # noqa: S603 — 고정 실행 파일
["node", os.path.join(HERE, "helper_588_key_registry.cjs")],
capture_output=True,
text=True,
encoding="utf-8",
timeout=60,
)
assert proc.returncode == 0, proc.stderr
return json.loads(proc.stdout)
def test_CAD_154_명령_꼭_한_묶음_기타_여섯(r):
ids = r["groupIds"]
assert len(ids) == 154 and len(set(ids)) == 154
assert sorted(r["other"]) == ["LAYER", "PLACETABLE", "RECOVER", "REDO", "TOAREA", "UNDO"]
assert r["groups"][0]["label"] == "홈 › 그리기"
assert r["groups"][-1]["label"] == "" # 기타 이름은 화면 글(locale)
def test_찾기_낱말_모두_대소문자_무시(r):
f = r["find"]
assert {"LINE", "PLINE"} <= set(f["sun"]) and {"LINE", "PLINE"} <= set(f["L"])
assert "PLINE" in f["sunPl"] and "LINE" not in f["sunPl"] # 낱말 모두
assert f["blank"] == 154 and f["none"] == []
def test_키_글_한글_자판_안전(r):
c = r["chord"]
assert c["hangulCtrlZ"] == "Ctrl+Z"
assert c["ctrlShiftZ"] == "Ctrl+Shift+Z"
assert c["meta"] == "Ctrl+Z"
assert c["space"] == "Space"
assert c["shiftOnly"] == "" and c["process"] == ""
assert c["f3"] == "F3"
assert c["shiftDigit"] == "Ctrl+Shift+1"
assert c["arrow"] == "Shift+ArrowUp" and c["label"] == "Shift+↑"
def test_바꾼_키만_먹음_못_바꾸는_줄은_무시(r):
k = r["keyIs"]
assert k["delDefault"] is True and k["hangulUndo"] is True
assert k["delAfter"] is False and k["ctrlDAfter"] is True
assert k["fixedIgnored"] == ["Escape"]
assert k["cadAction"] == "cad.grid"
def test_겹침_판정(r):
c = r["check"]
assert c["none"] == {}
assert c["sameScope"] == {"plan.delete": "dup"}
assert c["withAll"] == {"plan.delete": "dup"}
assert c["withLoupe"] == {"plan.delete": "dup"}
assert c["otherPage"] == {} # D03 과 CAD 는 다른 화면
assert c["reserved"] == {"plan.delete": "reserved"}
assert c["cadLetter"] == {"cad.snap": "letter"}
assert c["cadShiftLetter"] == {"cad.snap": "letter"}
assert c["cadCtrl"] == {}
assert c["samePage"] == {"b05.undo": "dup"} # B05 · B06 한 페이지 — 횡단 Enter 와 겹침
assert c["swap"] == {} # 서로 바꿈은 됨
assert c["both"] == {"plan.drawFinish": "dup", "plan.drawBack": "dup"}
def test_등록부_꼴(r):
ids = [a["id"] for a in r["actions"]]
assert len(ids) == len(set(ids))
for a in r["actions"]:
assert a["scope"] in r["scopes"] and a["keys"]
assert a["id"].startswith(a["scope"] + ".")
# 바꿀 수 있는 줄 = 코드가 실제로 부름(등록부에만 있고 안 먹는 키 없음)
WIRED = {
"b05": "B05_Profile/B05_Profile_UI_Profile_Panel_Tools.ts",
"profile": "B05_Profile/B05_Profile_UI_Profile_Panel_Tools.ts",
"plan": "D03_PlanAnalysis",
"cad": "B07_DesignDetail/openwebcad/src/inputController",
}
def _sources(rel: str) -> str:
full = os.path.join(ROOT, rel)
if os.path.isfile(full):
return _read(rel)
names = sorted(n for n in os.listdir(full) if n.endswith(".ts"))
return "\n".join(_read(os.path.join(rel, n)) for n in names)
def test_바꿀_수_있는_줄은_배선됨(r):
for a in r["actions"]:
if a["fixed"]:
continue
src = _sources(WIRED[a["scope"]])
assert f'"{a["id"]}"' in src or f"'{a['id']}'" in src, a["id"]
def test_손글_안내_지움_표는_등록부():
assert "App_Settings_Keys_" not in _read("ui_template/ui_template_locale_common.ts")
assert "App_Settings_Keys_" not in _read("A00_Common/app_settings.ts")
# 588-4 — 화면 옮기기 자리는 모두 설정 버튼을 따름(가운데 고정 판정이 남지 않음)
PAN_SITES = [
"B05_Profile/B05_Profile_UI_RouteEdit_Input.ts", # B05 · B06 겹침 평면 · D03 지도
"B07_DesignDetail/openwebcad/src/inputController/input-controller.ts",
"A00_Common/b_svg_zoom_pan.ts",
"B04_PreProcess/B04_PreProcess_UI_MapViewer.ts",
"B04_PreProcess/B04_PreProcess_UI_Camera.ts",
"B05_Profile/B05_Profile_UI_Drainage_Interact.ts",
"B05_Profile/B05_Profile_UI_Profile_Wheel.ts",
"B08_Quantity/B08_Quantity_UI_Milestone_Diagram.ts",
"M02_MasterTemplete/DataFlow/M02_DF_Diagram.ts",
"M02_MasterTemplete/M02_MasterTemplete_Labor_Diagram.ts",
]
@pytest.mark.parametrize("rel", PAN_SITES)
def test_옮기기_자리는_설정_버튼(rel):
src = _read(rel)
assert "isPanButton(" in src or "isAuxPanButton(" in src, rel