fix(B05·B06): 관 · 구조물을 전부 지우고 떠나도 묻는 창이 뜨게 함 (PLAN 469-3 · 요구 432)
- 빈 목록 초안 "[]" 판정을 draftFilled 한 함수로 — 떠남 확인(design_leave)과 hasDrafts 가 같은 규칙 - 저장분이 있는 목록 칸의 "[]" = 고침 · 저장분도 빈 곳 · 저장분을 모를 때 = 전처럼 빈 칸 - 저장분 있음은 페이지 자료 줄(design_page_data)이 받을 때 적음 — 새 서버 요청 없음 - 지킴 시험 test_469_3 · 자료 줄 흉내 헬퍼 둘에 새 import 흉내 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,6 +56,7 @@ const drafts = loadTs("B06_Section/B06_Section_Section_Drafts.ts", {
|
||||
fetchSectionContext: async () => ({ route_id: 1 }),
|
||||
},
|
||||
"./design_page_route": loadTs("A00_Common/design/design_page_route.ts"), // 노선 id 한 칸(386-2b)
|
||||
"../b_page_state": { noteSavedList: () => undefined, forgetSavedLists: () => undefined },
|
||||
}),
|
||||
"../B05_Profile/B05_Profile_Api_Pipes_Draft": { readPendingPipes: () => draftPipes },
|
||||
"../B05_Profile/B05_Profile_Api_PlusStations": { readPlusDraft: () => null },
|
||||
|
||||
@@ -15,6 +15,7 @@ const routeBox = { exports: {} };
|
||||
new Function("exports", "module", "require", routeJs)(routeBox.exports, routeBox, () => ({}));
|
||||
const STUBS = {
|
||||
"./design_page_route": routeBox.exports, // 노선 id 한 칸(386-2b · 진짜)
|
||||
"../b_page_state": { noteSavedList: () => undefined, forgetSavedLists: () => undefined },
|
||||
"../../B04_PreProcess/B04_PreProcess_Api_Fetch": {
|
||||
fetchDetailPipePoints: async () => {
|
||||
calls.pipes += 1;
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/* 469-3 빈 목록 초안("[]") 떠남 판정 헬퍼 — `design_leave` · `b_page_state` 를 한 번씩만 읽어(같은 모듈 한 벌)
|
||||
* 저장분 있음/없음에 따라 designDirty · hasDrafts 가 같게 나오는지. 결과 JSON 을 stdout 으로.
|
||||
*/
|
||||
const path = require("path");
|
||||
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
|
||||
|
||||
const ROOT = path.join(__dirname, "..", "..");
|
||||
|
||||
const map = new Map();
|
||||
const session = {
|
||||
getItem: (key) => (map.has(key) ? map.get(key) : null),
|
||||
setItem: (key, value) => map.set(key, String(value)),
|
||||
removeItem: (key) => map.delete(key),
|
||||
key: (index) => [...map.keys()][index] ?? null,
|
||||
get length() {
|
||||
return map.size;
|
||||
},
|
||||
};
|
||||
globalThis.window = { sessionStorage: session, localStorage: session };
|
||||
globalThis.sessionStorage = session;
|
||||
|
||||
const STUBS = {
|
||||
"@config/config_frontend": {
|
||||
ROUTES: { B05_PROFILE: "/b05-profile", B06_SECTION: "/b06-section" },
|
||||
},
|
||||
"@ui/ui_template_locale": { t: (key) => key },
|
||||
"../b_project_switch": { guardProjectLeave: () => undefined },
|
||||
};
|
||||
const { loadTs } = makeLoader({
|
||||
root: ROOT,
|
||||
requireFor: (full, file) => (request) => {
|
||||
if (request in STUBS) return STUBS[request];
|
||||
if (request.startsWith(".")) return loadTs(path.join(path.dirname(file), `${request}.ts`));
|
||||
return require(request);
|
||||
},
|
||||
});
|
||||
const state = loadTs(path.join(ROOT, "A00_Common", "b_page_state.ts"));
|
||||
const leave = loadTs(path.join(ROOT, "A00_Common", "design", "design_leave.ts"));
|
||||
const P = "p1";
|
||||
const set = (name, raw) => session.setItem(`aislo:draft:${name}:${P}`, raw);
|
||||
const unset = (name) => session.removeItem(`aislo:draft:${name}:${P}`);
|
||||
const both = () => [leave.designDirty(P), state.hasDrafts(P)];
|
||||
|
||||
const out = {};
|
||||
set("pipes", "[]");
|
||||
out.unknownSaved = both(); // 저장분을 모름 = 빈 칸(전과 같음)
|
||||
state.noteSavedList(P, "pipes", false);
|
||||
out.savedEmpty = both(); // 처음부터 관 0
|
||||
state.noteSavedList(P, "pipes", true);
|
||||
out.savedFilled = both(); // 관 있던 곳에서 모두 지움
|
||||
unset("pipes");
|
||||
set("structures", "[]");
|
||||
out.structuresSavedEmpty = both();
|
||||
state.noteSavedList(P, "structures", true);
|
||||
out.structuresSavedFilled = both();
|
||||
leave.discardDesignEdits(P);
|
||||
out.afterDiscard = [both(), session.getItem(`aislo:draft:structures:${P}`)];
|
||||
set("pipes", "[]");
|
||||
state.forgetSavedLists(P);
|
||||
out.afterForget = both();
|
||||
for (const raw of ["{}", ""]) {
|
||||
set("pipes", raw);
|
||||
state.noteSavedList(P, "pipes", true);
|
||||
out[`raw_${raw || "empty"}`] = both();
|
||||
}
|
||||
state.noteSavedList(P, "pipes", true);
|
||||
set("pipes", '[{"id":1}]');
|
||||
out.withItems = both();
|
||||
process.stdout.write(JSON.stringify(out));
|
||||
@@ -0,0 +1,44 @@
|
||||
"""469-3 빈 목록 초안("[]") 떠남 판정 — 저장분이 있으면 고침 · 없으면 빈 칸 · 떠남 확인과 hasDrafts 한 규칙.
|
||||
|
||||
./venv/Scripts/python.exe -m pytest resources/tester/test_469_3_list_draft_leave.py -q
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
HELPER = Path(__file__).resolve().parent / "helper_469_3_list_draft.cjs"
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def out() -> dict:
|
||||
run = subprocess.run( # noqa: S603 — 고정 실행 파일
|
||||
["node", str(HELPER)], capture_output=True, text=True, encoding="utf-8"
|
||||
)
|
||||
assert run.returncode == 0, run.stderr
|
||||
return json.loads(run.stdout)
|
||||
|
||||
|
||||
def test_저장분이_비었거나_모르면_빈_칸(out) -> None:
|
||||
assert out["unknownSaved"] == [False, False]
|
||||
assert out["savedEmpty"] == [False, False]
|
||||
assert out["structuresSavedEmpty"] == [False, False]
|
||||
assert out["afterForget"] == [False, False]
|
||||
|
||||
|
||||
def test_저장분이_있는데_모두_지웠으면_고침(out) -> None:
|
||||
assert out["savedFilled"] == [True, True]
|
||||
assert out["structuresSavedFilled"] == [True, True]
|
||||
|
||||
|
||||
def test_폐기는_빈_목록_칸도_지움(out) -> None:
|
||||
assert out["afterDiscard"] == [[False, False], None]
|
||||
|
||||
|
||||
def test_빈_객체_빈_글은_그대로_빈_칸_항목이_있으면_고침(out) -> None:
|
||||
assert out["raw_{}"] == [False, False] and out["raw_empty"] == [False, False]
|
||||
assert out["withItems"] == [True, True]
|
||||
Reference in New Issue
Block a user