Files
Aislo/resources/tester/helper_224_1_picker_top_table.cjs
T
eomsangdonandClaude Sonnet 5.5 03eddde558 test(508-1b 옛 헬퍼 공용 불러오기 2/7): 헬퍼 26 곳 loadTs 베낌 걷고 makeLoader 로
- 헬퍼 동작 그대로(풀이 함수 본문은 옮겨 담음) · 제품 코드 안 고침
- 확인: 이 묶음 헬퍼를 쓰는 시험 279 개 전 279 통과 → 후 279 통과 (시험별 junit 대조 · 어긋남 0)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 17:07:17 +09:00

182 lines
6.5 KiB
JavaScript

/* 고르기 모달 상단 표(224-1) 시험 헬퍼 — `ui_template_item_picker_table.ts` 를 트랜스파일해
* 표 부품 · 집계표 모듈 · 서버 읽기를 대역으로 갈아 끼우고 돌려 부름 기록을 JSON 한 벌로 냄.
* 동적 `import()` 도 CommonJS 변환에서 같은 `require` 길을 타 대역이 먹음.
* ⚠ 확장자가 `.cjs` 인 까닭은 `helper_b05_curve_radius_floor.cjs` 머리와 같다.
*/
const fs = require("fs");
const path = require("path");
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const UI = path.join(ROOT, "ui_template");
const log = [];
const state = { numbersFail: false, tableFail: null };
const node = (props = {}) => ({
className: props.className ?? "",
hidden: "attrs" in props && props.attrs && "hidden" in props.attrs,
text: props.text ?? "",
children: props.children ?? [],
replaceChildren(...kids) {
this.children = kids;
},
});
const STUBS = {
"./ui_template_elements": { el: (_tag, props) => node(props) },
"./ui_template_locale": {
t: (key) => (key === "M02_PickerTableFailed" ? "표 실패 {value}" : "읽는 중"),
},
"../M02_MasterTemplete/M02_MasterTemplete_Api_Fetch": {
readTemplate: async (...args) => {
log.push(["readTemplate", ...args]);
if (state.tableFail) throw new Error(state.tableFail);
return { 문서: { 열: [], tag: `${args[0]}|${args[4]}` } };
},
fetchStructureNumbersAt: async (...args) => {
log.push(["numbers", ...args]);
if (state.numbersFail) throw new Error("numbers down");
return { rv1: { 도번: "SD1" } };
},
},
"../M02_MasterTemplete/M02_MasterTemplete_Structure": {
STRUCTURE_TABLE: "구조물집계표",
comboView: (doc) => ({ ...doc, comboView: true }),
numberLabels: (numbers) => ({ laborLabel: () => "", seenNumbers: numbers() }),
},
"./sheet/ui_template_sheet": {
createSheet: (host, doc, opts) => {
const entry = { doc, opts, selected: [], destroyed: false, host };
log.push(["createSheet", entry]);
host.replaceChildren({ sheet: true });
return {
selectColumn: (id) => entry.selected.push(id),
destroy: () => (entry.destroyed = true),
};
},
},
};
const { loadTs } = makeLoader({
root: ROOT,
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (request.startsWith(".")) return loadTs(`${path.resolve(path.dirname(full), request)}.ts`);
return require(request);
},
});
const flush = () => new Promise((resolve) => setTimeout(resolve, 20));
const row = (key, 열, layer, owner) => ({ key, 열, layer, owner });
const names = () => log.map((entry) => entry[0]);
// 280-2 — 표는 층(+ 주인) · 열을 받음
const at = (r) => (r ? { layer: r.layer, owner: r.owner } : null);
const show = (table, r) => table.show(at(r), r ? r.열 : "");
const picked = [];
const creates = () => log.filter((entry) => entry[0] === "createSheet").map((entry) => entry[1]);
(async () => {
const { createComboTable } = loadTs(path.join(UI, "ui_template_item_picker_table.ts"));
const data = loadTs(path.join(UI, "ui_template_item_picker_data.ts"));
const out = {};
const mine = row("SS1", "rv1", "personal", "1/3");
const sameLayer = row("SS2", "rv2", "personal", "1/3");
const master = row("SS9", "rv9", "system", null);
const table = createComboTable((colId) => picked.push(colId));
out.startHidden = table.root.hidden;
show(table, null);
out.nullHidden = table.root.hidden;
out.nullCalls = names();
show(table, mine);
out.shownHidden = table.root.hidden;
await flush();
out.firstReads = log.filter((e) => e[0] !== "createSheet");
const first = creates()[0];
out.first = {
count: creates().length,
readOnly: first.opts.readOnly,
lockHead: first.opts.lockHead,
mode: first.opts.mode,
combo: !!first.opts.combo,
comboDoc: first.doc.comboView,
docTag: first.doc.tag,
numbersSeen: first.opts.seenNumbers,
selected: first.selected,
};
log.length = 0;
show(table, sameLayer); // 같은 층 다른 조합 — 표 그대로 · 열만
await flush();
out.sameLayer = { calls: names(), selected: first.selected, destroyed: first.destroyed };
log.length = 0;
show(table, master); // 다른 층 — 그 층 표로 바뀜
await flush();
out.otherLayer = {
reads: log.filter((e) => e[0] === "readTemplate"),
creates: creates().length,
oldDestroyed: first.destroyed,
selected: creates()[0].selected,
docTag: creates()[0].doc.tag,
};
log.length = 0;
show(table, null);
out.hideAgain = table.root.hidden;
// 읽는 사이에 다른 조합을 고름 — 마지막 것만 그려짐
log.length = 0;
show(table, mine);
show(table, master);
await flush();
out.race = { creates: creates().length, docTag: creates()[0]?.doc.tag };
// 번호 읽기 실패 — 표는 그려짐
log.length = 0;
state.numbersFail = true;
const lone = createComboTable((colId) => picked.push(colId));
show(lone, mine);
await flush();
out.numbersFail = { creates: creates().length, seen: creates()[0]?.opts.seenNumbers };
state.numbersFail = false;
// 표 읽기 실패 — 까닭 글 · 표 없음
log.length = 0;
state.tableFail = "그 층은 아직 만든 것이 없음";
const broken = createComboTable((colId) => picked.push(colId));
show(broken, mine);
await flush();
out.tableFail = { creates: creates().length, text: broken.root.children[0].text };
out.keys = {
mineSame: data.tableKey(mine) === data.tableKey(sameLayer),
layerDiffers: data.tableKey(mine) !== data.tableKey(master),
ownerDiffers: data.tableKey(mine) !== data.tableKey(row("SS1", "rv1", "personal", "1/4")),
mine: data.tableKey(mine),
};
// 280-2 — 표에서 고른 열은 부른 쪽에 넘김 · 열 없는 고름(colId null)은 안 넘김
state.tableFail = null;
const fresh = createComboTable((colId) => picked.push(colId));
log.length = 0;
show(fresh, mine);
await flush();
const sheetOpts = creates()[0].opts;
sheetOpts.onSelect({ colId: "rv2" });
sheetOpts.onSelect({ colId: null });
out.onColumn = picked.slice(-1);
// 층만 바꿈(고른 열 없음) — 그 층 표를 그리고 열은 안 고름
log.length = 0;
fresh.show({ layer: "system", owner: null }, "");
await flush();
out.layerOnly = {
reads: log.filter((e) => e[0] === "readTemplate"),
selected: creates()[0].selected,
};
console.log(JSON.stringify(out));
})().catch((error) => {
console.error(error);
process.exit(1);
});