test(508-1d 빨강 가림 1/2): 낡은 가짜 모듈 넷 지금 코드에 맞춤 · 공용 불러오기로 · 낡은 기대 둘 맞춤

- 54_9 알약: 구조물 표 불러오기(322-1) 못 찾음 → makeLoader 기본 풀이
- 398_2 · 408: 곡선 판 가둠(505-3) ResizeObserver · 판 찾기 가짜 더함 → makeLoader
- 323_9: 라우터 draft 길 import.meta.glob(302-1) 가짜 · 옛 풀이 그대로 requireFor · 기대 = 노선 그대로 [저장] 가림막 없음(498-3 D1)
- test_app_settings: CAD 명령 153 → 154(488-3 IMPORT)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-21 17:43:27 +09:00
co-authored by Claude Opus 5.5
parent 98136052a4
commit 0dc6769d6b
6 changed files with 51 additions and 107 deletions
+17 -32
View File
@@ -2,25 +2,12 @@
* `B06_Section_UI_Page_Persist.ts`(횡단 뒤처리) · `B06_Section_Section_Store.ts`(상세 캐시)를 Node 로 돌림.
* 서버 창구만 가짜 — 상세는 저장 전(옛 자리) · 저장 뒤(새 자리) 두 벌.
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader, memoryStorage } = require("./helper_ts_stub_loader.cjs");
const CATALOG = require("./helper_322_catalog_module.cjs"); // 구조물 표(322-1)
const ROOT = path.join(__dirname, "..", "..");
const memory = () => {
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;
},
};
};
globalThis.window = { sessionStorage: memory(), localStorage: memory() };
globalThis.window = { sessionStorage: memoryStorage(), localStorage: memoryStorage() };
globalThis.sessionStorage = globalThis.window.sessionStorage;
const calls = [];
@@ -66,29 +53,27 @@ STUBS[path.join(ROOT, "A00_Common", "design", "design_save_api.ts")] = {
},
};
const cache = new Map();
function loadTs(file) {
const full = path.resolve(file);
if (STUBS[full]) return STUBS[full];
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) => {
// 라우터(302-1 draft 길 `import.meta.glob`) — 이 로더로 못 읽음 · 저장 차례는 지금 길만 봄
STUBS[path.join(ROOT, "A00_Common", "router.ts")] = {
currentRoute: () => "",
remountRoute: () => undefined,
navigateTo: () => undefined,
setLeaveGuard: () => undefined,
};
const anyModule = () => new Proxy({}, { get: () => () => undefined });
const { loadTs } = makeLoader({
root: ROOT,
fileStub: (full) => STUBS[full],
requireFor: (full) => (request) => {
if (STUBS[request]) return STUBS[request];
if (CATALOG.isCatalogRequest(request)) return CATALOG;
if (request.endsWith(".json")) return require(path.join(path.dirname(full), request));
if (request.endsWith(".css")) return {};
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
if (request.startsWith("@")) return new Proxy({}, { get: () => () => undefined });
if (request.startsWith("@")) return anyModule();
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
},
});
// 측점 열쇠 한 벌(344-3 · 346-2)은 진짜로 — 빈 대역은 열쇠 목록을 못 냄
STUBS["@util/common_util_station_key"] = loadTs(
+14 -21
View File
@@ -3,13 +3,11 @@
* 같은 길(스냅 켬 = `fitCurveStations` → 길이 고정 R · 하한 → `buildEditedPolyline`)로 흉내.
* node helper_398_2_curve_input.cjs
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const B05 = path.join(ROOT, "B05_Profile");
const cache = new Map();
let handlers = null;
const shows = [];
const STUBS = {
@@ -23,23 +21,13 @@ const STUBS = {
"@ui/ui_template_elements": { showToast: () => {} }, // 곡선 삭제 경고(430)
};
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) =>
STUBS[request] ??
(request.startsWith(".")
? loadTs(path.join(path.dirname(full), `${request}.ts`))
: require(request));
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
// 곡선 판 가둠(505-3) — 판 크기 감시 · 가짜 그릇엔 판이 없어 빈 감시
globalThis.ResizeObserver = class {
observe() {}
disconnect() {}
};
const { loadTs } = makeLoader({ root: ROOT, stubs: STUBS });
const curve = loadTs(path.join(B05, "logic", "B05_Profile_UI_RouteEdit_Curve.ts"));
const edits = loadTs(path.join(B05, "logic", "B05_Profile_UI_RouteEdit_Edits.ts"));
@@ -101,7 +89,12 @@ function editor(snap) {
status.textContent = `예상노선 — ${message} 꼬리`;
};
made = bar.createCurveBar({
canvas: { getBoundingClientRect: () => ({ left: 0, top: 0, right: 800, bottom: 600 }) },
canvas: {
getBoundingClientRect: () => ({ left: 0, top: 0, right: 800, bottom: 600 }),
closest: () => null,
parentElement: null,
isConnected: true,
},
container: { querySelector: (sel) => (sel === ".b05-routeedit__status" ? status : null) },
state: () => state,
toScreen: (v) => [v[0], v[1]],
@@ -3,13 +3,11 @@
* 같은 길(스냅 켬 = `fitStart` → `fitCurveStations` → 길이 고정 R · 하한 → `buildEditedPolyline`)로 흉내.
* node helper_408_radius_downstream.cjs
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const B05 = path.join(ROOT, "B05_Profile");
const cache = new Map();
let handlers = null;
const STUBS = {
"./B05_Profile_UI_RouteEdit_Label": {
@@ -22,23 +20,13 @@ const STUBS = {
"@ui/ui_template_elements": { showToast: () => {} }, // 곡선 삭제 경고(430)
};
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) =>
STUBS[request] ??
(request.startsWith(".")
? loadTs(path.join(path.dirname(full), `${request}.ts`))
: require(request));
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
// 곡선 판 가둠(505-3) — 판 크기 감시 · 가짜 그릇엔 판이 없어 빈 감시
globalThis.ResizeObserver = class {
observe() {}
disconnect() {}
};
const { loadTs } = makeLoader({ root: ROOT, stubs: STUBS });
const curve = loadTs(path.join(B05, "logic", "B05_Profile_UI_RouteEdit_Curve.ts"));
const edits = loadTs(path.join(B05, "logic", "B05_Profile_UI_RouteEdit_Edits.ts"));
@@ -108,7 +96,12 @@ function editor(snap, apexLock = []) {
committed = copy(state);
};
bar.createCurveBar({
canvas: { getBoundingClientRect: () => ({ left: 0, top: 0, right: 800, bottom: 600 }) },
canvas: {
getBoundingClientRect: () => ({ left: 0, top: 0, right: 800, bottom: 600 }),
closest: () => null,
parentElement: null,
isConnected: true,
},
container: { querySelector: (sel) => (sel === ".b05-routeedit__status" ? status : null) },
state: () => state,
toScreen: (v) => [v[0], v[1]],
+3 -28
View File
@@ -3,19 +3,12 @@
*
* ⚠ 확장자가 `.cjs` 인 까닭은 `helper_b05_structures_form_summary.cjs` 머리와 같다.
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const { makeLoader, memoryStorage } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
const session = new Map();
const fakeStorage = {
getItem: (k) => session.get(k) ?? null,
setItem: (k, v) => session.set(k, String(v)),
removeItem: (k) => session.delete(k),
};
const fakeStorage = memoryStorage();
globalThis.window = { sessionStorage: fakeStorage, localStorage: fakeStorage };
globalThis.sessionStorage = fakeStorage;
globalThis.localStorage = fakeStorage;
@@ -24,25 +17,7 @@ const STUBS = {
"@config/config_frontend": { API_BASE_URL: "/api", API_TIMEOUT_MS: 1000 },
};
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.endsWith(".json")) return require(path.join(path.dirname(full), request));
if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`));
if (request.startsWith("@")) return new Proxy({}, { get: () => () => {} });
return require(request);
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
const { loadTs } = makeLoader({ root: ROOT, stubs: STUBS });
const marks = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_Structures_Marks.ts"));
+1 -3
View File
@@ -42,13 +42,11 @@ def test_after_save_cards_show_server_new_detail(out: dict) -> None:
def test_no_redraw_from_stale_cache_while_saving(out: dict) -> None:
assert out["savingSeen"] == [True, False] and out["savingIdle"] is False
# 저장 도중 신호는 건너뜀 · 뒤처리가 새로 한 번 받음(오버레이 안)
# 저장 도중 신호는 건너뜀 · 뒤처리가 새로 한 번 받음 · 노선 그대로 [저장] = 가림막 없음(498-3 D1)
assert out["calls"] == [
"overlay:on",
"refresh:skip",
"cross:save",
"fetch:새 자리 4+8 · 47+0",
"overlay:off",
]
+2 -2
View File
@@ -53,7 +53,7 @@ def node() -> dict:
def test_별칭_검사(node):
assert node["commands"] == 153
assert node["commands"] == 154 # 488-3 IMPORT 더함
assert node["parse"] == [["LL", "CC", "X1"], [], []]
assert node["ok"] == {} # 남의 기본 별칭(C = CIRCLE)을 내 것으로 덮는 건 됨(acad.pgp 식)
assert node["chars"] == {"LINE": "chars", "CIRCLE": "chars"}
@@ -140,7 +140,7 @@ def test_설정_창_탭_저장_물음():
page.click("[data-settings-tab=cad]")
assert _visible_panel_has(page, "input[data-cad-command]")
assert not _visible_panel_has(page, "input[type=radio]")
assert page.locator(".app-settings input[data-cad-command]").count() == 153
assert page.locator(".app-settings input[data-cad-command]").count() == 154
page.click("[data-settings-tab=keys]")
assert (
page.evaluate(