import test from 'node:test' import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import { fileURLToPath } from 'node:url' import { dirname, resolve } from 'node:path' const currentDir = dirname(fileURLToPath(import.meta.url)) const srcDir = resolve(currentDir, '..') function readSource(path) { return readFileSync(resolve(srcDir, path), 'utf8') } test('code analysis route and project list entry are wired', () => { const router = readSource('router/index.js') const projectList = readSource('views/ProjectListView.vue') assert.match(router, /path: '\/project\/:projectId\/code-analysis'/) assert.match(router, /name: 'code-analysis'/) assert.match(projectList, /content="代码解读"/) assert.match(projectList, /router\.push\(`\/project\/\$\{projectId\}\/code-analysis`\)/) }) test('code analysis api uses dedicated project endpoints', () => { const api = readSource('api/project.js') assert.match(api, /export function createCodeAnalysisTask/) assert.match(api, /url: `\/front\/project\/\$\{projectId\}\/code-analysis`/) assert.match(api, /export function listCodeAnalysisHistory/) assert.match(api, /url: `\/front\/project\/\$\{projectId\}\/code-analysis\/history`/) assert.match(api, /export function continueCodeAnalysisTask/) assert.match(api, /\/code-analysis\/\$\{generationId\}\/continue/) assert.match(api, /export async function streamCodeAnalysis/) assert.match(api, /\/front\/project\/\$\{projectId\}\/code-analysis\/stream/) assert.match(api, /export async function streamContinueCodeAnalysis/) assert.match(api, /\/front\/project\/\$\{projectId\}\/code-analysis\/\$\{generationId\}\/continue\/stream/) }) test('code analysis view supports history, stream generation, polling fallback, and exports', () => { const source = readSource('views/CodeAnalysisView.vue') assert.match(source, /listCodeAnalysisHistory/) assert.match(source, /streamCodeAnalysis/) assert.match(source, /streamContinueCodeAnalysis/) assert.match(source, /AbortController/) assert.match(source, /getAiTask/) assert.match(source, /setInterval\(refreshActiveTask,\s*1800\)/) assert.match(source, /selectedGenerationId/) assert.match(source, /downloadMarkdown/) assert.match(source, /downloadWordDoc/) assert.match(source, /reportMarkdown/) }) test('code analysis continue sends the current edited report', () => { const source = readSource('views/CodeAnalysisView.vue') assert.match(source, /previousMarkdown:\s*reportMarkdown\.value/) assert.match(source, /streamContinueCodeAnalysis\(projectId\.value,\s*selectedGenerationId\.value/) }) test('code analysis entry stays centralized in the project list', () => { const projectList = readSource('views/ProjectListView.vue') const preview = readSource('views/PreviewView.vue') const generate = readSource('views/GenerateView.vue') assert.match(projectList, /代码解读/) assert.match(projectList, /openCodeAnalysis/) assert.doesNotMatch(preview, /openCodeAnalysis/) assert.doesNotMatch(generate, /openCodeAnalysis/) })