- 맞춤 함수 그대로(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
89 lines
3.6 KiB
Python
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
|