Files
Aislo/resources/tester/test_90_chute_band.py
T

60 lines
2.0 KiB
Python

"""90-2 도수로 · 돌붙임 띠 — 윗면 = 유출 성토사면 선 · 사면 안쪽(아래)으로 두께만큼 · 안에 돌.
화면 TS(`appendChuteBand`)를 그 자리에서 돌린 값(`helper_90_chute_band.cjs`).
"""
import json
import math
import subprocess
from pathlib import Path
import pytest
HERE = Path(__file__).parent
ROOT = HERE.parents[1]
pytestmark = pytest.mark.skipif(
not (ROOT / "config" / "node_modules").is_dir(), reason="프론트엔드 의존성 미설치"
)
@pytest.fixture(scope="module")
def out() -> dict:
done = subprocess.run( # noqa: S603 — 고정 실행 파일
["node", str(HERE / "helper_90_chute_band.cjs")],
capture_output=True,
text=True,
encoding="utf-8",
)
assert done.returncode == 0, done.stderr
return json.loads(done.stdout)
def _distance(p: dict, a: dict, b: dict) -> float:
dx, dz = b["offset"] - a["offset"], b["elevation"] - a["elevation"]
cross = (p["offset"] - a["offset"]) * dz - (p["elevation"] - a["elevation"]) * dx
return abs(cross) / math.hypot(dx, dz)
@pytest.mark.parametrize("case", ["left", "right"])
def test_띠_두께는_사면에서_직각으로_0_30m_아래(out: dict, case: str) -> None:
points = out[case]["points"]
n = len(points) // 2
top, bottom = points[:n], points[n:][::-1]
for i, low in enumerate(bottom):
# 꼭짓점마다 붙은 변(앞 · 뒤)까지 직각 거리 = 두께
for j in {max(i - 1, 0), min(i, n - 2)}:
assert _distance(low, top[j], top[j + 1]) == pytest.approx(0.3, abs=1e-6)
assert low["elevation"] < top[i]["elevation"] # 사면 안쪽 = 아래
def test_안에_돌_윗면은_사면선(out: dict) -> None:
for case in out.values():
assert case["stones"] >= 2 and case["clipped"]
assert "돌붙임" in case["title"] and "0.30m" in case["title"]
assert out["left"]["points"][:4] == [
{"offset": 5, "elevation": 10},
{"offset": 7.4, "elevation": 8},
{"offset": 8.4, "elevation": 8},
{"offset": 10.8, "elevation": 6},
]