73 lines
4.3 KiB
JavaScript
73 lines
4.3 KiB
JavaScript
#!/usr/bin/env node
|
|
import { readFile } from 'node:fs/promises'
|
|
import { resolve } from 'node:path'
|
|
import { pathToFileURL } from 'node:url'
|
|
import { describeAcceptanceScope } from './admin-test-env-acceptance.mjs'
|
|
|
|
/** 只输出白名单统计和模块名,不转抄报告中的账号、地址、凭据或业务载荷。 */
|
|
export function summarizeReport(report) {
|
|
if (!report || !Array.isArray(report.steps) || report.steps.length === 0
|
|
|| report.steps.some((step) => typeof step.passed !== 'boolean')) {
|
|
throw new Error('报告缺少有效 steps,不能认定验收结果')
|
|
}
|
|
const steps = report.steps
|
|
const failed = steps.filter((step) => !step.passed && !step.skipped)
|
|
const skipped = steps.filter((step) => step.skipped)
|
|
const skippedModules = Array.isArray(report.modules) ? report.modules.filter((module) => module.skipped).length : 0
|
|
const gaps = Array.isArray(report.coverageGaps) ? report.coverageGaps : []
|
|
const blockers = gaps.filter((gap) => gap.blocking || gap.deploymentBlocker)
|
|
const scope = report.executionScope
|
|
// 历史报告不包含计划信息,不能从断言数量或模块名字推定完整执行。
|
|
const scopeKnown = Array.isArray(scope?.plannedModules) && scope.plannedModules.length > 0
|
|
&& Array.isArray(scope.defaultModules) && scope.defaultModules.length > 0
|
|
const observedModules = new Set(steps.map((step) => step.module))
|
|
const missingModules = scopeKnown ? scope.plannedModules.filter((name) => !observedModules.has(name)) : []
|
|
const limited = Boolean(scope?.preparationOnly || scope?.returnMainChainOnly || report.fullAcceptance === false)
|
|
const failedResult = Boolean(report.fatal) || report.success === false || failed.length > 0 || blockers.length > 0
|
|
return {
|
|
result: failedResult ? 'FAILED' : skipped.length || skippedModules || gaps.length || missingModules.length || limited ? 'INCOMPLETE' : 'RECORDED_CHECKS_PASSED',
|
|
passed: steps.filter((step) => step.passed && !step.skipped).length,
|
|
failed: failed.length,
|
|
skipped: skipped.length,
|
|
skippedModules,
|
|
blockingGaps: blockers.length,
|
|
nonBlockingGaps: gaps.length - blockers.length,
|
|
failedModules: [...new Set(failed.map((step) => step.module).filter(Boolean))],
|
|
// 无请求的失败包含前置不足和模块退出,不能计作独立接口缺陷。
|
|
failuresWithRequest: failed.filter((step) => step.request).length,
|
|
failuresWithoutRequest: failed.filter((step) => !step.request).length,
|
|
scope: !scopeKnown ? 'UNKNOWN_LEGACY_REPORT' : limited ? 'LIMITED_SCOPE'
|
|
: scope.defaultModules.every((name) => scope.plannedModules.includes(name)) ? 'DEFAULT_ADMIN_PLAN' : 'SELECTED_MODULES',
|
|
missingPlannedModules: missingModules,
|
|
currentVersionVerified: false,
|
|
pageAcceptance: 'NOT_VERIFIED_BY_HTTP',
|
|
}
|
|
}
|
|
|
|
/** 默认仅展示范围;显式报告只读分析,不发现历史目录、不联网、不执行验收。 */
|
|
async function main(argv) {
|
|
if (argv.length && !(argv.length === 2 && argv[0] === '--report')) {
|
|
throw new Error('用法:node scripts/acceptance-overview.mjs [--report <明确JSON路径>]')
|
|
}
|
|
const scope = describeAcceptanceScope()
|
|
const result = {
|
|
purpose: '离线验收范围总览,不执行HTTP,不证明当前部署通过',
|
|
admin: { entry: 'scripts/admin-test-env-acceptance.mjs', ...scope },
|
|
otherEntries: [
|
|
{ entry: 'scripts/client-test-env-acceptance.mjs', scope: 'Client全量HTTP,独立执行' },
|
|
{ entry: 'scripts/client-phase2-test-env-acceptance.mjs', scope: '测量计费专项,不替代Client全量' },
|
|
{ entry: 'scripts/fleet-test-env-acceptance.mjs', scope: '车辆专项,不计入Admin默认全量' },
|
|
],
|
|
boundaries: ['可选模块不等于默认执行;其他专项入口详见scripts/README.md',
|
|
'本地合同、HTTP、页面与真机验收分别报告',
|
|
'报告通过只代表该次记录;需另核对源码、配置与实际部署版本',
|
|
'环境与凭据前置仍由实际入口校验;本工具不读取环境文件'],
|
|
}
|
|
if (argv.length) result.report = summarizeReport(JSON.parse(await readFile(resolve(argv[1]), 'utf8')))
|
|
console.log(JSON.stringify(result, null, 2))
|
|
}
|
|
|
|
if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) {
|
|
main(process.argv.slice(2)).catch((error) => { console.error(error.message); process.exitCode = 1 })
|
|
}
|