import test from 'node:test'; import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { join } from 'node:path'; import { renderOverview, validateOverview } from '../scripts/overview-render.js'; import { repoRoot } from './helpers/run-script.js'; const base = { schemaVersion: 1, source: { requirement: { repo: 'owner/repo', index: 7 } }, requirement: { title: '建立需求總覽', summary: '把複雜需求整理成可理解的交接資料。', goals: ['可追蹤工作包', '可離線檢視'], nonGoals: [], diagrams: [{ kind: 'flowchart', direction: 'LR', title: '輸入流程', nodes: [{ id: 'a', label: '輸入' }, { id: 'b', label: '輸出' }], edges: [{ from: 'a', to: 'b', label: '轉換' }] }], formulas: [{ title: '估算', latex: 'a+b', description: '簡單公式' }], }, workPackages: [{ title: '建立抽取契約', type: 'implementation', description: '提供可重複的資料抽取。', scope: '只處理抽取。', repos: ['owner/repo'], depends: [], todos: [{ text: '建立函式', done: true }], acceptance: ['輸出固定'], issue: 'https://gitea.example/owner/repo/issues/8', handoff: false, }], overview: { generatedAt: '2026-09-18T00:00:00Z' }, }; test('renderer validates and renders self-contained HTML', () => { const html = renderOverview(base); assert.match(html, //i); assert.match(html, / { assert.throws(() => validateOverview({ ...base, schemaVersion: 2 }), (error) => error.code === 'SCHEMA_UNSUPPORTED'); assert.throws(() => validateOverview({ ...base, requirement: { ...base.requirement, diagrams: [{ kind: 'unknown', nodes: [], edges: [] }] } }), (error) => error.code === 'DIAGRAM_UNSUPPORTED'); }); test('renderer script is shipped and template is intentionally removed', () => { assert.equal(readFileSync(join(repoRoot, 'scripts', 'overview-render.js'), 'utf8').includes('overview'), true); assert.throws(() => readFileSync(join(repoRoot, 'templates', 'overview-artifact.html'), 'utf8')); });