feat: add src/trace.ts
This commit is contained in:
27
src/trace.ts
Normal file
27
src/trace.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import type { CaseResult, Requirement, TraceReport } from './model';
|
||||||
|
import { evidenceState } from './evidence';
|
||||||
|
|
||||||
|
export function evaluateTrace(requirements: Requirement[], cases: CaseResult[], reviewDate: string): TraceReport {
|
||||||
|
const required = requirements.filter(item => item.mandatory);
|
||||||
|
const ids = new Set(required.map(item => item.id));
|
||||||
|
const usedCases = new Set<string>(), duplicateCases: string[] = [], orphanCases: string[] = [];
|
||||||
|
const links = new Map<string, CaseResult[]>();
|
||||||
|
for (const item of cases) {
|
||||||
|
if (usedCases.has(item.id)) { duplicateCases.push(item.id); continue; }
|
||||||
|
usedCases.add(item.id);
|
||||||
|
for (const id of item.requirementIds) {
|
||||||
|
if (!ids.has(id)) { orphanCases.push(item.id); continue; }
|
||||||
|
links.set(id, [...(links.get(id) ?? []), item]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const gaps = [];
|
||||||
|
for (const requirement of required) {
|
||||||
|
const related = links.get(requirement.id) ?? [];
|
||||||
|
if (related.length === 0) gaps.push({ requirementId: requirement.id, reason: '无验证用例' });
|
||||||
|
else if (!related.some(item => evidenceState(item, reviewDate) === null))
|
||||||
|
gaps.push({ requirementId: requirement.id, reason: related.map(item => evidenceState(item, reviewDate)).join('、') });
|
||||||
|
}
|
||||||
|
const covered = required.length - gaps.length;
|
||||||
|
return { covered, total: required.length, percent: required.length ? Math.round(covered * 100 / required.length) : 100,
|
||||||
|
gaps, orphanCases, duplicateCases };
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user