- Cross_Refresh refreshLocally — 세션 고름(단추 · 노견 확장 · 소단 깊이 · 암 경계 · 암 경사) ?? 저장 정본(savedDesigns) · 정본에 없는 측점만 메모리 설계 · 소단 깊이 · 소단 제원은 이번 원천 그대로(↶ 뒤 앞 값이 안 남음) - Design_Sync handleDesignChange — target.design 덮기 셋 뺌(세션만 · 카드는 다시 셈 알림이 그림) - 새 시험 test_272_choice_undo(옛 코드 = 넷 다 ↶ 뒤 앞 고름에 머묾) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
112 lines
3.6 KiB
Python
112 lines
3.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""467 덧 (요구 272) — 횡단 고름을 되돌리면(↶) 다시 셈이 정본 값으로 돌아옴.
|
|
|
|
못박는 것
|
|
- 카드 단추(지반 · 단면 갈래 · 측구) · 노견 확장 · 소단 깊이 · 암 경계를 세션에 쓰고 다시 셈 → 세션 칸 지움(↶) →
|
|
설계 = 고르기 전(정본으로 셈) 설계와 글자까지 같음 · 다시 씀(↷) = 고른 값과 같음.
|
|
- 다시 셈 입력 물러섬 = 저장 정본 설계(메모리 설계에 남은 앞 고름 · 결과 아님).
|
|
- 고름 단추가 메모리 상세 설계를 덮지 않음(`handleDesignChange`).
|
|
|
|
Node 헬퍼 `helper_272_choice_undo.mjs` 가 vite ssr 로 묶은 진짜 모듈을 부름.
|
|
"""
|
|
|
|
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))
|
|
|
|
from config.config_system import ( # noqa: E402
|
|
STANDARD_CROSS_SECTION,
|
|
STANDARD_ROCK_BOUNDARY_DEFAULT_OFFSET_M,
|
|
)
|
|
|
|
GROUND = [
|
|
{"offset_m": o / 2, "elevation_m": round(100.0 + 0.35 * o / 2, 4), "valid": True}
|
|
for o in range(-24, 25)
|
|
]
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def out(tmp_path_factory):
|
|
work = tmp_path_factory.mktemp("b272undo")
|
|
build = subprocess.run( # noqa: S603 — 고정 실행 파일
|
|
[
|
|
"node",
|
|
str(ROOT / "config" / "node_modules" / "vite" / "bin" / "vite.js"),
|
|
"build",
|
|
"--configLoader",
|
|
"runner",
|
|
"--ssr",
|
|
"../resources/tester/helper_272_choice_undo_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_choice_undo_entry.js", bundle)
|
|
job = work / "job.json"
|
|
job.write_text(
|
|
json.dumps(
|
|
{
|
|
"standard": STANDARD_CROSS_SECTION,
|
|
"rockDefault": STANDARD_ROCK_BOUNDARY_DEFAULT_OFFSET_M,
|
|
"ground": GROUND,
|
|
}
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
proc = subprocess.run( # noqa: S603
|
|
["node", str(HERE / "helper_272_choice_undo.mjs"), str(bundle), 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 test_고르기_전_메모리_다시_셈_같음(out):
|
|
assert out["pristineSame"]
|
|
|
|
|
|
@pytest.mark.parametrize("name", ["choice", "shoulder", "bermDepth"])
|
|
def test_고름_되돌림_정본_다시_고름_같음(out, name):
|
|
case = out["cases"][name]
|
|
assert case["changed"], name # 고름이 실제로 설계를 바꿈
|
|
assert case["undoIsCanon"], name # ↶ = 정본
|
|
assert case["redoIsPicked"], name # ↷ = 고른 값
|
|
assert case["undoAgain"], name
|
|
|
|
|
|
def test_암_경계_되돌림_정본(out):
|
|
case = out["cases"]["rock"]
|
|
assert case["undoIsCanon"] and case["redoIsPicked"] and case["undoAgain"]
|
|
|
|
|
|
def test_단추가_메모리_설계를_안_덮음():
|
|
sync = (ROOT / "B06_Section" / "B06_Section_UI_Page_Design_Sync.ts").read_text(encoding="utf-8")
|
|
body = sync[
|
|
sync.index("async function handleDesignChange") : sync.index("function recomputeIfRock")
|
|
]
|
|
assert "target.design" not in body
|
|
refresh = (ROOT / "B06_Section" / "B06_Section_Cross_Refresh.ts").read_text(encoding="utf-8")
|
|
assert "savedDesigns(projectId, input.routeId)" in refresh
|