Files
L2keka/server/src/__tests__/code-quality.test.ts
T
hangshuo652 1b89743d77 评审真实性增强:前端硬规则+人工启动方案+文档-实现三级校验
- 前端存在性硬规则:detectFrontend 源码级判定,web形态无真实前端/不可访问 → 实现完整度封顶50%(CLI/插件豁免)
- verify 多态:build_status 支持 done/failed/done_no_ui,前端按钮新增「无前端」
- 人工启动方案:评审环境自动启动失败 → awaiting_browse 暂停,评委手动启动后填 service_url 走 /verify-browse 恢复(SSRF 信任评委确认地址)
- Gitea 稳定性:clone 自动重试×3(525抖动)+ 每队独立 token 回退(全局账号失效兜底)
- A 阶段报告备份:feature_inventory.__stageA_report 防 B 阶段维度重复累积/A维度丢失
- tryTest 依赖预装:Python 项目自动 pip install(测试不再因缺依赖误判失败)
- 运行验证压缩静态维度:前端缺失+测试失败 → 静态纸面维度封顶50%(防原型拿高分)
- 文档-实现三级校验:claim-consistency 注入运行时证据(构建/测试/前端),识别「代码有但跑不起来」的虚报(逸飞冲天 61%→25%)
- 赛事文档:中期20%+最终80%(AI=人工总分)、评审表/评审规则/赛事说明/07设计同步
- 清空 review_snapshots 测试污染数据,保留当前正式分(零号158/逸飞冲天126)
- 测试 446 全通过(后端435+前端11)
2026-09-01 08:44:56 +08:00

102 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect } from 'vitest';
import { computeCodeQuality } from '../services/code-quality';
const mk = (path: string, content: string) => ({ path, content });
describe('TC-QUALITY · 代码质量确定性评估(2026-08-27', () => {
it('真实实现(大量逻辑、无占位)→ 质量分高', () => {
const files = [
mk('src/core.py', [
'def process(data):',
' result = []',
' for item in data:',
' if item["ok"]:',
' result.append(item["value"] * 2)',
' else:',
' result.append(0)',
' return result',
'',
'def analyze(x):',
' return {"count": len(x), "total": sum(x)}',
].join('\n')),
mk('tests/test_core.py', [
'def test_process():',
' assert process([{"ok": True, "value": 3}]) == [6]',
'def test_analyze():',
' assert analyze([1,2,3]) == {"count": 3, "total": 6}',
].join('\n')),
];
const r = computeCodeQuality(files);
expect(r.applicable).toBe(true);
expect(r.stubRatio).toBe(0); // 无空壳
expect(r.qualityScore).toBeGreaterThanOrEqual(60);
expect(r.testValidityRatio).toBe(0.5); // 2断言/2测试函数 = 0.5
});
it('空壳函数多(pass/占位)→ 空壳率升高、质量分低', () => {
const files = [
mk('src/core.py', [
'def a():',
' pass',
'def b():',
' pass',
'def c():',
' pass',
'def real():',
' return 42',
].join('\n')),
];
const r = computeCodeQuality(files);
expect(r.applicable).toBe(true);
expect(r.stubRatio).toBeGreaterThan(0.5); // 3/4 空壳
expect(r.qualityScore).toBeLessThan(40);
});
it('重复代码多 → 重复率升高', () => {
const dupBlock = [
' result = []',
' for item in items:',
' if item["ok"] and item["val"] > threshold:',
' result.append(item["val"] * 2 + offset - tax_rate)',
' else:',
' result.append(0)',
' return result',
].join('\n');
const files = [];
for (let i = 0; i < 5; i++) {
files.push(mk(`src/mod${i}.py`, `def f${i}(items, offset, tax_rate, threshold):\n${dupBlock}\n`));
}
const r = computeCodeQuality(files);
expect(r.applicable).toBe(true);
expect(r.dupRatio).toBeGreaterThan(0.5);
});
it('测试只测边角料(无断言)→ 测试有效度低', () => {
const files = [
mk('src/core.py', 'def real(x):\n return x * 2\n'),
mk('tests/test_core.py', [
'def test_placeholder():',
' pass',
'def test_other():',
' return',
].join('\n')),
];
const r = computeCodeQuality(files);
expect(r.applicable).toBe(true);
expect(r.testValidityRatio).toBe(0); // 无断言
});
it('无源码文件 → 不适用', () => {
const r = computeCodeQuality([mk('README.md', '# doc')]);
expect(r.applicable).toBe(false);
});
it('toPrompt 含三项指标', () => {
const r = computeCodeQuality([mk('src/a.py', 'def x():\n return 1\n')]);
expect(r.toPrompt).toContain('空壳率');
expect(r.toPrompt).toContain('重复率');
expect(r.toPrompt).toContain('测试有效度');
expect(r.toPrompt).toContain('确定性证据');
});
});