Files
Aislo/resources/tester/test_588_key_registry.py
eomsangdonandClaude Opus 5.5 598b80eb26 refactor(794-1b): M01 흐름도 패널 걷음 — 로직 상세 오른쪽 = 원문만 · [신규 로직] = 빈 시트 줄 · 흐름 서버 길 · DataFlow 화면 지움
요구 651 · 653 — 계산 공식 참고용 흐름도(① M01 로직 상세 오른쪽 접는 패널)를 걷음. ② M02 일위대가 다이어그램은 그대로.

지움(64 파일 · 18,666 줄 · 되돌릴 길 = git 이력)
- M01 6 파일 1,064 줄 — Store_Flow.py · UI_LogicLab_Flow.ts/.css · FlowRows.ts · FlowView.ts/.css
- M02_MasterTemplete/DataFlow 43 파일 12,799 줄 — 흐름도 화면 · 셈(Compute · Convert · Lookup · Model · Eval …)
- 시험 15 파일 4,803 줄 — test_m01_logic_flow{view,_engine,_project,_save} · test_m02_df_*(값 찾기 values_old 뺌) — 지운 흐름 코드만 지키던 것

남김(바닥) — DataFlow M02_DF_UnitPick(일위대가 셋) · M02_DF_Values(M02_Item_Prices) · M02_DF_Round · _standard 표 ·
  M02_DF_Router = GET /api/m02/df/standards 하나 · M02_DF_Api = cfStandards 하나 · CfRound 꼴은 Round 안으로

고침
- M01 Router — /save = Store_Make.save(개정 확인 · 자체 파일 새 줄 GX · added 그대로) · /calc /text /logic/auto = 옛 셈만 · /logic/flow 둘 지움
- master_formula — 흐름 훅 지움 · 줄에 「흐름」 이 남으면 「흐름도 로직은 걷음」 까닭 오류(저장된 흐름 로직 0 — 마스터 · storage 다시 확인)
- Sangeun_Calc._defaults = 옛 자동값 · M02_Logic_Lib_Read /logic/flow 지움 · main.py 주석
- 화면 — LogicLab(startFlow · scheduleFlow · 예시값 잇기 지움 · [신규 로직] 줄 = 입력 · 중간 · 호표 빈 목록 + 끝수 null) ·
  Side(원문 패널 하나) · Source(머리 칸 이름 m01lab-src__top/__title · DF_Panel.css 안 씀) · Detail · View(nowInputs 지움) · Sheet(흐름 갈래 지움) · 글
- 시험 — 지운 파일을 가리키던 목록 넷(spreadsheet_size · 208_1 · 588 · input_prefs) · 717_1 흐름 길 두 줄 · values_old 흐름 셈 부분 지움
- test_713_3_list 기대 — 로직 1,461 → 1,515 · 묶음 307 → 335 · 작업량 21 → 65 · 부르는 506 → 512(782-1 · 2 · 3 건설 기초 로직 54 더함 ·
  옛 키만 세면 307 · 21 · 506 그대로)
- 새 지킴 test_794_1b_flow_gone — 흐름 길 404 · 표준 표 남음 · 신규 로직 자체 GX · 흐름 남은 줄 까닭 오류

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 19:38:39 +09:00

152 lines
5.6 KiB
Python
Raw Permalink 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/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