Files
Aislo/resources/tester/test_178_1_slope_wall_guard.py
T

106 lines
4.2 KiB
Python

"""178-1 사면안정 벽(흙막이 · 옹벽) 가드 한 벌 — 카드 · 서버 면적 · B07 · 3D.
흠: 카드는 「연동 관 벽이 이 측점에 실제로 설 때만」 독립 벽을 건너뛰는데, 서버 면적
(`computeStoredLayouts` → Node) · B07 은 링크만 있어도 건너뛰고 3D 는 관 측점만 봤다.
⇒ 관 링크는 있으나 관 벽이 안 서는 측점에서 카드엔 흙막이가 서고 서버 면적 · B07 엔 없음.
고침: `ownWallsDrawAt` 한 벌을 세 곳이 함께 씀. 서버 면적은 같은 TS 를 Node 로 돌리므로
번들을 새로 빌드해 그 결과로 판정한다.
"""
import copy
import json
import subprocess
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[2]
VITE = ROOT / "config" / "node_modules" / "vite" / "bin" / "vite.js"
FIXTURE = ROOT / "resources" / "tester" / "fixtures" / "b06_73_4_body_guard_sections.json"
SOIL_GUARD = {
"structure_id": "w1",
"type_id": "soil_guard",
"name": "흙막이",
"start_m": 150,
"end_m": 370,
"anchor_m": 260,
"form": "돌쌓기(찰)",
"height_m": 1.5,
}
@pytest.fixture(scope="module")
def bundle(tmp_path_factory) -> Path:
if not VITE.is_file():
pytest.skip("프론트엔드 의존성 미설치")
out = tmp_path_factory.mktemp("server_calc")
subprocess.run( # noqa: S603 — 고정 실행 파일
[
"node",
str(VITE),
"build",
"--configLoader",
"runner",
"--ssr",
"../B06_Section/B06_Section_Server_Calc_Node.ts",
"--outDir",
str(out),
"--logLevel",
"error",
],
cwd=str(ROOT),
check=True,
capture_output=True,
)
return out / "B06_Section_Server_Calc_Node.js"
def _areas(bundle: Path, sections: list, tmp_path: Path) -> dict[float, tuple]:
src, dst = tmp_path / "in.json", tmp_path / "out.json"
src.write_text(json.dumps({"detail": {"cross_sections": sections}}), encoding="utf-8")
subprocess.run(["node", str(bundle), str(src), str(dst)], check=True, cwd=str(ROOT)) # noqa: S603
rows = json.loads(dst.read_text(encoding="utf-8"))["areas"]
return {row["chainage_m"]: (row["cut_area_m2"], row["fill_area_m2"]) for row in rows}
def _sections() -> list:
return copy.deepcopy(json.loads(FIXTURE.read_text(encoding="utf-8"))["cross_sections"])
def test_링크만_있고_관_벽이_안_서면_흙막이_면적_행이_나온다(bundle, tmp_path):
"""173.087 관의 다단 구간값(20 m)이 160 · 180 을 덮어 링크는 서지만 관 벽(전 · 후 5 m)은 안 섬."""
sections = [s for s in _sections() if s["chainage_m"] < 300]
sections[1]["design"]["extra_spans"] = {"extra0": {"before_m": 20, "after_m": 20}}
for section in sections:
if not section.get("culvert"):
section["revetment"] = SOIL_GUARD
areas = _areas(bundle, sections, tmp_path)
assert 160 in areas and 180 in areas, f"흙막이가 선 측점 면적 행 없음: {sorted(areas)}"
# 표준 성토(160 = 1.45 · 180 = 5.32 ㎡)보다 벽이 사면을 끊어 줄어듦
assert areas[160][1] < 1.45 and areas[180][1] < 5.32
def test_관_벽이_서는_측점은_독립_벽을_안_그린다(bundle, tmp_path):
"""340 · 360 은 352.14 관 벽이 섬 — 흙막이를 얹어도 면적이 관 벽 그대로(겹쳐 그리지 않음)."""
plain = _areas(bundle, _sections(), tmp_path)
walled = _sections()
for section in walled:
if not section.get("culvert"):
section["revetment"] = SOIL_GUARD
areas = _areas(bundle, walled, tmp_path)
assert areas[340] == plain[340] and areas[360] == plain[360]
def test_카드_서버_3D_가_가드_한_벌을_쓴다():
files = {
"카드": ROOT / "B06_Section" / "B06_Section_UI_Cross_View.ts",
"서버 면적 · B07": ROOT / "B06_Section" / "B06_Section_Structure_Layouts.ts",
"3D": ROOT / "B05_Profile" / "B05_Profile_UI_Corridor_Structures.ts",
}
for where, path in files.items():
source = path.read_text(encoding="utf-8")
assert "ownWallsDrawAt(" in source, f"{where} 가 가드 한 벌을 안 씀"
assert "culvertWallsStandAt(" not in source, f"{where} 에 따로 가드가 남음"