83 lines
2.5 KiB
TypeScript
83 lines
2.5 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import type { Bug } from './bug';
|
|
import { calcXiaobaoVersionRisk } from './xiaobao-risk';
|
|
import { buildRiskSignature, summarizeRiskTrend } from './xiaobao-risk-trend';
|
|
import type { XiaobaoRiskSnapshot } from './xiaobao-risk-trend';
|
|
|
|
function snapshot(patch: Partial<XiaobaoRiskSnapshot>): XiaobaoRiskSnapshot {
|
|
return {
|
|
versionId: 'ver-1',
|
|
date: '2026-06-27',
|
|
riskScore: 38,
|
|
riskLevel: 'attention',
|
|
openBugCount: 0,
|
|
failedTestCount: 0,
|
|
blockedCount: 0,
|
|
silentRiskCount: 0,
|
|
confidence: 80,
|
|
createdAt: '2026-06-27T01:00:00.000Z',
|
|
...patch,
|
|
};
|
|
}
|
|
|
|
test('summarizeRiskTrend detects continuous rising risk across three snapshots', () => {
|
|
const trend = summarizeRiskTrend([
|
|
snapshot({ riskScore: 71, createdAt: '2026-06-29T01:00:00.000Z', date: '2026-06-29' }),
|
|
snapshot({ riskScore: 38, createdAt: '2026-06-27T01:00:00.000Z', date: '2026-06-27' }),
|
|
snapshot({ riskScore: 52, createdAt: '2026-06-28T01:00:00.000Z', date: '2026-06-28' }),
|
|
]);
|
|
|
|
assert.equal(trend.direction, 'up');
|
|
assert.equal(trend.delta, 33);
|
|
assert.equal(trend.pattern, 'continuous_rising');
|
|
});
|
|
|
|
test('buildRiskSignature changes when score and bug counts change', () => {
|
|
const base = buildRiskSignature(snapshot({ riskScore: 52, openBugCount: 1 }));
|
|
const changed = buildRiskSignature(snapshot({ riskScore: 71, openBugCount: 2 }));
|
|
|
|
assert.notEqual(base, changed);
|
|
});
|
|
|
|
test('calcXiaobaoVersionRisk uses all open bugs in the current trend snapshot signature', () => {
|
|
const now = new Date('2026-07-02T01:00:00.000Z');
|
|
const risk = calcXiaobaoVersionRisk({
|
|
version: {
|
|
id: 'ver-1',
|
|
name: 'V1.0',
|
|
expectedReleaseDate: '2026-07-03T10:00:00.000Z',
|
|
members: [{ name: 'Alice' }],
|
|
},
|
|
devTasks: [],
|
|
testCases: [],
|
|
bugs: [bug({ severity: 'major', priority: 'P2' })],
|
|
now,
|
|
});
|
|
|
|
assert.equal(risk.signals.openBugCount, 1);
|
|
assert.equal(risk.signals.criticalBugCount, 0);
|
|
assert.equal(risk.currentSnapshot.openBugCount, 1);
|
|
assert.equal(buildRiskSignature(risk.currentSnapshot).split('|')[5], '1');
|
|
});
|
|
|
|
function bug(patch: Partial<Bug> = {}): Bug {
|
|
return {
|
|
id: 'bug-1',
|
|
bugNo: 'BUG-001',
|
|
versionId: 'ver-1',
|
|
testCaseId: 'tc-1',
|
|
title: 'Non-critical open bug',
|
|
description: 'Open but not critical.',
|
|
severity: 'major',
|
|
priority: 'P2',
|
|
reportedBy: 'qa-1',
|
|
assigneeId: 'dev-1',
|
|
status: 'open',
|
|
createdAt: '2026-07-01T09:00:00.000Z',
|
|
updatedAt: '2026-07-01T09:00:00.000Z',
|
|
...patch,
|
|
};
|
|
}
|