feat(版本详情): 完善流程日志与需求覆盖
This commit is contained in:
@@ -23,6 +23,7 @@ export interface TestCase {
|
||||
estimateHours?: number;
|
||||
aiEstimateHours?: number;
|
||||
plannedTestAt?: string;
|
||||
plannedEndAt?: string;
|
||||
startedAt?: string;
|
||||
completedAt?: string;
|
||||
executedAt?: string;
|
||||
@@ -98,6 +99,7 @@ export function normalizeTestCase(testCase: Partial<TestCase>, index = 0): TestC
|
||||
estimateHours: typeof testCase.estimateHours === 'number' && testCase.estimateHours > 0 ? testCase.estimateHours : undefined,
|
||||
aiEstimateHours: typeof testCase.aiEstimateHours === 'number' && testCase.aiEstimateHours > 0 ? testCase.aiEstimateHours : undefined,
|
||||
plannedTestAt: testCase.plannedTestAt,
|
||||
plannedEndAt: testCase.plannedEndAt,
|
||||
startedAt: testCase.startedAt,
|
||||
completedAt: testCase.completedAt,
|
||||
executedAt: testCase.executedAt,
|
||||
@@ -172,6 +174,7 @@ export function copyTestCaseToRound(source: TestCase, roundNo: number, createdBy
|
||||
estimateHours: source.estimateHours,
|
||||
aiEstimateHours: source.aiEstimateHours,
|
||||
plannedTestAt: source.plannedTestAt,
|
||||
plannedEndAt: source.plannedEndAt,
|
||||
assigneeId: source.assigneeId,
|
||||
startedAt: undefined,
|
||||
completedAt: undefined,
|
||||
@@ -224,6 +227,23 @@ export function getTestCaseEstimateHours(tc: TestCase): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
export function needsTestCaseClaim(testCase: Pick<TestCase, 'assigneeId'>): boolean {
|
||||
return !testCase.assigneeId?.trim();
|
||||
}
|
||||
|
||||
export function hasTestCasePlan(testCase: Pick<TestCase, 'plannedTestAt' | 'plannedEndAt'>): boolean {
|
||||
if (!testCase.plannedTestAt || !testCase.plannedEndAt) return false;
|
||||
const start = new Date(testCase.plannedTestAt).getTime();
|
||||
const end = new Date(testCase.plannedEndAt).getTime();
|
||||
return Number.isFinite(start) && Number.isFinite(end) && end > start;
|
||||
}
|
||||
|
||||
export function canStartTestCase(
|
||||
testCase: Pick<TestCase, 'assigneeId' | 'plannedTestAt' | 'plannedEndAt'>,
|
||||
): boolean {
|
||||
return !needsTestCaseClaim(testCase) && hasTestCasePlan(testCase);
|
||||
}
|
||||
|
||||
export function getTestCaseActualHours(tc: TestCase, now: Date = new Date()): number {
|
||||
if (!tc.startedAt) return 0;
|
||||
const isTerminal = tc.status === 'passed' || tc.status === 'failed' || tc.status === 'blocked';
|
||||
|
||||
Reference in New Issue
Block a user