- 상세 가게 칸 셋(B06_Section_Section_Canon.ts · 가벼운 자리): 저장 정본 상세(받을 때 · 세션 · 판 바뀜 · 되돌릴 때 · 갈아끼움 제외) · 초안 전 hold 상세(판 바뀌면 새 판) · 노선 초안 상세(= pipelineDetail) - 페이지: canon.detail · held.detail · shown 사본 걷음 — 저장 기준 셈(savedEdits · storedPvi · crossNow)은 가게 칸을 읽음 · 초안 버림 = 가게 hold 상세로 정본 잡음 - 떠남(forgetSectionMemory) · invalidate 때 칸 셋 비움 · savedStations 는 sub2 관 · 구조물 줄로 셈 → 남김 - 시험: test_472_5b_detail_owner(옛 코드 빨강 3) · 묶음 헬퍼 넷(365 · 346_2 · 349_0j · 451_drop)이 종단도 흉내 정본을 가게 칸에도 채움 - 위키 design_page 값 · 규칙 · 층 줄 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
2.8 KiB
Python
61 lines
2.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""472-5 5-B — 횡단 상세 객체의 주인 = 상세 가게 하나(칸 셋: 저장 정본 · 초안 전 hold · 노선 초안).
|
|
|
|
옛 꼴: 계산 묶음 페이지가 상세 객체를 따로 쥠(정본 `canon.detail` · 초안 전 `held.detail` ·
|
|
노선 초안 `shown`) — 가게가 판 바뀜(433-16)으로 hold 를 새 판으로 바꿔도 페이지는 옛 객체로
|
|
정본을 잡았음.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
TS = ROOT / "config" / "node_modules" / "typescript"
|
|
|
|
|
|
def _src(*parts: str) -> str:
|
|
return (ROOT.joinpath(*parts)).read_text(encoding="utf-8")
|
|
|
|
|
|
def test_페이지는_상세를_안_쥠() -> None:
|
|
page = _src("A00_Common", "design", "design_pipeline_page.ts")
|
|
saved = _src("A00_Common", "design", "design_pipeline_page_saved.ts")
|
|
assert "let shown" not in page # 노선 초안 상세 = 가게 칸
|
|
assert "setDraftSectionDetail(projectId, shown)" in page
|
|
assert "detail: () => draftDetailOf(projectId)" in page
|
|
assert "detail: SectionDetailResponse | null;" not in page # hold 에 상세 사본 없음
|
|
assert "heldSectionDetail(projectId, routeId as number)" in page
|
|
assert "let canon: { routeId: unknown; samples: unknown } | null" in saved # 지문만
|
|
assert "savedSectionDetail(projectId, canon.routeId)" in saved
|
|
|
|
|
|
def test_가게가_칸을_채움() -> None:
|
|
store = _src("B06_Section", "B06_Section_Section_Store.ts")
|
|
# 받을 때(세션 · 새로 받음 · 판 바뀜) · 되돌릴 때 = 저장 정본 칸 · 갈아끼움은 안 씀
|
|
assert store.count("keepSavedDetail(projectId, routeId,") == 4
|
|
swap = store[store.index("export async function swapSectionStations(") :]
|
|
assert "keepSavedDetail" not in swap[: swap.index("\n}\n")]
|
|
# 판이 바뀌면 hold 도 새 판(433-16)
|
|
renew = "if (heldSectionDetail(projectId, routeId) === stored) keepHeldDetail("
|
|
assert renew + "projectId, routeId, fresh);" in store
|
|
forget = store[store.index("export function forgetSectionMemory(") :]
|
|
assert "forgetDetailSlots(projectId);" in forget[: forget.index("\n}\n")]
|
|
|
|
|
|
@pytest.mark.skipif(not TS.is_dir(), reason="프론트엔드 의존성 미설치")
|
|
def test_칸_셋_넣고_비움() -> None:
|
|
helper = ROOT / "resources" / "tester" / "helper_472_5b_slots.cjs"
|
|
run = subprocess.run(
|
|
["node", str(helper)], capture_output=True, text=True, encoding="utf-8", timeout=60
|
|
)
|
|
assert run.returncode == 0, run.stderr
|
|
got = json.loads(run.stdout)
|
|
assert got["saved1"] == "a" and got["held1"] == "b" and got["draft"] == "d"
|
|
assert got["after1"] == [None, None, "b", "d"] # 노선 하나만 · 초안 칸은 그대로
|
|
assert got["afterAll"] == [None, None]
|