Files
Genarrative/apps/ai-game-creator-shell/tests/resourceCanvasVersionBindingModel.test.ts
T
k88936 594063a1e0 测试:修正 AGC 测试文件的类型错误
- 按 vitest 0.34 的参数元组口径改写 mock 泛型
- 修正 noUncheckedIndexedAccess 下的下标访问
- 补齐与当前类型脱节的测试桩字段
- 按 scripts/*.mjs 的运行时契约补局部类型声明
2026-10-03 17:41:30 +08:00

119 lines
4.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, test } from 'vitest';
import {
currentVersionResourceBindingIds,
formatIterationVersionLabel,
isResourceUsedByCurrentVersion,
} from '../src/features/resource-canvas/resourceCanvasVersionBindingModel';
/**
* 夹具必须与落盘口径一致:`versions[].createdAt` 是 **Unix 秒**。
*
* 写入侧见 `project/manifest.rs` 的 `created_at: unix_timestamp()`(`as_secs()`)。
* `1788075047` 取自真机项目 `What do u wanna do kitten` 的 `versions[0].createdAt`,
* 它被当成毫秒渲染时正好是 `1970/1/22 00:41:15`,即真机截图里的 1970 年。
*/
const versions = [
{
versionId: 'version-root',
parentVersionId: null,
projectRevision: 3,
resourceBindings: [
{ slotId: 'asset:asset-player', resourceId: 'asset-player' },
],
createdReason: 'initial' as const,
createdAt: 1_788_075_047,
},
{
versionId: 'version-child',
parentVersionId: 'version-root',
projectRevision: 4,
resourceBindings: [
{ slotId: 'asset:asset-town', resourceId: 'asset-town' },
// 悬空绑定的 slotId 不是恒等映射,不参与「当前使用」判定。
{ slotId: 'player', resourceId: 'asset-player' },
],
createdReason: 'agent-revision' as const,
createdAt: 1_788_075_104,
},
];
describe('运行模块版本绑定判定', () => {
test('falls back to the newest manifest version when no version is selected', () => {
expect(Array.from(currentVersionResourceBindingIds({ versions }))).toEqual([
'asset-town',
]);
});
test('resolves the binding ids of the explicitly selected version', () => {
expect(
Array.from(
currentVersionResourceBindingIds({ versions }, 'version-root'),
),
).toEqual(['asset-player']);
});
test('returns no bindings for a missing version or a manifest without versions', () => {
expect(
currentVersionResourceBindingIds({ versions }, 'version-missing').size,
).toBe(0);
expect(currentVersionResourceBindingIds({}).size).toBe(0);
expect(currentVersionResourceBindingIds({ versions: [] }).size).toBe(0);
});
test('marks only registered assets bound by the current version as in use', () => {
const bindingIds = currentVersionResourceBindingIds(
{ versions },
'version-root',
);
expect(
isResourceUsedByCurrentVersion(
{ manifestAssetId: 'asset-player' },
bindingIds,
),
).toBe(true);
expect(
isResourceUsedByCurrentVersion(
{ manifestAssetId: 'asset-town' },
bindingIds,
),
).toBe(false);
// 未登记为 manifest 素材的资源永远不算「当前使用」。
expect(
isResourceUsedByCurrentVersion({ manifestAssetId: null }, bindingIds),
).toBe(false);
});
test('labels a version with its Chinese created reason and creation time', () => {
expect(formatIterationVersionLabel(versions[0]!)).toBe(
`初始版本 · ${new Date(1_788_075_047 * 1000).toLocaleString('zh-CN')}`,
);
expect(formatIterationVersionLabel(versions[1]!)).toBe(
`智能体修订 · ${new Date(1_788_075_104 * 1000).toLocaleString('zh-CN')}`,
);
});
test('把版本 createdAt 的 Unix 秒换算成毫秒,不再渲染成 1970 年', () => {
// 期望值按同一个本地时区口径算出,用例结果不随运行机器时区漂移。
// 1788075047 秒 = 2026-08-30T07:30:47Z。
const createdAtLocal = new Date(1_788_075_047 * 1000).toLocaleString(
'zh-CN',
);
const label = formatIterationVersionLabel(versions[0]!);
expect(label).toBe(`初始版本 · ${createdAtLocal}`);
// 年 / 月 / 日必须来自真实时刻,而不是 1970。这里用显式数值选项断言,
// 不依赖 `toLocaleString` 的具体排版(不同 ICU 版本会给出不同分隔符)。
expect(
new Intl.DateTimeFormat('zh-CN', {
year: 'numeric',
month: 'numeric',
day: 'numeric',
}).format(new Date(1_788_075_047 * 1000)),
).toBe('2026/8/30');
// 回归守卫:按毫秒解释同一个值会落到 1970/1/22,这正是真机截图里的错误显示。
expect(label).not.toContain('1970');
});
});