95 lines
3.5 KiB
Python
95 lines
3.5 KiB
Python
"""PLAN 511-A (요구 320-4) — 묶음마다 서버 창구 답 = 브라우저 자리 TS 답(거울).
|
|
|
|
브라우저 쪽 = `helper_511_a_mirror.cjs` 가 그 자리 함수를 바로 부름 · 서버 쪽 = 늘 떠 있는 Node
|
|
(`run_calc_served` · 창구와 같은 본문 꼴 — `design_calc_server.ts` `areasRequest` · `bermRequest` ·
|
|
시험 길 args).
|
|
고정 자료 = golden_472 · 272 소단 사례 · 손 자료(공유 DB · 실제 마스터 안 씀).
|
|
|
|
./venv/Scripts/python.exe -m pytest resources/tester/test_511_a_calc_mirror.py -q
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
ROOT = HERE.parents[1]
|
|
if str(ROOT) not in sys.path:
|
|
sys.path.insert(0, str(ROOT))
|
|
if str(HERE) not in sys.path:
|
|
sys.path.insert(0, str(HERE))
|
|
|
|
from common_util import common_util_calc_runner as runner # noqa: E402
|
|
|
|
FIXTURE = HERE / "fixtures" / "golden_472"
|
|
|
|
pytestmark = pytest.mark.skipif(
|
|
shutil.which("node") is None or not (ROOT / "config" / "node_modules" / "vite").is_dir(),
|
|
reason="node · 프론트엔드 의존성 없음",
|
|
)
|
|
|
|
|
|
def _fixture(name: str):
|
|
return json.loads((FIXTURE / name).read_text(encoding="utf-8"))
|
|
|
|
|
|
def _browser(tmp_path: Path, calls: list[dict]) -> list:
|
|
job = tmp_path / "job.json"
|
|
job.write_text(json.dumps(calls, ensure_ascii=False), encoding="utf-8")
|
|
proc = subprocess.run( # noqa: S603 — 고정 실행 파일
|
|
["node", str(HERE / "helper_511_a_mirror.cjs"), str(job)],
|
|
cwd=ROOT,
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
timeout=120,
|
|
)
|
|
assert proc.returncode == 0, proc.stderr
|
|
return json.loads(proc.stdout)
|
|
|
|
|
|
def _served(run: list[str], inputs: dict) -> dict:
|
|
answer = runner.run_calc_served(run, inputs)
|
|
assert answer and "results" in answer, answer
|
|
return answer["results"]
|
|
|
|
|
|
def _trial(id_: str, args: list):
|
|
return _served([id_], {"args": {id_: args}})[id_]
|
|
|
|
|
|
# ── ③ 토량 · 구조물 셈(E1 · F7 · C4 · F8 = 브라우저 부름 없음) ───────────────────────
|
|
|
|
|
|
def test_quantity_F7_C4_E1_서버_브라우저_같음(tmp_path):
|
|
from test_272_berm_source import STRUCTURE_CASES
|
|
|
|
detail = _fixture("detail.json")
|
|
sections = detail["cross_sections"]
|
|
conv = _fixture("context.json")["earthwork_conversion"]
|
|
long_ = detail["longitudinal"]
|
|
calls = [
|
|
{"mod": "B06_Section/B06_Section_Structure_Layouts.ts", "fn": "structureAreaRows",
|
|
"args": [sections]},
|
|
{"mod": "common_util/common_util_mass_haul.ts", "fn": "computeMassHaulSeries",
|
|
"args": [long_, sections, conv, None, ["cross"]]},
|
|
] + [
|
|
{"mod": "common_util/common_util_berm_spans.ts", "fn": "bermSpansFromStructures",
|
|
"args": [case]}
|
|
for case in STRUCTURE_CASES
|
|
] # fmt: skip
|
|
browser = _browser(tmp_path, calls)
|
|
areas = _served(["structure.layouts"], {"detail": {"cross_sections": sections}})
|
|
assert areas["structure.layouts"]["areas"] == browser[0] and browser[0]
|
|
series = _trial("masshaul.series", [long_, sections, conv, None, ["cross"]])
|
|
assert series == browser[1] and series[0]["result"]["final_cumulative_m3"]
|
|
for index, case in enumerate(STRUCTURE_CASES):
|
|
got = _served(["cross.berm_spans"], {"berm": {"structures": case, "chainages": []}})
|
|
assert got["cross.berm_spans"]["spans"] == browser[2 + index], index
|