1. 新增测试门禁脚本test-gate.js,统一管理tests目录下的测试用例执行 2. 在package.json中添加test、test:util、prebuild、prestart脚本,将测试环节前置到构建和启动流程 3. 重构normalizeUrl函数,新增更严格的URL规范化逻辑并补充完整注释 4. 优化代码格式,修正多处对象字面量的空格排版 5. 新增util.js的单元测试文件,覆盖核心工具函数的测试场景
86 lines
2.4 KiB
JavaScript
86 lines
2.4 KiB
JavaScript
/**
|
|
* 测试门禁:扫描 tests/ 下所有 *.test.js,全部通过才能正常返回 0
|
|
*
|
|
* 用法:
|
|
* node scripts/test-gate.js
|
|
* 或: npm test
|
|
*
|
|
* 工作机制:
|
|
* 1) 扫描 tests/ 目录,找到所有 *.test.js 文件
|
|
* 2) 用 node --test 跑每个文件,任一文件非 0 退出则整体失败
|
|
* 3) 输出汇总:总数 / 通过 / 失败 / 失败的文件列表
|
|
*
|
|
* 兼容性:
|
|
* node 18+ 自带 test runner(--test)。低于 18 会给出明确错误并退出非 0。
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const { spawnSync } = require('node:child_process');
|
|
|
|
const ROOT = path.resolve(__dirname, '..');
|
|
const TESTS_DIR = path.join(ROOT, 'tests');
|
|
|
|
function listTestFiles(dir) {
|
|
if (!fs.existsSync(dir)) return [];
|
|
return fs.readdirSync(dir)
|
|
.filter(function (f) { return f.endsWith('.test.js'); })
|
|
.map(function (f) { return path.join(dir, f); })
|
|
.sort();
|
|
}
|
|
|
|
function checkNodeVersion() {
|
|
const major = Number(process.versions.node.split('.')[0]);
|
|
if (major < 18) {
|
|
console.error('[test-gate] 需要 node 18+(自带 --test),当前 node 版本:', process.version);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
function runTestFile(testFile) {
|
|
console.log('\n[test-gate] === 运行测试文件:', path.relative(ROOT, testFile), '===');
|
|
const result = spawnSync(
|
|
process.execPath,
|
|
['--test', testFile],
|
|
{ stdio: 'inherit', cwd: ROOT },
|
|
);
|
|
return {
|
|
file: path.relative(ROOT, testFile),
|
|
ok: result.status === 0,
|
|
status: result.status,
|
|
};
|
|
}
|
|
|
|
function main() {
|
|
checkNodeVersion();
|
|
const files = listTestFiles(TESTS_DIR);
|
|
if (files.length === 0) {
|
|
console.error('[test-gate] tests/ 下没有任何 *.test.js 文件');
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log('[test-gate] 找到', files.length, '个测试文件');
|
|
const results = files.map(runTestFile);
|
|
|
|
const failed = results.filter(function (r) { return !r.ok; });
|
|
|
|
console.log('\n[test-gate] =============== 汇总 ===============');
|
|
console.log(' 总数:', results.length);
|
|
console.log(' 通过:', results.length - failed.length);
|
|
console.log(' 失败:', failed.length);
|
|
if (failed.length > 0) {
|
|
console.log(' 失败文件:');
|
|
failed.forEach(function (r) {
|
|
console.log(' -', r.file, '(退出码', r.status + ')');
|
|
});
|
|
console.log('\n[test-gate] ❌ 测试未全部通过,不允许继续');
|
|
process.exit(1);
|
|
}
|
|
console.log('\n[test-gate] ✅ 全部测试通过');
|
|
process.exit(0);
|
|
}
|
|
|
|
main();
|