- 박스 흙막이 높이 빈 칸 = 박스 높이 값(2 m 박스 → 2 m) · 윗면 = 본체 윗면 · 바닥 = 윗면 − 높이 · 세월교는 그대로 - x 원점(사면 경사길이 4 m 지점) 되돌림 — 손대지 않은 벽(x · d 빈 칸)만 성토사면 제일 위 · 손으로 x 를 넣은 독립 기슭막이 · 옹벽 · 관 보호공은 종전 자리 - 세월교 · 박스 흙막이 조정창 제목 「흙막이(유입 · 유출)」 · 박스 에이프런 툴팁 유입 · 유출 날개벽 이름 바로잡음 - 시험: test_79_guard_shape — 박스 높이 값 · 저장 x 있는 관 보호공 · 독립 기슭막이 = 종전 자리 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYJJRCfHfdCGNhmXTjQKV7
123 lines
5.3 KiB
Python
123 lines
5.3 KiB
Python
"""79 흙막이 · 세월교 · 박스암거 형상 — 화면 TS 를 그 자리에서 돌린 값(`helper_79_guard_shape.cjs`).
|
|
|
|
픽스처 = 73-4 와 같은 검증_sub7 상세 일부(세월교 173.09 · 박스 352.14 유입 · 유출 흙막이).
|
|
- 79-5 관 보호공 · 독립 기슭막이(옹벽) 기본 자리 = 성토사면 제일 위(d 0 · 관은 m 단위 맞춤만큼 아래)
|
|
- 79-6 구간 연동 측점 벽 = 연동 표시
|
|
- 79-7 흙막이 윗면 = 본체 윗면 · 높이 빈 칸 = 본체 끝 높이 · 세월교 ㄴ형 측벽 걷음 · 박스 수평 ·
|
|
박스 날개벽 끝 절 · 성토선 · 끝 절토 = 수평공간(컨테이너 칸) 뒤 절토 경사
|
|
"""
|
|
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
if str(ROOT) not in sys.path:
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
HELPER = Path(__file__).parent / "helper_79_guard_shape.cjs"
|
|
NODE_MODULES = ROOT / "config" / "node_modules"
|
|
|
|
pytestmark = pytest.mark.skipif(not NODE_MODULES.is_dir(), reason="프론트엔드 의존성 미설치")
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def shape() -> dict:
|
|
done = subprocess.run( # noqa: S603 — 고정 실행 파일
|
|
["node", str(HELPER)], cwd=str(ROOT), capture_output=True, text=True, encoding="utf-8"
|
|
)
|
|
assert done.returncode == 0, done.stderr
|
|
return json.loads(done.stdout)
|
|
|
|
|
|
def test_세월교_높이_빈칸은_본체_끝_높이_윗면은_본체_윗면(shape: dict) -> None:
|
|
walls = shape["fordAuto"]
|
|
assert {w["role"] for w in walls} == {"inlet", "outlet"}
|
|
for wall in walls:
|
|
assert wall["topGap"] == pytest.approx(0, abs=1e-3)
|
|
assert wall["bottomGap"] == pytest.approx(0, abs=1e-3)
|
|
assert wall["pureHeight"] == pytest.approx(wall["endHeight"], abs=1e-3)
|
|
|
|
|
|
def test_박스_높이_빈칸은_박스_높이_값_윗면은_본체_윗면(shape: dict) -> None:
|
|
# 2 m 박스 → 2 m(사용자 원문 숫자 · 79b) — 바닥 = 윗면 − 그 높이
|
|
walls = shape["boxAuto"]
|
|
assert {w["role"] for w in walls} == {"inlet", "outlet"}
|
|
for wall in walls:
|
|
assert wall["topGap"] == pytest.approx(0, abs=1e-3)
|
|
assert wall["pureHeight"] == pytest.approx(wall["autoHeight"], abs=1e-3)
|
|
assert wall["autoHeight"] < wall["endHeight"]
|
|
assert wall["bottomGap"] == pytest.approx(wall["endHeight"] - wall["autoHeight"], abs=1e-3)
|
|
|
|
|
|
def test_높이를_적으면_윗면은_그대로_바닥이_따라감(shape: dict) -> None:
|
|
for wall in shape["boxSet"]:
|
|
assert wall["topGap"] == pytest.approx(0, abs=1e-3)
|
|
assert wall["bottomGap"] == pytest.approx(wall["endHeight"] - wall["pureHeight"], abs=1e-3)
|
|
|
|
|
|
def test_세월교_흙막이_쪽_ㄴ형_측벽은_사라짐(shape: dict) -> None:
|
|
assert all(side["parts"] == 0 for side in shape["fordParts"])
|
|
one = {side["role"]: side["parts"] for side in shape["fordOneGuardParts"]}
|
|
assert one == {"inlet": 0, "outlet": 2}
|
|
|
|
|
|
def test_박스_본체는_늘_수평(shape: dict) -> None:
|
|
level = shape["boxLevel"]
|
|
assert level["left"] == pytest.approx(level["right"], abs=1e-6)
|
|
assert level["slope"] is None
|
|
|
|
|
|
def test_박스_날개벽_끝_절성토선(shape: dict) -> None:
|
|
for side in shape["boxWing"]:
|
|
assert side["cut"] + side["fill"] >= 1
|
|
|
|
|
|
def test_흙막이_끝_절토는_수평공간_뒤(shape: dict) -> None:
|
|
tails = [tail for group in shape["cutDefault"] for tail in group]
|
|
assert tails, "절토 끝선이 없음"
|
|
for tail in tails:
|
|
assert tail["points"] == 3
|
|
assert tail["flat"] == pytest.approx(0, abs=1e-6)
|
|
assert tail["berm"] == pytest.approx(1.0, abs=1e-3)
|
|
for tail in shape["cutBerm2"]:
|
|
assert tail["berm"] == pytest.approx(2.0, abs=1e-3)
|
|
|
|
|
|
def test_관_보호공_기본_자리는_제일_위(shape: dict) -> None:
|
|
pipe = shape["pipe"]
|
|
assert pipe is not None
|
|
assert pipe["d"]["inlet"] == pytest.approx(0, abs=1e-6)
|
|
# 유출은 관 m 단위 맞춤이 사면 아래로 민 만큼만 내려감(종전 기본 = 경사길이 4 m · d 3.07)
|
|
assert pipe["d"]["outlet"] < 1.0
|
|
inlet = next(w for w in pipe["walls"] if w["role"] == "inlet")
|
|
assert inlet["topBelowEdge"] == pytest.approx(0, abs=0.05)
|
|
assert float(pipe["lengthM"]).is_integer()
|
|
|
|
|
|
def test_저장_x_있는_관_보호공은_종전_자리_그대로(shape: dict) -> None:
|
|
# d 빈 칸 기본 = 경사길이 4 m 지점(3.07) — x 원점 그대로라 절대 자리 안 바뀜(79b)
|
|
stored = shape["pipeStoredX"]
|
|
assert stored["x"] == pytest.approx(1.0)
|
|
assert stored["d"] == pytest.approx(4.0 * 1.2 / (1 + 1.2**2) ** 0.5, abs=0.05)
|
|
|
|
|
|
def test_저장_x_있는_독립_기슭막이_옹벽은_종전_자리_그대로(shape: dict) -> None:
|
|
stored = shape["revetStoredX"]
|
|
assert stored["x"] == pytest.approx(1.0)
|
|
assert stored["d"] == pytest.approx(2.6) # 종전 기본 하강(3.07 / 1.2 → 0.1 눈금)
|
|
run = 4.0 * 1.2 / (1 + 1.2**2) ** 0.5
|
|
assert stored["shift"] == pytest.approx(run + 1.0, abs=1e-3)
|
|
assert stored["shiftXD"] == pytest.approx(run + 1.0, abs=1e-3)
|
|
|
|
|
|
def test_독립_기슭막이_옹벽_기본_자리는_제일_위(shape: dict) -> None:
|
|
revet = shape["revet"]
|
|
assert revet["d"] == 0
|
|
assert revet["topBelowEdge"] == pytest.approx(0, abs=1e-3)
|
|
assert revet["linked"] is False
|
|
assert shape["revetLinked"] is True
|