Files
Aislo/resources/tester/test_472_5d_adjust_owner.py
T

128 lines
4.7 KiB
Python

"""PLAN 472-5 5-D (요구 273) — B06 조정창 값 주인 = 세션 칸 하나 · 메모리 맵 걷음(N5).
못박는 것
- 조정창(반폭 · 흙막이 4축 · 유입 형식 · 연동 · 단 수 · 세월교)을 고친 뒤 ↶ 하고 다른 측점을 고쳐도 되돌린 값이
되살아나지 않음 — 옛 코드는 메모리 맵이 옛 값을 쥐고 다음 조작이 칸을 통째로 다시 써 ↶ 를 덮었음(옛 코드 실패).
- ↶ 뒤 조정창 읽기 · 캐시 설계 칸(상세 가게 얹기 뒤) = 조작 전 값(저장분은 그대로) · ↷ = 다시 그 값.
- 저장 묶음(횡단 patch 재료)도 세션 칸 그대로.
./venv/Scripts/python.exe -m pytest resources/tester/test_472_5d_adjust_owner.py -q
"""
from __future__ import annotations
import json
import shutil
import subprocess
from pathlib import Path
import pytest
HERE = Path(__file__).resolve().parent
ROOT = HERE.parents[1]
pytestmark = pytest.mark.skipif(
not (ROOT / "config" / "node_modules" / "vite").is_dir(),
reason="프론트엔드 의존성 미설치",
)
SAVED_OUTLET = {"x": 2, "d": None, "h": None, "m": None}
@pytest.fixture(scope="module")
def out(tmp_path_factory) -> dict:
work = tmp_path_factory.mktemp("s4725d")
subprocess.run( # noqa: S603 — 고정 실행 파일
[
"node",
str(ROOT / "config" / "node_modules" / "vite" / "bin" / "vite.js"),
"build",
"--configLoader",
"runner",
"--ssr",
"../resources/tester/helper_472_5d_adjust_entry.ts",
"--outDir",
str(work),
"--logLevel",
"error",
],
cwd=ROOT,
check=True,
capture_output=True,
timeout=300,
)
bundle = work / "bundle.mjs"
shutil.copy(work / "helper_472_5d_adjust_entry.js", bundle)
proc = subprocess.run( # noqa: S603
["node", str(HERE / "helper_472_5d_adjust.mjs"), str(bundle)],
cwd=ROOT,
capture_output=True,
text=True,
encoding="utf-8",
timeout=120,
)
assert proc.returncode == 0, proc.stderr
return json.loads(proc.stdout)
def test_조작_A_는_세션_칸에(out) -> None:
a = out["afterA"]
assert a["revetx"]["100.00:inlet"]["x"] == 3
assert a["crossw"] == {"100.00": 6}
assert a["inletstruct"] == {"100.00": "L"}
assert a["revetlink"]["detached"] == {"120.00": True}
assert a["extrawall"] == {"120.00": 2}
assert a["fordadjust"]["140.00"]["inlet"]["lateralM"] == 2
def test_되돌리면_칸이_비고_조정창도_조작_전(out) -> None:
assert out["afterUndo"] == {name: None for name in out["afterUndo"]}
r = out["readsUndo"]
assert r["inlet"]["x"] == 0
assert r["outlet"] == SAVED_OUTLET # 저장분 그대로
assert r["width100"] is None
assert r["struct100"] == "auto"
assert r["linked120"] is True
assert r["extra120"] == 0
assert r["ford140"] == 0
def test_되돌린_뒤_캐시_설계_칸도_조작_전(out) -> None:
"""옛 코드 = 조정창이 캐시(section.design)에 실은 값이 ↶ 뒤에도 남아 그림 · [저장] 바탕으로 나감."""
d100, d120, d140 = out["designsUndo"]
assert d100 == {"revet_adjust": {"outlet": SAVED_OUTLET}}
assert d120 == {}
assert d140 == {}
def test_되돌린_뒤_다른_조작이_되돌림을_안_덮음(out) -> None:
"""N5 — 옛 코드는 메모리 맵이 A 값을 쥐고 B 를 쓸 때 통째로 다시 씀(옛 코드 실패)."""
b = out["afterB"]
assert set(b["revetx"]) == {"100.00:outlet"}
assert b["revetx"]["100.00:outlet"]["x"] == 1
assert b["crossw"] == {"120.00": 8}
assert b["inletstruct"] == {"120.00": "I"}
assert b["revetlink"]["detached"] == {"140.00": True}
assert b["extrawall"] == {"140.00": 1}
assert set(b["fordadjust"]) == {"100.00"}
p = out["payloadB"]
assert set(p["revet"]) == {"100"} and set(p["revet"]["100"]) == {"outlet"}
assert set(p["link"]) == {"140"}
assert p["extra"] == {"140": {"outlet": 1}}
assert p["ford"] == [100]
def test_다시하기_뒤_값_같음(out) -> None:
assert out["afterUndo2"] == {name: None for name in out["afterUndo2"]}
assert out["afterRedo"] == out["afterB"]
d100, d120, d140 = out["designsRedo"]
assert d100["revet_adjust"] == {"outlet": {"x": 1, "d": None, "h": None, "m": None}}
assert "inlet_structure" not in d100
assert d120["inlet_structure"] == "I"
assert d140["revet_link_detached"] is True
assert d140["extra_wall_counts"] == {"outlet": 1, "basin": 0}
assert d100["ford_adjust"]["outlet"]["lateralM"] == 1
r = out["readsRedo"]
assert r["outlet"]["x"] == 1 and r["inlet"]["x"] == 0
assert r["width100"] is None and r["ford140"] == 0