Files
Aislo/resources/tester/test_398_2_curve_input.py
T
eomsangdonandClaude Opus 5.5 7846827fab feat(B05 노선 편집 R 입력): 반지름 · 곡선 길이 뒤 상태줄 함께 밀린 교점 · 못 맞춘 곡선 보고 + 뒤쪽 MC 시험 (408-1)
- 맞춤 함수 그대로(fitCurveStations) · 스냅 켬일 때만 꼬리 — KeyNudge nudgeReport 재사용 fitNote
- StationFit offStationMcs(측점 밖 MC 목록) · offStationCount 는 그 길이
- 시험 test_408_radius_downstream 새로 · test_398_2 뒤쪽 곡선 MC 더함

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

89 lines
3.6 KiB
Python

"""398-2 꺾임점 창 반지름 · 곡선 길이 넣기(요구 249) — 넣은 값으로 곡선이 바뀜 ·
스냅 켬 = 맞춤 뒤 값 · 접선 자리 모자라 눌리면 칸 = 그린 값 · 상태줄 = 넣은 값 · 그린 값 · 까닭 ·
「고정」 켬 = 그 값 지킴.
까닭: 접선은 앞뒤 직선 짧은 쪽 절반까지(`buildEditedPolyline` · 서버 짝)라 큰 R 이 조용히 눌렸는데
창 칸은 넣은 값을 그대로 보여 바뀐 게 없어 보였음.
TS 셈은 `helper_398_2_curve_input.cjs`(Node · `_CurveBar` 배선 그대로).
./venv/Scripts/python.exe -m pytest resources/tester/test_398_2_curve_input.py -q
"""
import json
import subprocess
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[2]
HELPER = Path(__file__).with_name("helper_398_2_curve_input.cjs")
@pytest.fixture(scope="module")
def got() -> dict:
run = subprocess.run( # noqa: S603 — 고정 실행 파일
["node", str(HELPER)],
capture_output=True,
text=True,
encoding="utf-8",
timeout=120,
)
assert run.returncode == 0, run.stderr
return json.loads(run.stdout)
@pytest.mark.parametrize("snap", ["snapOff", "snapOn"])
def test_반지름_40_60_곡선이_바뀜(got, snap) -> None:
row = got[snap]
assert row["r40"] == pytest.approx(40) and row["r60"] == pytest.approx(60)
assert row["r60Shown"] == pytest.approx(60)
assert "반지름을 바꿨습니다" in row["r60Status"]
@pytest.mark.parametrize("snap", ["snapOff", "snapOn"])
def test_곡선_길이_18_25_곡선이_바뀜(got, snap) -> None:
row = got[snap]
tol = 0.1 if snap == "snapOn" else 1e-6 # 스냅 켬 = IP 맞춤으로 교각이 조금 바뀐 뒤 값
assert row["l18"] == pytest.approx(18, abs=tol) and row["l25"] == pytest.approx(25, abs=tol)
assert row["l25Shown"] == pytest.approx(row["l25"])
assert "곡선 길이를 바꿨습니다" in row["l25Status"]
def test_스냅_켬_MC_가_측점에(got) -> None:
assert got["snapOn"]["r60Mc"] == pytest.approx(120, abs=0.05) # 20 m 간격
assert got["snapOff"]["r60Mc"] != pytest.approx(120, abs=0.05)
def test_스냅_켬_R_바꾼_뒤_뒤쪽_곡선_MC(got) -> None:
"""408-1 — 고친 곡선 뒤 곡선도 맞춤 · 측점 위였던 곡선은 R 바꾼 뒤에도 측점 위."""
on = got["snapOn"]
def hit(mc: float) -> bool:
return abs(mc - round(mc / 20) * 20) <= 0.05
assert [hit(mc) for mc in on["r60Later"]] >= [hit(mc) for mc in on["r40Later"]]
assert all(hit(mc) for mc in on["r60Later"])
assert "함께 밀린 교점 " in on["r60Status"] and "함께 밀린" not in got["snapOff"]["r60Status"]
@pytest.mark.parametrize("snap", ["snapOff", "snapOn"])
def test_접선_자리_모자람_칸은_그린_값_상태줄_까닭(got, snap) -> None:
row = got[snap]
assert row["capR"] < 60 and row["capShown"] == pytest.approx(row["capR"])
want = f"반지름 60m → {round(row['capR'], 1)}m(앞뒤 직선이 짧아 접선 자리 모자람)"
assert want in row["capStatus"]
assert "곡선 길이 40m → " in row["capArcStatus"]
assert "반지름을 자동으로 되돌렸습니다" in row["autoStatus"] # 빈 값 = 자동 · 까닭 없음
def test_고정(got) -> None:
assert got["arcLocked"]["arc"] == pytest.approx(25) # 교각이 바뀌어도 길이 그대로
assert got["arcFree"]["arc"] != pytest.approx(25, abs=0.1)
assert got["radiusLocked"] == {"radius": pytest.approx(60), "lock": "radius"}
def test_편집기_줄_수_그대로() -> None:
edit = (ROOT / "B05_Profile" / "B05_Profile_UI_RouteEdit.ts").read_text(encoding="utf-8")
assert edit.count("\n") <= 695