# -*- coding: utf-8 -*- """노면공 확폭 구간(PLAN 87-3) — 구간 묶기 · `widening_off` 글 읽고 쓰기 · 안 맞는 값 무시. 규칙은 Node 헬퍼(`helper_87_widening.cjs`)가 `design_structure_widening.ts` 를 그대로 돌림. """ import json import os import subprocess import pytest HERE = os.path.dirname(os.path.abspath(__file__)) @pytest.fixture(scope="module") def out(): proc = subprocess.run( ["node", os.path.join(HERE, "helper_87_widening.cjs")], capture_output=True, text=True, encoding="utf-8", timeout=60, ) assert proc.returncode == 0, proc.stderr return json.loads(proc.stdout) def test_곡선_둘은_구간_둘_확폭은_구간_최대(out): assert out["runs"] == [ {"start_m": 20, "end_m": 60, "widening_m": 0.75}, {"start_m": 100, "end_m": 120, "widening_m": 0.6}, ] def test_범위_안_측점만_묶음(out): assert out["inner"] == [ {"start_m": 40, "end_m": 60, "widening_m": 0.75}, {"start_m": 100, "end_m": 100, "widening_m": 0.5}, ] assert out["none"] == [] def test_설계_없으면_곡선_확폭_바깥쪽만(out): assert out["fallback"] == 0.9 assert out["fallbackStraight"] == 0 def test_끈_구간_글_왕복(out): assert out["off"] == "20-60" assert out["parsed"] == [[20, 60], [100, 120]] # 틀린 조각은 버림 assert out["isOff"] == [True, False] assert out["toggledOff"] == "100-120" assert out["toggledBoth"] == "20-60,100-120" assert out["toggledOn"] == "" def test_안_맞는_끈_값은_무시_저장_때_빠짐(out): assert out["stale"] == "20-60" assert out["empty"] == "" def test_확폭_면적_사다리꼴_앞뒤_0_측점까지(out): # 0~20: (0+0.3)/2×20=3 · 20~40: 10.5 · 40~60: 11.5 · 60~80: 4 → 29 # 80~100: 5 · 100~120: 11 · 120~140: 6 → 22 assert [round(a, 6) for a in out["area"]] == [29.0, 22.0] def test_확폭_면적_노면공_범위로_자름(out): # 30 에서 자름: w(30)=0.525 → (0.525+0.75)/2×10=6.375 + 11.5 + 4 = 21.875 assert round(out["areaClipped"], 6) == 21.875 def test_한_측점_구간도_면적_자료_없으면_0(out): assert round(out["areaSingle"], 6) == 20.0 # (0+1)/2×20 × 2 assert out["areaMissing"] == 0