Files
Aislo/resources/tester/test_432_mc_on_station.py
T
eomsangdonandClaude Opus 5.5 7e0580ffd1 fix(노선 편집): MC 를 일반측점 위에 두면 그 뒤 스냅대로 — 「위」 판정 폭 = 측점 목록 「(MC)」 규칙 · 밀어내는 걸음 막음 (PLAN 576-1 · 요구 432)
- StationFit: 일반측점(측점 간격 배수) 「위」 = curveStations 반올림 폭(mcScale 공유 · 정수 m ±0.5 m) · 폭 안이면 정확히 맞춰 보고 못 맞춰도 「위」 · 10 m N+10 · 간격 격자는 옛 0.05 m 그대로
- offStationCount · offStationMcs 에 측점 간격 인자 · 편집기 · 곡선 띠가 넘김(1 m · 10 m 스냅 동작 전후 같음)
- pushedOff — R · 곡선 길이 입력 등 applyEdit 걸음이 측점 위 곡선을 밖으로 밀면 되돌림(꺾임점 · 곡선 켬 같은 걸음만)
- 시험: test_432_mc_on_station 새로 · helper_366_3 가 편집기처럼 측점 간격을 넘김(옛 helper 는 간격=측점 간격 가정) · test_390_5 배선 문구 offStation 한 곳으로 바뀜
- build:design-calc 다시 지음

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 22:59:17 +09:00

76 lines
3.1 KiB
Python

"""432 MC 를 일반측점 위에 두면 그 뒤 스냅대로.
「위」 판정 폭 = 측점 목록 「(MC)」 규칙(`curveStations` 반올림 · 정수 m = ±0.5 m) ·
폭 안이면 정확히 맞춰 보고 못 맞춰도 「위」 · 그 곡선을 폭 밖으로 미는 걸음(끌기 · R 입력)은
`pushedOff` 로 막음 · 측점 밖 정수 m 자리(1 m 스냅)는 옛 판정 그대로.
TS 셈은 `helper_432_mc_on_station.cjs`(Node · `StationFit` 그대로).
./venv/Scripts/python.exe -m pytest resources/tester/test_432_mc_on_station.py -q
"""
import json
import subprocess
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[2]
HELPER = Path(__file__).with_name("helper_432_mc_on_station.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)
def test_폭_안은_위_폭_밖은_측점_밖(got) -> None:
station = got["station"]
assert got["fittedOff"] == 0
assert got["inside"]["mc"] == pytest.approx(station + 0.3, abs=1e-6)
assert got["inside"]["off"] == 0
assert got["outside"]["mc"] == pytest.approx(station + 0.7, abs=1e-6)
assert got["outside"]["off"] == 1
def test_못_맞춰도_위_맞출_수_있으면_정확히(got) -> None:
station = got["station"]
assert got["lockInFit"]["off"] == 0 # 고정 IP · 그 자리 그대로 「위」
assert got["lockInFit"]["mc"] == pytest.approx(station + 0.3, abs=1e-3)
assert got["freeFit"]["off"] == 0 # 같은 측점에 정확히(다른 측점으로 안 옮김)
assert abs(got["freeFit"]["mc"] - station) <= 0.05
def test_폭_밖으로_미는_걸음_막음(got) -> None:
station = got["station"]
for case in ("drag", "radius"):
assert abs(got[case]["mc"] - station) > 0.5 and got[case]["pushed"] is True
for case in ("small", "radiusIn"):
assert abs(got[case]["mc"] - station) < 0.5 and got[case]["pushed"] is False
assert abs(got["freeRadius"]["mc"] - station) <= 0.05 and got["freeRadius"]["pushed"] is False
def test_1m_스냅_측점_밖은_옛_판정(got) -> None:
one = got["oneStep"]
assert one["insideOff"] == 0 # 일반측점 + 0.3 = 「(MC)」 폭
assert one["oddOff"][0] == pytest.approx(one["oddMc"], abs=1e-6) # 정수 m + 0.3 = 측점 밖
def test_편집기_배선() -> None:
edit = (ROOT / "B05_Profile" / "B05_Profile_UI_RouteEdit.ts").read_text(encoding="utf-8")
apply_edit = edit[edit.index("function applyEdit(") :]
apply_edit = apply_edit[: apply_edit.index("writeRouteLocks(")]
assert (
"stationSnap && fitting && before && fit.pushedOff(before, snapshotNow(), fitLimits())"
in apply_edit
)
assert "fit.offStationCount(plannedLine, curveInfo, snap(), stationIntervalM)" in edit
bar = (ROOT / "B05_Profile" / "B05_Profile_UI_RouteEdit_CurveBar.ts").read_text(
encoding="utf-8"
)
assert "offStationMcs(line, curveInfo, snap.stepM, snap.stationM)" in bar