"""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