perf(web): 优化大数据量页面切换与聚合性能
This commit is contained in:
171
apps/web/lib/version-data-scope.test.ts
Normal file
171
apps/web/lib/version-data-scope.test.ts
Normal file
@@ -0,0 +1,171 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
|
||||
import { buildVersionDataScope, buildVersionDataScopeMap } from './version-data-scope';
|
||||
import type { Bug } from './bug';
|
||||
import type { DevTask } from './dev-task';
|
||||
import type { OvertimeRecord } from './overtime';
|
||||
import type { Requirement } from './requirement';
|
||||
import type { TestCase } from './test-case';
|
||||
import type { VersionPlan } from './version-plan';
|
||||
|
||||
function requirement(id: string, versionId: string | undefined): Requirement {
|
||||
return {
|
||||
id,
|
||||
code: id.toUpperCase(),
|
||||
title: `Requirement ${id}`,
|
||||
description: '',
|
||||
productId: 'product-1',
|
||||
projectId: 'project-1',
|
||||
versionId,
|
||||
sourceType: 'internal',
|
||||
sourceTarget: 'product',
|
||||
platforms: ['web'],
|
||||
typeId: 'type-1',
|
||||
status: 'planned',
|
||||
priority: 'P1',
|
||||
effort: 'M',
|
||||
creator: 'PM',
|
||||
createdAt: '2026-07-02T09:00:00.000Z',
|
||||
};
|
||||
}
|
||||
|
||||
function plan(id: string, versionId: string, type: VersionPlan['type']): VersionPlan {
|
||||
return {
|
||||
id,
|
||||
versionId,
|
||||
type,
|
||||
title: `Plan ${id}`,
|
||||
owner: 'PM',
|
||||
startTime: '2026-07-02T09:00:00.000Z',
|
||||
endTime: '2026-07-02T18:00:00.000Z',
|
||||
status: 'pending',
|
||||
createdAt: '2026-07-02T09:00:00.000Z',
|
||||
addedBy: 'PM',
|
||||
};
|
||||
}
|
||||
|
||||
function devTask(id: string, patch: Partial<DevTask>): DevTask {
|
||||
return {
|
||||
id,
|
||||
taskNo: id.toUpperCase(),
|
||||
versionId: undefined,
|
||||
requirementId: '',
|
||||
title: `Task ${id}`,
|
||||
categoryId: 'frontend',
|
||||
assigneeId: 'Alice',
|
||||
priority: 'P1',
|
||||
expectedStartAt: '',
|
||||
expectedEndAt: '',
|
||||
status: 'todo',
|
||||
isBlocked: false,
|
||||
createdBy: 'PM',
|
||||
createdAt: '2026-07-02T09:00:00.000Z',
|
||||
updatedAt: '2026-07-02T09:00:00.000Z',
|
||||
...patch,
|
||||
};
|
||||
}
|
||||
|
||||
function testCase(id: string, versionId: string): TestCase {
|
||||
return {
|
||||
id,
|
||||
caseNo: id.toUpperCase(),
|
||||
versionId,
|
||||
title: `Case ${id}`,
|
||||
categoryId: 'testing',
|
||||
priority: 'P1',
|
||||
status: 'pending',
|
||||
createdBy: 'QA',
|
||||
createdAt: '2026-07-02T09:00:00.000Z',
|
||||
updatedAt: '2026-07-02T09:00:00.000Z',
|
||||
};
|
||||
}
|
||||
|
||||
function bug(id: string, versionId: string): Bug {
|
||||
return {
|
||||
id,
|
||||
bugNo: id.toUpperCase(),
|
||||
versionId,
|
||||
testCaseId: 'tc-1',
|
||||
title: `Bug ${id}`,
|
||||
description: '',
|
||||
severity: 'major',
|
||||
priority: 'P1',
|
||||
reportedBy: 'QA',
|
||||
assigneeId: 'Bob',
|
||||
status: 'open',
|
||||
createdAt: '2026-07-02T09:00:00.000Z',
|
||||
updatedAt: '2026-07-02T09:00:00.000Z',
|
||||
};
|
||||
}
|
||||
|
||||
function overtime(id: string, versionId: string): OvertimeRecord {
|
||||
return {
|
||||
id,
|
||||
projectId: 'project-1',
|
||||
versionId,
|
||||
person: 'Alice',
|
||||
startTime: '2026-07-02T19:00:00.000Z',
|
||||
endTime: '2026-07-02T21:00:00.000Z',
|
||||
duration: 2,
|
||||
reasonId: 'reason-4',
|
||||
createdAt: '2026-07-02T21:00:00.000Z',
|
||||
};
|
||||
}
|
||||
|
||||
test('buildVersionDataScope scopes version detail data once', () => {
|
||||
const scope = buildVersionDataScope({
|
||||
versionId: 'version-1',
|
||||
requirements: [requirement('req-1', 'version-1'), requirement('req-2', 'version-2')],
|
||||
plans: [plan('plan-1', 'version-1', 'research'), plan('plan-2', 'version-1', 'product'), plan('plan-3', 'version-2', 'ui')],
|
||||
devTasks: [
|
||||
devTask('dev-direct', { versionId: 'version-1', requirementId: '' }),
|
||||
devTask('dev-legacy', { requirementId: 'req-1' }),
|
||||
devTask('dev-other', { versionId: 'version-2', requirementId: 'req-2' }),
|
||||
],
|
||||
testCases: [testCase('tc-1', 'version-1'), testCase('tc-2', 'version-2')],
|
||||
bugs: [bug('bug-1', 'version-1'), bug('bug-2', 'version-2')],
|
||||
overtimeRecords: [overtime('ot-1', 'version-1'), overtime('ot-2', 'version-2')],
|
||||
});
|
||||
|
||||
assert.deepEqual(scope.requirementIds, ['req-1']);
|
||||
assert.deepEqual(scope.plans.map((item) => item.id), ['plan-1', 'plan-2']);
|
||||
assert.deepEqual(scope.plansByType.research.map((item) => item.id), ['plan-1']);
|
||||
assert.deepEqual(scope.plansByType.product.map((item) => item.id), ['plan-2']);
|
||||
assert.deepEqual(scope.devTasks.map((item) => item.id), ['dev-direct', 'dev-legacy']);
|
||||
assert.deepEqual(scope.testCases.map((item) => item.id), ['tc-1']);
|
||||
assert.deepEqual(scope.bugs.map((item) => item.id), ['bug-1']);
|
||||
assert.deepEqual(scope.overtimeRecords.map((item) => item.id), ['ot-1']);
|
||||
});
|
||||
|
||||
test('buildVersionDataScopeMap indexes many versions in one pass', () => {
|
||||
const scopeMap = buildVersionDataScopeMap({
|
||||
versionIds: ['version-1', 'version-2', 'version-empty'],
|
||||
requirements: [
|
||||
requirement('req-1', 'version-1'),
|
||||
requirement('req-2', 'version-2'),
|
||||
requirement('req-outside', 'version-3'),
|
||||
],
|
||||
plans: [
|
||||
plan('plan-1', 'version-1', 'research'),
|
||||
plan('plan-2', 'version-2', 'ui'),
|
||||
plan('plan-outside', 'version-3', 'product'),
|
||||
],
|
||||
devTasks: [
|
||||
devTask('dev-direct', { versionId: 'version-2', requirementId: 'req-1' }),
|
||||
devTask('dev-legacy', { requirementId: 'req-1' }),
|
||||
devTask('dev-outside', { requirementId: 'req-outside' }),
|
||||
],
|
||||
testCases: [testCase('tc-1', 'version-1'), testCase('tc-2', 'version-2'), testCase('tc-outside', 'version-3')],
|
||||
bugs: [bug('bug-1', 'version-1'), bug('bug-2', 'version-2'), bug('bug-outside', 'version-3')],
|
||||
overtimeRecords: [overtime('ot-1', 'version-1'), overtime('ot-2', 'version-2'), overtime('ot-outside', 'version-3')],
|
||||
});
|
||||
|
||||
assert.deepEqual(scopeMap['version-1'].requirements.map((item) => item.id), ['req-1']);
|
||||
assert.deepEqual(scopeMap['version-1'].devTasks.map((item) => item.id), ['dev-legacy']);
|
||||
assert.deepEqual(scopeMap['version-2'].requirements.map((item) => item.id), ['req-2']);
|
||||
assert.deepEqual(scopeMap['version-2'].devTasks.map((item) => item.id), ['dev-direct']);
|
||||
assert.deepEqual(scopeMap['version-2'].plansByType.ui.map((item) => item.id), ['plan-2']);
|
||||
assert.deepEqual(scopeMap['version-empty'].requirements, []);
|
||||
assert.deepEqual(Object.keys(scopeMap).sort(), ['version-1', 'version-2', 'version-empty']);
|
||||
});
|
||||
Reference in New Issue
Block a user