Files
Aislo/resources/tester/test_b05_curve_radius_floor.py
T
eomsangdonandClaude Opus 5 1fafe2548c fix(b05): 곡선 길이(L) 하한도 지키게 — 내각 155° 이상은 예외
R 하한만 막고 L 하한은 칸 입력에서만 막던 것을 고침. L = R·Δ 라 한 자리의 하한을
반지름 하나로 모아 봄(`radiusFloorM` = max(R 하한, L 하한/Δ)) — 값 끌어올리기·
모자란 양 판정·칸 막기가 모두 이 값을 씀.

내각 155° 이상은 별표2 Ⅰ.2.다.(1) 상 곡선을 안 둬도 되는 자리라 L 하한을 안 걺 —
걸면 교각이 0 에 가까워 R 이 수십 배로 부풀어 안 고친 구간이 휨. 그 자리는 곡선
패널에 「155° 이상 — 곡선 생략 가능」으로 적어 냄.

`deflectionRad` 를 화면 파일(`_Label`)에서 셈 파일(`_Edits`)로 옮김 — 순수 함수가
DOM 파일에 얹혀 있어 시험이 화면째 들여와야 했음(부르던 자리는 재수출로 지킴).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DJffo4VwgTumVUM3kdbJzd
2026-09-12 21:48:39 +09:00

77 lines
3.2 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.
# -*- coding: utf-8 -*-
"""계획노선 편집의 **곡선 하한(R·L)** 회귀검증 — 2026-09-12.
사용자 확정: 「반경과 길이가 트레이드오프기는 하지만 **둘 다 지켜야** 한다」.
L = R·Δ 라 한 자리의 하한은 반지름 하나로 모이고, 그 값을 `radiusFloorM` 이 낸다.
⚠ 예외 하나 — **내각 155° 이상은 곡선을 설치하지 않을 수 있다**(별표2 .2.다.(1)).
거기서 L 을 채우라고 하면 교각이 0 에 가까워 R 이 수십 배로 부풀고, 아무것도 안 고쳤는데
노선이 휜다(실측: 내각 174.8° 자리가 R 12m → 55m). 그래서 그 자리는 R 하한만 본다.
Node 헬퍼(`helper_b05_curve_radius_floor.cjs`)가 TS 를 그 자리에서 트랜스파일해 돌리고,
여기서 값을 판정한다.
"""
import json
import os
import subprocess
import pytest
HERE = os.path.dirname(os.path.abspath(__file__))
@pytest.fixture(scope="module")
def results():
proc = subprocess.run(
["node", os.path.join(HERE, "helper_b05_curve_radius_floor.cjs")],
capture_output=True,
text=True,
timeout=60,
)
assert proc.returncode == 0, proc.stderr
return json.loads(proc.stdout)
def test_R_하한이_이기는_자리는_R_하한_그대로(results):
"""내각 140° 면 R 12m 만 지켜도 L 이 8.4m 라 L 하한(5m)이 안 건다."""
assert results["floors"]["bend140"] == pytest.approx(12.0)
def test_L_하한이_이기면_R_을_끌어올린다(results):
"""내각 150°(교각 30°)에 L 하한 20m 면 R 은 38.2m 이어야 한다 — 여기가 「둘 다」의 핵심."""
assert results["floors"]["bend150LongArc"] == pytest.approx(20 / (30 * 3.141592653589793 / 180))
assert results["floors"]["bend150LongArc"] > 12.0
def test_내각_155도_이상은_L_하한을_안_건다(results):
"""곡선 생략이 되는 자리다 — 걸었다면 R 이 28.6m 로 부풀어 노선이 조용히 휜다."""
assert results["floors"]["bend170"] == pytest.approx(12.0)
assert results["floors"]["bend170NoExempt"] > 28.0 # 예외가 없을 때의 값(참고)
assert results["floors"]["bend155"] == pytest.approx(12.0)
def test_155도_바로_아래는_L_하한을_건다(results):
"""경계는 「155° 이상」이라 154° 는 지켜야 하는 쪽이다."""
assert results["floors"]["bend154"] > 12.0
def test_내각을_모르면_R_하한만_본다(results):
assert results["floors"]["unknown"] == pytest.approx(12.0)
def test_지정한_반지름만_끌어올린다(results):
"""비워 둔(자동) 자리는 안 건드린다 — 건드리면 안 고쳤는데 「R 지정」이 늘어난다."""
applied = results["applied"]
assert applied["specified"] == pytest.approx(20 / (30 * 3.141592653589793 / 180))
assert applied["auto"] is None
assert applied["curveOff"] == 12 # 곡선을 지운 자리는 그대로
def test_모자란_양도_R과_L을_함께_잰다(results):
"""내각 150°(하한 38.2m)에서 R 12m 는 26.2m 모자라고, 170° 는 곡선 생략 자리라 0 이다."""
short = results["shortfalls"]
assert short[0] == pytest.approx(20 / (30 * 3.141592653589793 / 180) - 12)
assert short[1] == 0
assert short[2] == 0 # R 40m 는 하한을 넘겼다