import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; import { test } from 'node:test'; import vm from 'node:vm'; import ts from 'typescript'; const source = await readFile(new URL('../src/main.ts', import.meta.url), 'utf8'); test('public failure guidance keeps technical details only in hidden diagnostics', () => { const status = {}, detail = {}; const code = source.match(/function setStatus\([^]*?\n\n/)[0]; const context = { status, experience: { setDetail(message) { detail.textContent = message; } } }; vm.createContext(context); vm.runInContext(ts.transpileModule(code, { compilerOptions: { target: ts.ScriptTarget.ES2020 } }).outputText, context); vm.runInContext("setStatus('WebGPU model failure', '사진을 준비하지 못했어요. 다시 시도해 주세요.')", context); assert.equal(status.textContent, 'WebGPU model failure'); assert.equal(detail.textContent, '사진을 준비하지 못했어요. 다시 시도해 주세요.'); vm.runInContext("setStatus('내비게이션으로 길을 찾는 중…')", context); assert.equal(detail.textContent, status.textContent); }); test('automatic journey starts in everyday language and failure has actionable public guidance', () => { const generate = source.slice(source.indexOf('async function generateAIDepth'), source.indexOf("aiDepthButton.addEventListener")); assert.ok(generate.includes("setStatus('출발 준비 중이에요. 처음에는 조금 더 걸릴 수 있어요.');")); assert.match(generate, /setStatus\(`사진 분석 실패: \$\{detail\}[^]*?'사진을 준비하지 못했어요\. 다시 시도하거나 다른 사진을 골라 주세요\. 평면 사진으로 볼 수도 있어요\.'\)/); assert.ok(generate.includes("experience.setState('error', true)")); });