Files
Aislo/resources/tester/test_124_b08_surcharge_panel.py
T

132 lines
5.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""124-1 B08 좌측 패널 할증 모래 · 자갈 · 시멘트 — 기본 12 · 5 · 3 · 패널 값 = 총괄 세 줄 · 저장 · 거울.
정본 = `project_settings.json › quantity › material_surcharge_pct`(받은 칸만 · 기본은 읽을 때 채움) ·
총괄자재수량집계표 그 세 줄은 패널 값만 씀(표 사용자 값 무시 · 표에서 안 고침).
견본 = 121 시험의 2공구 꼴 구조물 집계표 계.
"""
import asyncio
import json
import subprocess
from pathlib import Path
import pytest
from pydantic import ValidationError
from B08_Quantity import B08_Quantity_Router_Material as material_router
from B08_Quantity import B08_Quantity_Router_Options as options
from B08_Quantity.B08_Quantity_Material_Calc import PANEL_SURCHARGE, compute
from common_util.common_util_project_settings import settings_path
from M02_MasterTemplete import M02_Template_Layers as layers
from test_121_b08_material_sheets import EXCEL_MIX, IMPORTS, SUMMARY, _over
ROOT = Path(__file__).resolve().parents[2]
CALC_TS = ROOT / "B08_Quantity" / "B08_Quantity_Material_Calc.ts"
def _ts(summary, overrides, panel):
body = (
f"\nconst s = {json.dumps(summary, ensure_ascii=False)};"
f"\nconst o = {json.dumps(overrides, ensure_ascii=False)};"
f"\nconst p = {json.dumps(panel, ensure_ascii=False)};"
"\nconsole.log(JSON.stringify({sheets: computeMaterialSheets(s, o, p),"
" defaults: PANEL_SURCHARGE, filled: panelSurcharge(p)}));"
)
script = IMPORTS.sub("", CALC_TS.read_text(encoding="utf-8")) + body
result = subprocess.run(
["node", "--experimental-strip-types", "--no-warnings",
"--input-type=module-typescript", "-e", script],
capture_output=True, text=True, encoding="utf-8", timeout=60,
) # fmt: skip
assert result.returncode == 0, result.stderr
return json.loads(result.stdout)
def _rows(sheets):
return {row["key"]: row for row in sheets["material"]["rows"]}
@pytest.fixture
def root(tmp_path, monkeypatch) -> Path:
system = tmp_path / "master"
(system / "table").mkdir(parents=True)
(system / "table/구조물집계표.json").write_text(
json.dumps({"열": [], "변수": {"파형강관_1본_m": 8}}), encoding="utf-8"
)
monkeypatch.setattr(layers, "SYSTEM_ROOT", system)
project = tmp_path / "project"
project.mkdir()
return project
def test_기본_12_5_3_파일에_안_씀(root):
assert PANEL_SURCHARGE == {"sand": 12, "gravel": 5, "cement": 3}
rows = _rows(compute(SUMMARY, _over(mix=EXCEL_MIX)))
assert [rows[k]["surcharge"] for k in ("sand", "gravel", "cement")] == [12, 5, 3]
# 올림(14.5886 × 1.12) · 올림(18.0245 × 1.05) · 올림(238.73525 × 1.03)
assert [rows[k]["amount"] for k in ("sand", "gravel", "cement")] == [17, 19, 246]
assert [k for k, row in rows.items() if row["panel"]] == ["sand", "gravel", "cement"]
assert options.read_options(root)["material_surcharge_pct"] == PANEL_SURCHARGE
assert not settings_path(root).exists()
def test_패널_값이_총괄_세_줄을_바로_바꿈_표_값은_무시():
over = _over(mix=EXCEL_MIX, surcharge={"sand": 50, "sod": 20})
panel = {"sand": 6, "gravel": 4, "cement": 2} # 실무 엑셀 값
out = _ts(SUMMARY, over, panel)
rows = _rows(out["sheets"])
assert [rows[k]["amount"] for k in ("sand", "gravel", "cement")] == [
16,
19,
244,
] # 엑셀 G4 · G5 · G18
assert rows["sand"]["surcharge"] == 6 # 표 사용자 값 50 은 무시
assert rows["sod"]["surcharge"] == 20 # 나머지 줄은 표 값 그대로
assert out["sheets"] == compute(SUMMARY, over, panel)
def test_거울_빈칸_깨진_값은_기본():
for panel in (None, {}, {"gravel": 0}, {"sand": "x", "cement": 7.5}):
out = _ts(SUMMARY, _over(), panel)
assert out["defaults"] == PANEL_SURCHARGE
assert out["sheets"] == compute(SUMMARY, _over(), panel), panel
assert _rows(compute(SUMMARY, _over(), {"gravel": 0}))["gravel"]["surcharge"] == 0
def test_저장_뒤_남고_받은_칸만_씀(root, monkeypatch):
out = options.save_options(root, options.OptionsSave(material_surcharge_pct={"sand": 8}))
assert out["material_surcharge_pct"] == {"sand": 8, "gravel": 5, "cement": 3}
options.save_options(root, options.OptionsSave(material_surcharge_pct={"cement": 2.5}))
stored = json.loads(settings_path(root).read_text(encoding="utf-8"))
assert stored["quantity"]["material_surcharge_pct"] == {"sand": 8, "cement": 2.5}
# 다른 옵션 저장은 할증을 안 건드림
options.save_options(root, options.OptionsSave(soft_rock_pct=70))
assert options.read_options(root)["material_surcharge_pct"]["sand"] == 8
async def summary(_project_id):
return {**SUMMARY, "rows": [], "notes": []}
async def project_root(_project_id):
return root
monkeypatch.setattr(material_router, "structure_summary", summary)
monkeypatch.setattr(material_router, "_project_root", project_root)
got = asyncio.run(material_router.material_sheets("p"))
assert got["surcharge_pct"] == {"sand": 8, "gravel": 5, "cement": 2.5}
assert _rows(got["sheets"])["sand"]["surcharge"] == 8
def test_범위_밖_모르는_칸은_거절():
for bad in ({"sand": 120}, {"sand": -1}, {"rebar_d13": 3}):
with pytest.raises(ValidationError):
options.OptionsSave(material_surcharge_pct=bad)
def test_화면_연결():
ui = (ROOT / "B08_Quantity/B08_Quantity_UI_Material.ts").read_text(encoding="utf-8")
assert "liveSurcharge(projectId, payload.surcharge_pct)" in ui
assert "onOptionsChange(host," in ui
assert 'key === "surcharge" && !rows[i].panel' in ui and "할증 = 좌측 패널" in ui
panel = (ROOT / "B08_Quantity/B08_Quantity_UI_Options.ts").read_text(encoding="utf-8")
assert "put({ material_surcharge_pct:" in panel and "body.material_surcharge_pct" in panel