- 사진첩: 「{}」 · 「null」 · 「""」 = 칸 없음 — 빈 맵 쓰기가 걸음이 되어 ↷ 를 버리던 흠(R4) · 「[]」(관 · 구조물 모두 지움)은 값으로 둠
- 세션 맵 · 연동 플래그: 빈 맵 persist = 칸 지움(갈아끼움 이동이 「{}」 여섯 칸을 만들지 않음)
- 종단도: 본문 0 크기(판 접힘)에도 낡음 예약 · 유토 총괄값 · 배분 선반입 · 측점 자료를 셈 · 그리기만 건너뜀 — 떼어 낸 유토 판은 그림
- 배지: 소수 한 자리 고정(−17,570.0㎥)
- 시험: test_272_history_empty_cells · test_272_hidden_summary(옛 코드 7 실패)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
105 lines
3.5 KiB
Python
105 lines
3.5 KiB
Python
"""272 · 468 (C1) 되돌리기 빈 칸 — 「{}」 · 「null」 · 「""」 = 칸 없음 · 세션 맵 빈 쓰기 = 칸 지움.
|
|
|
|
R4 — 교점 ↓ → ↶ → B06(누름 뒤 첫 마운트가 빈 맵 여섯 「{}」를 씀) → ↶ 켜짐 · ↷ 사라짐 → 이제 ↶ 꺼짐 · ↷ 남음.
|
|
「[]」 는 목록 초안(관 · 구조물 모두 지움 = 저장분과 다름)이라 걸음 그대로.
|
|
짝: `helper_272_value_hold.mjs`(vite ssr 로 묶은 진짜 모듈 · `helper_272_entry.ts`).
|
|
|
|
./venv/Scripts/python.exe -m pytest resources/tester/test_272_history_empty_cells.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="프론트엔드 의존성 미설치",
|
|
)
|
|
|
|
|
|
def run_helper(tmp_path_factory: pytest.TempPathFactory) -> dict:
|
|
work = tmp_path_factory.mktemp("b272")
|
|
build = subprocess.run(
|
|
[
|
|
"node",
|
|
str(ROOT / "config" / "node_modules" / "vite" / "bin" / "vite.js"),
|
|
"build",
|
|
"--configLoader",
|
|
"runner",
|
|
"--ssr",
|
|
"../resources/tester/helper_272_entry.ts",
|
|
"--outDir",
|
|
str(work),
|
|
"--logLevel",
|
|
"error",
|
|
],
|
|
cwd=ROOT,
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
timeout=300,
|
|
)
|
|
assert build.returncode == 0, build.stderr
|
|
bundle = work / "bundle.mjs"
|
|
shutil.copy(work / "helper_272_entry.js", bundle)
|
|
proc = subprocess.run(
|
|
["node", str(HERE / "helper_272_value_hold.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)
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def out(tmp_path_factory):
|
|
return run_helper(tmp_path_factory)
|
|
|
|
|
|
def test_되돌린_뒤_빈_칸이_생겨도_다시하기_남음(out):
|
|
h1 = out["h1"]
|
|
assert h1["edited"] is True
|
|
assert h1["undone"] == {"undo": False, "redo": True, "grade": None}
|
|
# 빈 맵 여섯 「{}」 · 「null」 · 「""」 = 걸음 아님
|
|
assert h1["after"] == {"undo": False, "redo": True}
|
|
|
|
|
|
def test_사용자_조작은_한_걸음_그대로(out):
|
|
h1 = out["h1"]
|
|
assert h1["redone"] is True
|
|
assert h1["redoGrade"] == json.dumps({"station_offsets": {"100": 1}}, separators=(",", ":"))
|
|
assert h1["final"] == {"undo": True, "redo": False}
|
|
|
|
|
|
def test_빈_목록_초안은_걸음(out):
|
|
# 관 모두 지움(「[]」) ≠ 칸 없음(저장분 관) — 되돌리기 · 다시하기 그대로
|
|
assert out["h2"] == {"step": True, "undonePipes": None, "redonePipes": "[]"}
|
|
|
|
|
|
def test_빈_칸_걸음으로_되돌리면_빈_칸(out):
|
|
h3 = out["h3"]
|
|
assert h3["step"] is True
|
|
assert h3["crossw"] in (None, "{}") # 빈 칸 = 칸 없음(읽는 쪽은 빈 맵)
|
|
assert h3["revetx"] == json.dumps({"100.00:inlet": {"x": 1}}, separators=(",", ":"))
|
|
|
|
|
|
def test_세션_맵_빈_쓰기는_칸_지움(out):
|
|
h4 = out["h4"]
|
|
assert h4["emptyWrite"] is None
|
|
assert h4["filledWrite"] == '{"100.00":6}'
|
|
assert h4["clearedWrite"] is None
|
|
# 빈 맵 이동은 칸을 안 만듦 · 값 있는 맵은 새 자리로 옮겨 씀
|
|
assert h4["moved"] == [None] * 6
|
|
assert h4["movedFilled"] == '{"120.00":2}'
|