/* 280-6 드롭다운 초점 빼기(`ui_template/ui_template_native_menu.ts` `releaseSelectAfterPick`) 단위검증 헬퍼 — * 그 자리에서 트랜스파일해 Node 로 돌리고 값을 JSON 으로 냄. 가짜 창 · 가짜 select · 가짜 타이머로 판정. */ const fs = require("fs"); const path = require("path"); const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); const ROOT = path.join(__dirname, "..", ".."); const js = ts.transpileModule( fs.readFileSync(path.join(ROOT, "ui_template", "ui_template_native_menu.ts"), "utf8"), { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 } }, ).outputText; const box = { exports: {} }; new Function("exports", "module", "require", js)(box.exports, box, require); const m = box.exports; // 가짜 창 — 캡처 듣기 · 타이머(손으로 돌림) · 문서 하나 function setup() { const listeners = []; const timers = []; const doc = { activeElement: null }; const win = { addEventListener: (type, fn, capture) => listeners.push({ type, fn, capture }), setTimeout: (fn) => timers.push(fn), }; m.releaseSelectAfterPick(win); const el = (tagName) => { const node = { tagName, ownerDocument: doc, blurs: 0 }; node.blur = () => { node.blurs += 1; doc.activeElement = null; }; return node; }; const fire = (type, target) => listeners.filter((l) => l.type === type).forEach((l) => l.fn({ type, target })); const tick = () => timers.splice(0).forEach((fn) => fn()); return { listeners, doc, el, fire, tick }; } // 차례 하나 — 초점을 select 에 두고 입력들을 쏜 뒤 change · (처리) · 한 틱 function run(inputs, tag = "SELECT", moveFocus = false) { const t = setup(); const target = t.el(tag); t.doc.activeElement = target; inputs.forEach((type) => t.fire(type, target)); t.fire("change", target); const before = target.blurs; // 한 틱 전엔 안 뺌 if (moveFocus) t.doc.activeElement = t.el("INPUT"); t.tick(); return { before, blurs: target.blurs }; } const src = (rel) => fs.readFileSync(path.join(ROOT, rel), "utf8"); const setupOnce = setup(); console.log( JSON.stringify({ mouse: run(["pointerdown"]), keyboard: run(["keydown"]), none: run([]), input: run(["pointerdown"], "INPUT"), moved: run(["pointerdown"], "SELECT", true), mouseThenKey: run(["pointerdown", "keydown"]), keyThenMouse: run(["keydown", "pointerdown"]), listeners: setupOnce.listeners.map((l) => [l.type, l.capture]), wiring: { main: /releaseSelectAfterPick\(window\)/.test(src("A00_Common/main.ts")), cad: /releaseSelectAfterPick\(frame\.contentWindow\)/.test( src("ui_template/cad_host/cad_host.ts"), ), popout: /releaseSelectAfterPick\(next\)/.test( src("A00_Common/design/design_profile_popout.ts"), ), }, }), );