"""PLAN 332-1 — 휠 확대 방향 한 설정(`A00_Common/input_prefs.ts`) · 모든 휠 화면이 그 판정을 거침. · 기본 = 당김(휠을 몸 쪽으로 = 확대) · 밀기 저장 뒤 뒤집힘 · 깨짐 · 모르는 값 · 막힌 저장소 · Node = 기본 · 핀치(트랙패드 · 손가락)는 설정과 상관없이 늘 벌리면 확대 · 키 = 등록표 `input-prefs`(pref · global) 와 같은 글자 짝: `helper_input_prefs.cjs`(실제 TS 를 Node 로 돌림). """ from __future__ import annotations import json import os import re 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_input_prefs.cjs")], capture_output=True, text=True, encoding="utf-8", timeout=60, ) assert proc.returncode == 0, proc.stderr return json.loads(proc.stdout) PULL = {"pull": True, "push": False, "mouseCtrl": True, "bridgePull": True} PINCH = {"padSpread": True, "padPinch": False, "fingerSpread": True} def _pick(case: dict, keys: dict) -> dict: return {k: case[k] for k in keys} def test_Node_기본_당김(r): n = r["node"] assert n["default"] == {"wheelZoom": "pull", "cadAliases": {}} assert n["prefs"] == n["default"] assert _pick(n, PULL) == PULL and _pick(n, PINCH) == PINCH def test_밀기_저장_뒤_뒤집힘_핀치는_그대로(r): p = r["push"] assert p["prefs"]["wheelZoom"] == "push" assert _pick(p, PULL) == {"pull": False, "push": True, "mouseCtrl": False, "bridgePull": False} assert _pick(p, PINCH) == PINCH # 벌리면 확대는 설정과 상관없음 # 별칭 = 대문자 · 글자 아닌 것 · 빈 목록 버림 assert p["prefs"]["cadAliases"] == {"LINE": ["LL"]} @pytest.mark.parametrize("case", ["broken", "unknown", "empty", "blocked"]) def test_깨짐_모르는_값_없음_막힘_기본(r, case): c = r[case] assert c["prefs"] == {"wheelZoom": "pull", "cadAliases": {}} assert _pick(c, PULL) == PULL and _pick(c, PINCH) == PINCH def test_등록표_키(r): assert r["node"]["key"] == r["registryKey"] == "aislo:pref:input-prefs" assert r["registryEntry"] == {"bucket": "pref", "scope": "global"} def test_읽기_층은_의존_없음_불러올_때_window_안_만짐(): src = _read("A00_Common/input_prefs.ts") assert not re.search(r"^import ", src, re.M) assert "window." not in src # 휠 줌 자리 — 직접 박은 방향(`deltaY < 0 ?` · `deltaY > 0 ?` · `-ev.deltaY`)이 없고 공용 판정을 부름 WHEEL_SITES = { "A00_Common/touch_bridge.ts": "wheelEventIn(e, isPinchWheel(e))", "A00_Common/b_svg_zoom_pan.ts": "wheelEventIn(event)", "B04_PreProcess/B04_PreProcess_UI_Camera.ts": "wheelEventIn(event)", "M02_MasterTemplete/DataFlow/M02_DF_Diagram.ts": "wheelZoomsIn(ev)", "M02_MasterTemplete/M02_MasterTemplete_Labor_Diagram.ts": "wheelZoomsIn(e)", "ui_template/ui_template_loupe.ts": "wheelIn(deltaY)", "A00_Common/spreadsheet/spreadsheet_grid.ts": "wheelZoomsIn(ev)", # wheelZoomsIn 을 거쳐 따라오는 셋 "B04_PreProcess/B04_PreProcess_UI_MapViewer.ts": "wheelZoomsIn(event)", "B05_Profile/B05_Profile_UI_Drainage_Interact.ts": "wheelZoomsIn(event)", "B05_Profile/B05_Profile_UI_RouteEdit_Input.ts": "wheelZoomsIn(event)", } @pytest.mark.parametrize("rel", sorted(WHEEL_SITES)) def test_휠_자리_공용_판정(rel): src = _read(rel) assert WHEEL_SITES[rel] in src assert not re.search(r"deltaY [<>] 0 \?", src), rel assert "-ev.deltaY" not in src and "Math.sign(-deltaY)" not in src def test_700줄_안(): for rel in WHEEL_SITES: assert _read(rel).count("\n") <= 700, rel