- design_page_data 새로 — 저장분(구조물 · 관 · 정의 판 확인) 페이지에서 한 번 · 저장 정본 바뀜(invalidate) · 페이지 떠남에 비움 · 보기 전환 요청 0 - 묶음 · 두 보기 구조물 칸 · 초안 측점이 같은 줄 · 「계산 중」 점(도크 · 묶음 차례 동안) - 묶음 planline 저장 기준 = 입력(관 · 구조물)이 심는 측점(design_pipeline_base · 페이지가 옵션으로) · baseMoved 지움 · 종류 한 벌 - design_pipeline_page 700줄 앞 쪼갬(design_pipeline_page_types) - 시험 test_384_2 · test_384_3 · 엄격 흉내 helper 에 자료 줄 더함 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TteK8mfYZetk5P3bEZkyVZ
93 lines
3.3 KiB
JavaScript
93 lines
3.3 KiB
JavaScript
/* PLAN 386-2 단위검증 헬퍼 — 진짜 `design_page_data.ts` 를 서버 흉내(받은 횟수 셈)로 돌림.
|
|
* 결과 = 표준출력 JSON 한 벌. 짝 = `test_384_2_page_data.py`. */
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
|
|
|
|
const ROOT = path.join(__dirname, "..", "..");
|
|
const calls = { structures: 0, pipes: 0, version: 0 };
|
|
let failPipes = false;
|
|
const STUBS = {
|
|
"../../B04_PreProcess/B04_PreProcess_Api_Fetch": {
|
|
fetchDetailPipePoints: async () => {
|
|
calls.pipes += 1;
|
|
if (failPipes) throw new Error("끊김");
|
|
return { pipe_points: [{ chainage_m: 10, facility: "pipe" }], basins: [] };
|
|
},
|
|
},
|
|
"../../B05_Profile/B05_Profile_Api_Structures": {
|
|
fetchStructures: async () => {
|
|
calls.structures += 1;
|
|
return { structures: [{ structure_id: "s1", chainage_m: 20 }], revision: calls.structures };
|
|
},
|
|
dropStaleStructureTypes: async () => {
|
|
calls.version += 1;
|
|
return false;
|
|
},
|
|
},
|
|
};
|
|
const js = ts.transpileModule(
|
|
fs.readFileSync(path.join(ROOT, "A00_Common", "design", "design_page_data.ts"), "utf8"),
|
|
{ compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 } },
|
|
).outputText;
|
|
const box = { exports: {} };
|
|
new Function("exports", "module", "require", js)(box.exports, box, (name) => {
|
|
if (!STUBS[name]) throw new Error(`stub 없음: ${name}`);
|
|
return STUBS[name];
|
|
});
|
|
const data = box.exports;
|
|
const P = "p1";
|
|
const tick = () => new Promise((resolve) => setTimeout(resolve, 0));
|
|
|
|
(async () => {
|
|
const out = {};
|
|
// 열 때 · 보기 전환 · 다시 보임 = 같은 저장분 — 서버는 한 번
|
|
const [a, b] = await Promise.all([data.pageStructures(P), data.pageStructures(P)]);
|
|
await data.pageStructures(P);
|
|
await data.pagePipes(P);
|
|
await data.pagePipes(P);
|
|
await data.pageTypesChecked(P);
|
|
await data.pageTypesChecked(P);
|
|
out.open = { ...calls };
|
|
// 사본 — 받는 쪽이 고쳐도 다음 받기는 그대로
|
|
a.structures.push({ structure_id: "x" });
|
|
out.copy = { same: a === b, after: (await data.pageStructures(P)).structures.length };
|
|
// 다른 프로젝트는 따로
|
|
await data.pageStructures("p2");
|
|
out.other = calls.structures;
|
|
// 저장 정본이 바뀜 — 비우면 다음에 한 번 다시
|
|
data.forgetPageData(P);
|
|
await data.pageStructures(P);
|
|
await data.pageStructures(P);
|
|
out.afterForget = { ...calls };
|
|
// 실패는 기억 안 함 — 다음에 다시 물음
|
|
data.forgetPageData(P);
|
|
failPipes = true;
|
|
out.failed = await data.pagePipes(P).then(
|
|
() => "ok",
|
|
() => "error",
|
|
);
|
|
failPipes = false;
|
|
await data.pagePipes(P);
|
|
out.retry = calls.pipes;
|
|
// 「계산 중」 — 떠 있는 차례가 끝날 때까지 켬(밀림 · 실패도 끔)
|
|
const seen = [];
|
|
const stop = data.onPageBusy(P, (busy) => seen.push(busy));
|
|
let finish;
|
|
data.trackPageBusy(P, new Promise((resolve) => (finish = resolve)));
|
|
data.trackPageBusy(P, Promise.reject(new Error("밀림")));
|
|
data.trackPageBusy(P, null);
|
|
await tick();
|
|
out.midBusy = seen[seen.length - 1];
|
|
finish();
|
|
await tick();
|
|
stop();
|
|
data.trackPageBusy(P, Promise.resolve());
|
|
await tick();
|
|
out.busy = seen;
|
|
process.stdout.write(JSON.stringify(out));
|
|
})().catch((error) => {
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|