diff --git a/apps/ai-game-creator-shell/tests/useProjectResourceCardPreviews.test.ts b/apps/ai-game-creator-shell/tests/useProjectResourceCardPreviews.test.ts index b94b4bf58..a8360a4a4 100644 --- a/apps/ai-game-creator-shell/tests/useProjectResourceCardPreviews.test.ts +++ b/apps/ai-game-creator-shell/tests/useProjectResourceCardPreviews.test.ts @@ -1920,7 +1920,7 @@ describe('冷启动首屏的放行范围与放行顺序', () => { } // 首屏要保证有图可读:可见的 12 张一张都不能少。 expect(readPathsSet.size).toBe(resources.length - offscreen.length); - }); + }, 30000); it('releases intersecting cards in two bands: viewport first, margin second', async () => { // B:一次 observer 回调可能同时报来 ~21 张相交卡,物理读取只有 3 个槽。 @@ -2037,16 +2037,31 @@ describe('预览缓存驱逐后的可见性复核', () => { expect(targetReads()).toHaveLength(1); // 灌满缓存:第 49 张落地时把最早的、仍然可见的这张挤出去。 - for (const filler of fillers) { - const identity = result.current.identityByResourceId.get(filler.id)!; - act(() => result.current.requestPreview(filler, identity, 'visible')); - await waitFor(() => - expect(result.current.previews.get(identity)?.status).toBe('loaded'), - ); - } + // + // 一次性把 48 张都排进队列、只等"读取都发出去了",**不逐张断言 48 个卡的状态**: + // 驱逐本来就会往后连锁(目标卡被驱逐 → 补扫描重读 → 再挤掉一张别人), + // 逐张断言会在链条行进中读到 `undefined`,红的是时序不是契约。 + act(() => { + for (const filler of fillers) { + result.current.requestPreview( + filler, + result.current.identityByResourceId.get(filler.id)!, + 'visible', + ); + } + }); + await waitFor( + () => + expect(previewReadCalls(invoke).length).toBeGreaterThanOrEqual( + fillers.length + 1, + ), + { timeout: 20000 }, + ); // 驱逐后必须补一次可见性复核:仍可见的卡要重新入队并重新读到图。 - await waitFor(() => expect(targetReads()).toHaveLength(2)); + await waitFor(() => expect(targetReads()).toHaveLength(2), { + timeout: 20000, + }); expect(result.current.previews.get(targetIdentity)?.status).toBe('loaded'); - }); + }, 60000); });