- 헬퍼 동작 그대로(풀이 함수 본문은 옮겨 담음) · 제품 코드 안 고침 - 확인: 이 묶음 헬퍼를 쓰는 시험 70 개 전 70 통과 → 후 70 통과 (시험별 junit 대조 · 어긋남 0) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
106 lines
3.5 KiB
JavaScript
106 lines
3.5 KiB
JavaScript
/* 506-3 B07 저장 길 헬퍼 — `_UI_Save` 를 Node 로 돌려 끊긴(abort) 저장 판정 · 저장 중 표 · 자동백업 열쇠 ·
|
|
* [초기화] 물음 글을 표준출력 JSON 한 벌로. 서버 길 · 알림 · 물음은 기록용 가짜.
|
|
*/
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
|
|
|
|
const B07 = path.join(__dirname, "..", "..", "B07_DesignDetail");
|
|
const calls = [];
|
|
let confirmError = null;
|
|
let listConfirmed = false;
|
|
let savingSeen = null;
|
|
let asked = "";
|
|
let Save;
|
|
|
|
const STUBS = {
|
|
"@ui/ui_template_elements": {
|
|
showToast: (message, kind) => calls.push(["toast", kind]),
|
|
showLoadingOverlay: () => calls.push(["overlay+"]),
|
|
hideLoadingOverlay: () => calls.push(["overlay-"]),
|
|
showConfirmDialog: async (message) => ((asked = message), calls.push(["ask"]), true),
|
|
},
|
|
"./B07_DesignDetail_Api_Fetch": {
|
|
confirmDesignDrawing: async (projectId, id) => {
|
|
calls.push(["confirm", id]);
|
|
savingSeen = Save.isSaving();
|
|
if (confirmError) throw confirmError;
|
|
},
|
|
fetchDesignDrawingList: async () => {
|
|
calls.push(["list"]);
|
|
return { drawings: [{ id: "cross_s1", confirmed: listConfirmed }] };
|
|
},
|
|
invalidateDesignDrawing: async () => undefined,
|
|
resetDesignDrawings: async () => ({ status: "success" }),
|
|
},
|
|
};
|
|
|
|
global.localStorage = { removeItem: (key) => calls.push(["drop", key]) };
|
|
global.location = { reload: () => calls.push(["reload"]) };
|
|
global.document = { querySelectorAll: () => [] };
|
|
|
|
const { loadTs } = makeLoader({
|
|
root: path.join(__dirname, "..", ".."),
|
|
cache: false,
|
|
requireFor: (full) => {
|
|
return (r) => STUBS[r] ?? {};
|
|
},
|
|
});
|
|
|
|
Save = loadTs(path.join(B07, "B07_DesignDetail_UI_Save.ts"));
|
|
|
|
const storeOf = () => {
|
|
let dirty = true;
|
|
const tab = { id: "cross_s1", dirty };
|
|
return {
|
|
projectId: "p1",
|
|
drawings: [{ id: "cross_s1", kind: "cross", label: "횡단 1", confirmed: false }],
|
|
tabs: {
|
|
tabs: () => [tab],
|
|
active: () => tab,
|
|
markClean: (t) => ((t ?? tab).dirty = false),
|
|
anyDirty: () => tab.dirty,
|
|
},
|
|
current: () => ({ id: "cross_s1", kind: "cross", label: "횡단 1", confirmed: false }),
|
|
cadDirty: () => dirty,
|
|
setCadClean: () => (dirty = false),
|
|
requestCad: async () => ({ drawing: {}, quantityTable: null }),
|
|
isFrameEditing: () => false,
|
|
forget: () => undefined,
|
|
reload: async () => undefined,
|
|
};
|
|
};
|
|
const take = () => calls.splice(0).map((c) => c.join(":"));
|
|
const abort = () => new DOMException("The operation was aborted.", "AbortError");
|
|
|
|
(async () => {
|
|
const out = {};
|
|
out.scope = Save.recoveryScopeOf("p1", "cross_s1");
|
|
|
|
await Save.saveDrawingsNow(storeOf(), () => calls.push(["saved"]));
|
|
out.normal = { calls: take(), savingSeen, savingAfter: Save.isSaving() };
|
|
|
|
confirmError = abort();
|
|
listConfirmed = true;
|
|
await Save.saveDrawingsNow(storeOf(), () => calls.push(["saved"]));
|
|
out.abortSaved = { calls: take(), savingAfter: Save.isSaving() };
|
|
|
|
listConfirmed = false;
|
|
await Save.saveDrawingsNow(storeOf(), () => calls.push(["saved"]));
|
|
out.abortUnsaved = { calls: take(), savingAfter: Save.isSaving() };
|
|
|
|
confirmError = new Error("서버 오류");
|
|
listConfirmed = true;
|
|
await Save.saveDrawingsNow(storeOf(), () => calls.push(["saved"]));
|
|
out.otherError = take();
|
|
confirmError = null;
|
|
|
|
await Save.resetDrawings(storeOf());
|
|
out.reset = { calls: take(), asked };
|
|
|
|
process.stdout.write(JSON.stringify(out));
|
|
})().catch((error) => {
|
|
process.stderr.write(String(error && error.stack ? error.stack : error));
|
|
process.exit(1);
|
|
});
|