Files
Genarrative/apps/ai-game-creator-shell/tests/resourceCanvasController.test.ts
T
suzmii 09ed7b099b 视图切换取消排队预取在生产路径上真正生效:视图标识改为必填
- 原缺陷:预览 Hook 的预取作用域 key 缺省退化为"被喂进来的资源集合签名",而宿主按设计要求恒传**全量投影**(传全量才不会让总览里其它栏目只剩栏目标题栏),换栏目/换视图一字不改 ⇒ key 不变 ⇒ 取消上一视图排队预取的 effect 永不执行,"同级裁决"一并退化为 no-op。已有用例用"改 resources"模拟切视图,测的是生产不存在的调用方形状。
- resourceCanvasController.ts 新增 createResourceCanvasPrefetchScopeKey({ view, target, mode }):由视图身份(main / child:<栏目>)加排序模式算出标识。
- index.tsx 在资源画布处显式算出该标识并传给预览 Hook(栏目取 resourceBookState.view / resourceBookState.category,排序取 sortMode)。
- useProjectResourceCardPreviews.ts 把 prefetchScopeKey 由可选改为**必填**并删掉那段兜底:它能"看起来还在工作",正是它掩盖了漏接线;现在漏传是类型错误而不是静默少取消一次。
- 断言:resourceCanvasController.test.ts 新增标识派生两组用例(换栏目/换视图/换排序模式必须变,同一视图必须稳定);useProjectResourceCardPreviews.test.ts 改写两条既有切视图用例为生产形状(resources 恒为全量、只改视图标识与 eagerResources),并在用例内前置断言"换栏目必须换标识";其余既有用例经用例侧包装补齐标识,形状与生产一致,断言一条未放宽。
- 变异验证(提交前已跑):把 createResourceCanvasPrefetchScopeKey 的栏目分量去掉(只留 view + mode)→ 3 条用例变红(标识派生 / 取消上一视图排队预取 / 取消后重新可见再入队),还原后复跑 34 passed。
- 门禁:`npx vitest run` 上述两文件 34 passed;typecheck 见随后整轮。
2026-09-11 21:31:30 +08:00

77 lines
2.5 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
createResourceCanvasPageCategorySignature,
createResourceCanvasPrefetchScopeKey,
} from '../src/view/project-development/resourceCanvasController';
describe('resource canvas page wheel controller', () => {
it('invalidates page categories for same-count category changes without reacting to resource order', () => {
const original = [{ category: 'document' }, { category: 'scene' }];
const reordered = [...original].reverse();
const changed = [{ category: 'document' }, { category: 'audio' }];
expect(createResourceCanvasPageCategorySignature(reordered)).toBe(
createResourceCanvasPageCategorySignature(original),
);
expect(createResourceCanvasPageCategorySignature(changed)).not.toBe(
createResourceCanvasPageCategorySignature(original),
);
});
});
describe('资源画布预取作用域标识', () => {
/**
* 标识必须由**视图身份**算出:喂给预览 Hook 的资源集合是全量投影,换栏目一字不改,
* 因此"资源 id 签名"做不到区分视图 —— 用它当标识会让取消上一视图排队预取永不触发。
*/
it('changes for every view identity change that a resource-set signature cannot see', () => {
const childScene = createResourceCanvasPrefetchScopeKey({
view: 'child',
target: 'scene',
mode: 'dependency',
});
// 换栏目:同一批全量资源下的两个不同视图,标识必须不同。
expect(
createResourceCanvasPrefetchScopeKey({
view: 'child',
target: 'character',
mode: 'dependency',
}),
).not.toBe(childScene);
// 换视图:栏目页 → 总览。
expect(
createResourceCanvasPrefetchScopeKey({
view: 'main',
target: null,
mode: 'dependency',
}),
).not.toBe(childScene);
// 同一栏目内换排序模式:卡片整体重排,对用户就是换了一次视图。
expect(
createResourceCanvasPrefetchScopeKey({
view: 'child',
target: 'scene',
mode: 'type',
}),
).not.toBe(childScene);
});
it('stays stable for an unchanged view so unrelated renders never cancel prefetches', () => {
expect(
createResourceCanvasPrefetchScopeKey({
view: 'child',
target: 'scene',
mode: 'dependency',
}),
).toBe(
createResourceCanvasPrefetchScopeKey({
view: 'child',
target: 'scene',
mode: 'dependency',
}),
);
});
});