- 횡단 미리보기 요청에 적용 반폭을 실어 보내고 서버가 덮은 반폭을 되돌려 줌 - 파란 선 좌·우 길이 = 그 반폭 (원지반 선 범위와 같은 값) · 적용한 적 없으면 서버 기본값 - 시험 test_b05_routeedit_cross_width.py 추가 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmELpdXFDRZHhfbGuRhSmL
123 lines
4.4 KiB
JavaScript
123 lines
4.4 KiB
JavaScript
/* 계획노선 편집 창 **측점 반폭 선 길이**(계획서 22-1) 단위검증 헬퍼 —
|
|
* `B05_Profile_UI_RouteEdit_Cross.ts` 를 트랜스파일해 Node 로 돌린다.
|
|
* 서버 묻기 · 그림 조각은 가짜로 채운다 — 「무슨 반폭을 묻고 · 무슨 반폭으로 선을 잡나」만 본다.
|
|
*/
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
|
|
const ROOT = path.join(__dirname, "..", "..");
|
|
|
|
function memoryStorage() {
|
|
const map = new Map();
|
|
return {
|
|
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;
|
|
},
|
|
};
|
|
}
|
|
const session = memoryStorage();
|
|
Object.defineProperty(session, "length", { get: () => session._keys().length });
|
|
session._keys = () => {
|
|
const keys = [];
|
|
for (let i = 0; i < 1000; i += 1) {
|
|
const key = session.key(i);
|
|
if (key === null) break;
|
|
keys.push(key);
|
|
}
|
|
return keys;
|
|
};
|
|
// `Object.keys(sessionStorage)` 가 저장된 키를 돌려주도록 실제 브라우저처럼 속성으로도 둔다.
|
|
const sessionProxy = new Proxy(session, {
|
|
ownKeys: () => [...new Set(session._keys())],
|
|
getOwnPropertyDescriptor: (target, key) =>
|
|
session._keys().includes(key)
|
|
? { enumerable: true, configurable: true, value: target.getItem(key) }
|
|
: Reflect.getOwnPropertyDescriptor(target, key),
|
|
});
|
|
globalThis.window = { localStorage: memoryStorage(), sessionStorage: sessionProxy };
|
|
|
|
const fakeEl = () => ({
|
|
className: "",
|
|
textContent: "",
|
|
innerHTML: "",
|
|
querySelector: () => fakeEl(),
|
|
replaceChildren() {},
|
|
append() {},
|
|
getBoundingClientRect: () => ({ width: 300, height: 200 }),
|
|
});
|
|
globalThis.document = { createElement: fakeEl };
|
|
|
|
const asked = [];
|
|
const STUBS = {
|
|
"../A00_Common/b_svg_zoom_pan": { attachSvgZoomPan: () => {} },
|
|
"../common_util/common_util_station": { stationLabel: (m) => String(m) },
|
|
"./B05_Profile_UI_RouteEdit_Cross_Draw": {
|
|
buildCrossSvg: () => ({ svg: {}, layer: {}, width: 1, height: 1, content: {} }),
|
|
CROSS_PLOT_PAD: 0,
|
|
summarizeCross: () => "",
|
|
},
|
|
// 서버 흉내 — 요청 반폭을 그대로 되돌려 주고, 없으면 기본 20.
|
|
"./B05_Profile_Api_Replan": {
|
|
fetchCrossPreview: async (_project, request) => {
|
|
asked.push(request.cross_half_width_m ?? null);
|
|
return {
|
|
chainage_m: request.chainage_m,
|
|
cross_half_width_m: request.cross_half_width_m ?? 20,
|
|
samples: [],
|
|
design: null,
|
|
};
|
|
},
|
|
},
|
|
};
|
|
|
|
const cache = new Map();
|
|
function loadTs(file) {
|
|
const full = path.resolve(file);
|
|
if (cache.has(full)) return cache.get(full);
|
|
const js = ts.transpileModule(fs.readFileSync(full, "utf8"), {
|
|
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
|
|
}).outputText;
|
|
const box = { exports: {} };
|
|
cache.set(full, box.exports);
|
|
const localRequire = (request) => {
|
|
if (STUBS[request]) return STUBS[request];
|
|
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
|
|
return require(request);
|
|
};
|
|
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
|
|
cache.set(full, box.exports);
|
|
return box.exports;
|
|
}
|
|
|
|
const { createCrossPreview } = loadTs(
|
|
path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_Cross.ts"),
|
|
);
|
|
|
|
async function run() {
|
|
const cross = createCrossPreview({
|
|
projectId: "p-1",
|
|
side: { append() {} },
|
|
request: () => ({ vertices: [], min_radius_m: 12, station_interval_m: 20 }),
|
|
});
|
|
const out = {};
|
|
out.before = cross.watched();
|
|
await cross.open(100);
|
|
out.empty = { asked: asked.at(-1), watched: cross.watched() };
|
|
session.setItem("aislo:draft:cross-display:p-1:3", "15");
|
|
await cross.refresh();
|
|
out.applied15 = { asked: asked.at(-1), watched: cross.watched() };
|
|
session.setItem("aislo:draft:cross-display:p-1:12", "8.5");
|
|
session.setItem("aislo:draft:cross-display:p-2:99", "40");
|
|
await cross.refresh();
|
|
out.latestRoute = { asked: asked.at(-1), watched: cross.watched() };
|
|
session.setItem("aislo:draft:cross-display:p-1:12", "abc");
|
|
await cross.refresh();
|
|
out.badValue = { asked: asked.at(-1), watched: cross.watched() };
|
|
return out;
|
|
}
|
|
run().then((out) => console.log(JSON.stringify(out)));
|