Files
Aislo/resources/tester/test_b05_routeedit_view.py
T
eomsangdonandClaude Opus 5.5 a108c3ae11 feat(B05 평면 도구줄): 구분선 · 스냅 간격 고르기 · Ctrl+휠 5° 회전 · [기울기] 기본 꺼짐 (390-1 · 2 · 3)
- [측점 스냅] · 간격 | 분석 지형 구분선(분석 지형 숨으면 같이 숨김) · [기울기] 기본 끔
- 스냅 간격 0.1 · 1 · 10 m · 측점 No.(기본) — 프로젝트별 화면 기억 · 스냅 끔이면 흐림 · MC 를 간격 배수에 · 허용 오차 간격 따라(0.1 m = 0.005 m)
- Ctrl+휠 한 칸 5° 회전(단추 15° 그대로 · 손가락 · 트랙패드 벌림 = 확대 · 추천 지도 안 돎) · 도움말 한 줄

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ji4nuyLVHcxrXWHTdb5nRD
2026-10-17 17:17:51 +09:00

97 lines
4.2 KiB
Python

# -*- coding: utf-8 -*-
"""계획노선 편집 창 — **보던 화면 기억**(계획서 18 ③)과 노드 끼우기·빼기 회귀검증.
화면은 창 크기와 무관한 꼴(가운데 m · 1m 당 픽셀 · 회전각)로 기억한다. 창 크기가 바뀌어도
같은 자리를 같은 배율로 다시 열어야 한다. 자리는 화면 취향 통(`aislo:pref:`)의 프로젝트 칸.
Node 헬퍼(`helper_b05_routeedit_view.cjs`)가 TS 를 트랜스파일해 돌리고, 여기서 값을 판정한다.
"""
import json
import math
import os
import subprocess
import pytest
HERE = os.path.dirname(os.path.abspath(__file__))
@pytest.fixture(scope="module")
def results():
proc = subprocess.run(
["node", os.path.join(HERE, "helper_b05_routeedit_view.cjs")],
capture_output=True,
text=True,
timeout=60,
)
assert proc.returncode == 0, proc.stderr
return json.loads(proc.stdout)
def test_다른_창_크기에서도_같은_가운데와_배율(results):
saved, again = results["saved"], results["again"]
assert again["cx"] == pytest.approx(saved["cx"], abs=1e-6)
assert again["cy"] == pytest.approx(saved["cy"], abs=1e-6)
assert again["pxPerMeter"] == pytest.approx(saved["pxPerMeter"], rel=1e-9)
assert saved["rotationDeg"] == pytest.approx(30.0)
def test_저장소_왕복은_프로젝트마다(results):
assert results["readBack"] == pytest.approx(results["saved"])
assert results["otherProject"] is None
assert results["storedKeys"] == ["aislo:pref:routeedit-view:p-1"]
def test_보던_화면이_없으면_노선에_맞추고_회전_0(results):
assert results["fresh"]["rotationRad"] == 0
assert results["fresh"]["scale"] > 0
assert results["withSaved"]["rotationRad"] == pytest.approx(math.radians(30))
def test_노선이_안_보이는_기억은_버리고_노선에_맞춤(results):
assert results["stray"]["rotationRad"] == 0
assert results["stray"]["onScreen"] is True
def test_창_크기가_바뀌어도_가운데와_배율_그대로(results):
before, after = results["keptBefore"], results["keptAfter"]
assert after["cx"] == pytest.approx(before["cx"], abs=1e-6)
assert after["cy"] == pytest.approx(before["cy"], abs=1e-6)
assert after["pxPerMeter"] == pytest.approx(before["pxPerMeter"], rel=1e-9)
def test_노드_끼우기_빼기는_편집값이_같은_자리로(results):
inserted = results["afterInsert"]
assert inserted["planned"][1] == [5, 5]
assert inserted["curveOn"] == [True, True, False, True]
assert inserted["curveRadius"] == [None, None, 30, None]
assert inserted["curveLock"] == [None, None, "radius", None]
assert inserted["curveArc"] == [None, None, 12, None]
assert inserted["apexLock"] == [False, False, True, False]
removed = results["afterRemove"]
assert removed["planned"] == [[0, 0], [10, 0], [20, 0]]
assert removed["curveRadius"] == [None, 30, None]
assert removed["apexLock"] == [False, True, False]
def test_숨김_크기_0_뒤_다시_보이면_그대로(results):
"""349-0h — 크기 0 으로 셈하면 구석 · 작게(옛 흠) · 건너뛰고 되살리면 떠나기 전 그대로."""
hidden = results["hidden"]
kept, from_zero, back = hidden["keptShown"], hidden["fromZero"], hidden["keptBack"]
assert from_zero["pxPerMeter"] < kept["pxPerMeter"] / 4 # 옛 길 — 아주 작게
assert from_zero["cx"] != pytest.approx(kept["cx"], abs=1.0) # 옛 길 — 가운데가 구석으로
assert back["cx"] == pytest.approx(kept["cx"], abs=1e-6)
assert back["cy"] == pytest.approx(kept["cy"], abs=1e-6)
assert back["pxPerMeter"] == pytest.approx(kept["pxPerMeter"], rel=1e-9)
def test_Ctrl_휠은_5도_돌리기_벌림과_맨_휠은_확대(results):
"""390-3 — 마우스 Ctrl+휠 한 칸 = 5° · 트랙패드 벌림 · 맨 휠 = 확대 · 추천 지도(rotateWheel 없음) = 확대."""
w = results["wheel"]
assert w["ctrlDown"] == {"deg": pytest.approx(5), "scale": 1, "changes": 1}
assert w["ctrlUp"]["deg"] == pytest.approx(-5) and w["ctrlUp"]["scale"] == 1
for case in ("trackpad", "plain", "recommend"):
assert w[case]["deg"] == 0 and w[case]["changes"] == 0, case
assert w[case]["scale"] != 1, case