- 유입 · 유출 구조 「흙막이」면 배관 흙막이와 같은 세트(관 숨김 · body)를 같은 측점 culvert 자리에 함께 얹음(파이썬 _guard_set ↔ TS guardSet 짝 · 거울 시험) - 자동 자리 = 벽 전면이 관(세월교) · 본체(박스) 끝 · 좌우 x 는 그 자리 기준(본체를 늘리면 벽도 따라감) · 상하 d 는 배관과 같음 - 연동 옆 측점 · 3D 연동 해제 자리는 본체 기준 x 를 절대값으로 넘겨 받음 · 3D 만료 해시에 흙막이 값 포함 - 설계선 트림 = 벽 선 쪽은 흙막이 · 안 선 쪽은 본체 · 벽 선 쪽 본체 성토선은 걷음(두 줄 방지) · 관 연장은 안 실음 - 좌측 폼 → 캐시: 세트 다시 짓기 · 높이 · 형태 · 추가 흙막이 상자 수 = 유출 다단 수 - [연동][경사] 회색 풀림(옆 측점에 벽이 서면 연동 · 구간 있으면 경사) — 배관과 같은 규칙 - 시험: test_73_4_body_guard(벽 전면 = 본체 끝 · 박스 +1 m 따라감 · 연동 옆 측점 벽 · 서버 Node 면적 = 화면) · 거울 시험 흙막이 칸 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYJJRCfHfdCGNhmXTjQKV7
83 lines
3.7 KiB
Python
83 lines
3.7 KiB
Python
"""73-4 세월교 · 박스 흙막이 — 관보호공 흙막이와 같은 벽 · 같은 자리 규칙(관 · 본체 끝).
|
|
|
|
화면 TS 를 그 자리에서 돌린 값(`helper_73_4_body_guard.cjs`)과 서버 Node 번들(면적)을 대조함.
|
|
픽스처 = 검증_sub7 상세 일부(세월교 173.09 유입 · 유출 흙막이 · 박스 352.14 유입 · 유출 흙막이 전후 15 · 10 m).
|
|
"""
|
|
|
|
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_73_4_body_guard.cjs"
|
|
FIXTURE = Path(__file__).parent / "fixtures" / "b06_73_4_body_guard_sections.json"
|
|
NODE_MODULES = ROOT / "config" / "node_modules"
|
|
|
|
pytestmark = pytest.mark.skipif(not NODE_MODULES.is_dir(), reason="프론트엔드 의존성 미설치")
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def screen() -> 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_박스_벽_전면이_본체_끝(screen: dict) -> None:
|
|
walls = screen["box"]["walls"]
|
|
assert {w["role"] for w in walls} == {"inlet", "outlet"}
|
|
for wall in walls:
|
|
assert wall["dOffset"] == pytest.approx(0, abs=1e-3)
|
|
assert wall["dElevation"] == pytest.approx(0, abs=1e-3)
|
|
# 형태 = 폼 값 그대로(유입 찰 · 유출 콘크리트)
|
|
assert {w["role"]: w["form"] for w in walls} == {"inlet": "돌쌓기(찰)", "outlet": "콘크리트"}
|
|
# 자동 자리 = 본체 기준 0 — 되받아 저장해도 본체를 따라감
|
|
assert screen["box"]["applied"] == {"inlet": 0, "outlet": 0}
|
|
|
|
|
|
def test_박스를_늘리면_벽도_m_단위로_따라감(screen: dict) -> None:
|
|
before = {w["role"]: w["front"] for w in screen["box"]["walls"]}
|
|
for wall in screen["boxMoved"]:
|
|
assert wall["dOffset"] == pytest.approx(0, abs=1e-3)
|
|
assert abs(wall["front"] - before[wall["role"]]) == pytest.approx(1.0, abs=1e-3)
|
|
|
|
|
|
def test_세월교_벽_전면이_관_끝(screen: dict) -> None:
|
|
walls = {w["role"]: w for w in screen["ford"]["walls"]}
|
|
assert walls["outlet"]["dOffset"] == pytest.approx(0, abs=1e-3)
|
|
assert walls["outlet"]["dElevation"] == pytest.approx(0, abs=1e-3)
|
|
# 유입 2.5 m 벽은 관 끝 자리에선 노면 위로 솟음 — 배관 벽과 같이 상단이 노견에서 멈춰 내려앉음
|
|
assert walls["inlet"]["dElevation"] <= 0
|
|
|
|
|
|
def test_연동_옆_측점에도_벽이_섬(screen: dict) -> None:
|
|
assert [row["walls"] for row in screen["linked"]] == [2, 2]
|
|
|
|
|
|
def test_설계선_트림은_흙막이_쪽(screen: dict) -> None:
|
|
assert screen["box"]["trimSame"] and screen["ford"]["trimSame"]
|
|
|
|
|
|
def test_서버_면적이_화면과_같음(screen: dict) -> None:
|
|
from B06_Section.B06_Section_Server_Calc_Prebuild import _NPM_SCRIPT, BUNDLE
|
|
from common_util.common_util_node_bundle import run_bundle_json
|
|
|
|
sections = json.loads(FIXTURE.read_text(encoding="utf-8"))["cross_sections"]
|
|
output = run_bundle_json(BUNDLE, _NPM_SCRIPT, {"detail": {"cross_sections": sections}})
|
|
assert output, "서버 Node 번들 실행 실패"
|
|
server = {round(r["chainage_m"], 2): r for r in output["areas"]}
|
|
for row in screen["areas"]:
|
|
mine = server[round(row["chainage_m"], 2)]
|
|
for key in ("cut_area_m2", "fill_area_m2"):
|
|
assert mine[key] == pytest.approx(row[key], abs=1e-4), (row["chainage_m"], key)
|
|
# 세월교 · 박스 흙막이 세트는 관이 아님 — 관 연장 안 실음
|
|
assert all("pipe_length_m" not in r for r in screen["areas"])
|