- 시험 anchor 한 줄(test_272_detail_memory 화면 선만 바뀜 = 정본 노선 번호를 나눈 파일에서 읽음) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
122 lines
5.1 KiB
Python
122 lines
5.1 KiB
Python
"""PLAN 466 (요구 272 · 분석 4장 (A)) — 상세 가게 메모리 = 페이지 수명.
|
|
|
|
못박는 것
|
|
- 관 초안으로 갈아끼운 상세(메모리) → [폐기] → 페이지를 떠남 = 메모리 비움 → 다시 열기(B05 · B06 · B07) =
|
|
세션 정본(새로고침 길 · 뒤에서 판 확인 한 번) · 초안 측점이 남지 않음. 다른 프로젝트 메모리는 그대로.
|
|
- 페이지 dispose 가 비움(`design_page`) · 묶음 열 때 관 · 구조물 · 추가 측점 초안이 있으면 측점을 냄
|
|
(초안 남긴 채 떠남 · 새로고침 = 초안 측점 · 갈아끼움).
|
|
- 화면 선만 바뀜(비정규 측점 도착) = 상세가 그 선 대비 낡았으면 cross 한 번 더(`recrossIfStale`).
|
|
짝: `helper_272_detail_memory_entry.ts` + `helper_272_detail_memory.mjs`(진짜 상세 가게 · vite ssr).
|
|
|
|
./venv/Scripts/python.exe -m pytest resources/tester/test_272_detail_memory.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(work: Path) -> dict:
|
|
"""vite ssr 로 진짜 모듈을 묶어 헬퍼를 돌림 — 466 두 시험이 같이 씀."""
|
|
build = subprocess.run( # noqa: S603 — 고정 실행 파일
|
|
[
|
|
"node",
|
|
str(ROOT / "config" / "node_modules" / "vite" / "bin" / "vite.js"),
|
|
"build",
|
|
"--configLoader",
|
|
"runner",
|
|
"--ssr",
|
|
"../resources/tester/helper_272_detail_memory_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_detail_memory_entry.js", bundle)
|
|
proc = subprocess.run( # noqa: S603 — 고정 실행 파일
|
|
["node", str(HERE / "helper_272_detail_memory.mjs"), str(bundle)],
|
|
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 got(tmp_path_factory) -> dict:
|
|
return run_helper(tmp_path_factory.mktemp("b272"))
|
|
|
|
|
|
def test_초안_동안은_메모리만_갈아끼움(got) -> None:
|
|
m = got["memory"]
|
|
assert m["swapped"] and m["during"] == [0, 20, 30, 40, 60]
|
|
assert m["session"] == [0, 20, 40, 60] # 세션 = 저장 정본
|
|
|
|
|
|
def test_폐기만으론_메모리_그대로_떠나면_정본(got) -> None:
|
|
m = got["memory"]
|
|
assert m["pipesAfterDiscard"] is None # 관 초안 지움
|
|
assert m["afterDiscard"] == [0, 20, 30, 40, 60] # 같은 페이지 안 = 메모리(떠날 때 비움)
|
|
assert m["peekAfterForget"] is None
|
|
assert m["reopened"] == [0, 20, 40, 60] and m["reopenedSame"] is False # 새로고침 길
|
|
assert m["canonAsked"] == 1 # 세션으로 서고 뒤에서 판 확인(새로고침과 같음)
|
|
assert m["otherKept"] is True
|
|
|
|
|
|
def test_페이지가_떠날_때_비움() -> None:
|
|
page = (ROOT / "A00_Common/design/design_page.ts").read_text(encoding="utf-8")
|
|
dispose = page[page.index(" covers: (route)") :]
|
|
assert "forgetSectionMemory(projectId);" in dispose[: dispose.index("\n };\n")]
|
|
|
|
|
|
def test_초안_있으면_열_때_측점_냄() -> None:
|
|
src = (ROOT / "A00_Common/design/design_pipeline_page.ts").read_text(encoding="utf-8")
|
|
start = src[src.index(" const start = (): void => {") :]
|
|
body = start[: start.index("\n };\n")]
|
|
assert 'store.get("pipes") ?? store.get("structures") ?? readPlusDraft(projectId)' in body
|
|
assert "quietGeneration = inputs.route || drafts ? -1 : pipe.generation;" in body
|
|
|
|
|
|
def test_화면_선만_바뀌면_낡음_다시_셈() -> None:
|
|
src = (ROOT / "A00_Common/design/design_pipeline_page.ts").read_text(encoding="utf-8")
|
|
restart = src[src.index(" restart() {") :]
|
|
# 정본 지문은 `design_pipeline_page_saved`(472-5 나눔) — 노선 번호를 거기서 읽음
|
|
assert (
|
|
"publisher.recheck(projectId, pageSaved.canonRouteId()"
|
|
in restart[: restart.index(" },")]
|
|
)
|
|
store = (ROOT / "B06_Section/B06_Section_Section_Store.ts").read_text(encoding="utf-8")
|
|
fn = store[store.index("export function recrossIfStale(") :]
|
|
assert "recrossSaved(projectId, key, detail, routeId)" in fn[: fn.index("\n}\n")]
|
|
|
|
|
|
def test_확정_성공도_상세_비움() -> None:
|
|
# 470 N1 — [확정] 은 다음 페이지(B07)로 바로 감 · [저장]처럼 상세 메모리 · 옛 세션 사본을 비움
|
|
shared = (ROOT / "A00_Common/design/design_shared.ts").read_text(encoding="utf-8")
|
|
done = shared[shared.index(" done: async (isConfirm) => {") :]
|
|
confirm = done[done.index("if (isConfirm) {") : done.index("goToWorkflowStage(")]
|
|
assert "invalidateSectionDetail(shared.projectId);" in confirm
|