Files
Aislo/resources/tester/test_280_4_stations.py
T
eomsangdonandClaude Opus 5.5 20d0fd5e51 fix(483-1·2 B05 스냅): 일반측점을 MC 로 옮기지 않음 · MC 특별측점 더함 · 스냅 간격 1 m · 0.1 m 지움
- 서버 snap_curve_stations ↔ TS snapCurveStations · gridIndices 지움 — 스냅 켬 = 끔과 같은 측점(20 m 그대로 + 「No.N+10 (MC)」)
- 고르기 = 10 m · 측점 No. 둘 · load_station_snap_step = 10 만 · 옛 0.1 · 1 = 측점 No.
- 시험 = 새 test_280_4_stations(거울 다섯 경우) · 224_2 · 344_3 · 366_3 · 390_4 · 390_5 · 407 고쳐 씀

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 21:58:53 +09:00

125 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""PLAN 483-1(요구 280-4) — 스냅이 일반측점을 MC 로 옮기지 않음 · MC 특별측점 더함.
서버 `_station_layout`(`generate_sections`) ↔ TS `buildStations` 거울 — 분석 D 재현 1 다섯 경우
(BP–EP 200 m 직선 · 곡선 하나 · 측점 간격 20 m). 짝 = `helper_280_4_stations.cjs`.
"""
from __future__ import annotations
import json
import subprocess
import sys
import tempfile
from pathlib import Path
import numpy as np
import pytest
HERE = Path(__file__).resolve().parent
ROOT = HERE.parents[1]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from B05_Profile import B05_Profile_Engine_Sections_Core as core # noqa: E402
pytestmark = pytest.mark.skipif(
not (ROOT / "config" / "node_modules" / "typescript").is_dir(),
reason="프론트엔드 의존성 미설치",
)
LINE = [[0.0, 0.0], [200.0, 0.0]]
def _curve(bc: float, ec: float, radius: float = 30.0) -> list[dict]:
return [
{"start": [bc, 0.0], "apex": [(bc + ec) / 2, 3.0], "end": [ec, 0.0], "radius_m": radius}
]
CASES = {
"A_10m_긴호_MC50": {"curves": _curve(34.3, 65.7), "snap": True, "step": 10.0},
"B_10m_짧은호_MC50": {"curves": _curve(45.6, 54.4, 8.5), "snap": True, "step": 10.0},
"C_10m_MC60": {"curves": _curve(44.3, 75.7), "snap": True, "step": 10.0},
"D_측점No_MC47": {"curves": _curve(31.3, 62.7), "snap": True, "step": None},
"E_스냅끔_MC50": {"curves": _curve(34.3, 65.7), "snap": False, "step": None},
}
GRID = [float(v) for v in range(0, 201, 20)]
class _Flat:
def sample_xy(self, xy):
count = len(np.asarray(xy))
return np.zeros(count), np.ones(count, dtype=bool)
def _server(case: dict) -> list[dict]:
data = core.generate_sections(
[[x, y, 0.0] for x, y in LINE],
_Flat(),
core.SectionGenerationOptions(),
design_curves=case["curves"],
station_snap=case["snap"],
station_snap_step=case["step"],
)
return data["longitudinal"]["stations"]
@pytest.fixture(scope="module")
def ts() -> dict:
jobs = [{"line": LINE, **case} for case in CASES.values()]
with tempfile.TemporaryDirectory() as folder:
path = Path(folder) / "job.json"
path.write_text(json.dumps(jobs), encoding="utf-8")
proc = subprocess.run( # noqa: S603 — 고정 실행 파일
["node", str(HERE / "helper_280_4_stations.cjs"), str(path)],
capture_output=True,
text=True,
encoding="utf-8",
timeout=60,
)
assert proc.returncode == 0, proc.stderr
return dict(zip(CASES, json.loads(proc.stdout), strict=True))
_KIND = {"bp": "end", "ep": "end", "regular": "grid", "curve": "curve"}
EXPECT_CURVE = {
"A_10m_긴호_MC50": 50.0,
"B_10m_짧은호_MC50": 50.0,
"C_10m_MC60": None,
"D_측점No_MC47": 47.0,
"E_스냅끔_MC50": 50.0,
}
@pytest.mark.parametrize("name", list(CASES))
def test_일반측점_그대로_MC_특별측점(name, ts):
server = _server(CASES[name])
regular = [s["chainage_m"] for s in server if s["kind"] in ("bp", "regular", "ep")]
assert regular == GRID # 20 m 일반측점 하나도 안 사라짐
curves = [s for s in server if s["kind"] == "curve"]
mc = EXPECT_CURVE[name]
if mc is None: # N+0 = 일반측점 위 MC → 특별측점 없음
assert curves == []
else:
assert [s["chainage_m"] for s in curves] == [mc]
assert curves[0]["label"].endswith(" (MC)")
# 거울 — 누가거리 · 종류
ours = ts[name]
assert [s["m"] for s in ours] == pytest.approx([s["chainage_m"] for s in server], abs=1e-6)
assert [s["kind"] for s in ours] == [_KIND[s["kind"]] for s in server]
def test_A_열쇠(ts):
keys = {s["key"]: s["m"] for s in ts["A_10m_긴호_MC50"]}
assert keys["grid:2"] == 40.0 and keys["curve:50.00"] == 50.0
for s in ts["A_10m_긴호_MC50"]:
if s["kind"] == "grid":
assert s["key"] == f"grid:{round(s['m'] / 20)}"
def test_스냅_켬_끔_같은_목록():
on = _server(CASES["A_10m_긴호_MC50"])
off = _server(CASES["E_스냅끔_MC50"])
assert on == off