import assert from 'node:assert/strict' import { readFile } from 'node:fs/promises' import { fileURLToPath } from 'node:url' import path from 'node:path' const scriptDir = path.dirname(fileURLToPath(import.meta.url)) const sourceRoot = path.resolve(scriptDir, '../src') const [routerSource, listSource, detailSource, apiSource, mockSource] = await Promise.all([ readFile(path.join(sourceRoot, 'router/index.ts'), 'utf8'), readFile(path.join(sourceRoot, 'views/eval/EvalView.vue'), 'utf8'), readFile(path.join(sourceRoot, 'views/eval/EvalDetailView.vue'), 'utf8'), readFile(path.join(sourceRoot, 'api/modules/eval.ts'), 'utf8'), readFile(path.join(sourceRoot, 'mock/adapter.ts'), 'utf8'), ]) function extractRouteBlock(source, routePath) { const pathPattern = new RegExp(`path:\\s*['"]${routePath.replaceAll('/', '\\/')}['"]`) const pathIndex = source.search(pathPattern) assert.notEqual(pathIndex, -1, `未找到路由 ${routePath}`) const openBrace = source.lastIndexOf('{', pathIndex) assert.notEqual(openBrace, -1, `路由 ${routePath} 缺少左花括号`) let depth = 0 for (let index = openBrace; index < source.length; index += 1) { if (source[index] === '{') depth += 1 if (source[index] === '}') depth -= 1 if (depth === 0) return source.slice(openBrace + 1, index) } assert.fail(`路由 ${routePath} 缺少右花括号`) } const detailRoute = extractRouteBlock(routerSource, 'model-eval/:id') assert.match(detailRoute, /name:\s*['"]model-eval-detail['"]/, '评测详情路由名称不正确') assert.match( detailRoute, /component:\s*\(\)\s*=>\s*import\(['"]@\/views\/eval\/EvalDetailView\.vue['"]\)/, '评测详情路由未加载 EvalDetailView.vue', ) assert.match( listSource, /router\.push\(\s*\{\s*name:\s*['"]model-eval-detail['"]\s*,\s*params:\s*\{\s*id:\s*row\.id\s*\}\s*\}\s*\)/, '评测任务详情按钮必须使用命名路由并携带任务 id', ) assert.doesNotMatch(listSource, /详情功能开发中/, '评测任务详情入口仍是占位提示') assert.match(apiSource, /export\s+const\s+getEvalDetail\b/, '评测 API 缺少 getEvalDetail') assert.match( apiSource, /get(?:<[^>]+>)?\(`\/model-eval\/\$\{id\}`\)/, 'getEvalDetail 未请求 GET /model-eval/:id', ) assert.ok( mockSource.includes('/^\\/model-eval\\/([^/]+)$/'), 'Mock 未按任务 id 匹配 /model-eval/:id', ) assert.match(mockSource, /method\s*===\s*['"]get['"]/, '评测详情 Mock 未处理 GET 请求') for (const className of [ 'overall-review', 'score-hero', 'improvement-list', 'sample-results-table', 'dimension-summary', ]) { assert.match( detailSource, new RegExp(`class=["'][^"']*\\b${className}\\b`), `评测详情页缺少 .${className} 结构`, ) } for (const label of ['输入', '标准答案', '模型回答', '得分', '判定']) { assert.match( detailSource, new RegExp(`(?:label=["'][^"']*${label}[^"']*["']|>${label}<)`), `样本结果列表缺少“${label}”语义`, ) } assert.match(detailSource, /\bloading\b/, '评测详情页缺少加载状态') assert.match(detailSource, /\berror\b/, '评测详情页缺少错误状态') assert.match( detailSource, /(?:el-empty|empty-text|样本结果为空|暂无样本|暂无数据)/, '评测详情页缺少空状态', ) assert.match(detailSource, /