You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
4.3 KiB
124 lines
4.3 KiB
import { describe, expect, it } from "vitest";
|
|
import { AssetManager } from "@/core/AssetManager";
|
|
|
|
type FakeBundle = Record<string, unknown>;
|
|
|
|
describe("AssetSession", () => {
|
|
it("deduplicates concurrent first-time bundle loads", async () => {
|
|
const loadCalls: string[] = [];
|
|
let resolveLoad: ((bundle: FakeBundle) => void) | null = null;
|
|
const manager = new AssetManager({
|
|
init: async () => undefined,
|
|
loadBundle: (name: string) =>
|
|
new Promise<FakeBundle>((resolve) => {
|
|
loadCalls.push(name);
|
|
resolveLoad = resolve;
|
|
}),
|
|
unloadBundle: async () => undefined,
|
|
});
|
|
|
|
const sessionA = manager.createSession("scene");
|
|
const sessionB = manager.createSession("ui");
|
|
|
|
const pendingA = sessionA.loadBundle("shared");
|
|
const pendingB = sessionB.loadBundle("shared");
|
|
|
|
expect(loadCalls).toEqual(["shared"]);
|
|
|
|
resolveLoad?.({ shared: true });
|
|
const [bundleA, bundleB] = await Promise.all([pendingA, pendingB]);
|
|
|
|
expect(bundleA).toEqual({ shared: true });
|
|
expect(bundleB).toEqual({ shared: true });
|
|
expect(manager.getRefCount("shared")).toBe(2);
|
|
});
|
|
|
|
it("tracks owner/session relationships in inspector snapshot", async () => {
|
|
const loadCalls: string[] = [];
|
|
const unloadCalls: string[] = [];
|
|
const manager = new AssetManager({
|
|
init: async () => undefined,
|
|
loadBundle: async (name: string) => {
|
|
loadCalls.push(name);
|
|
return { name } as FakeBundle;
|
|
},
|
|
unloadBundle: async (name: string) => {
|
|
unloadCalls.push(name);
|
|
},
|
|
});
|
|
|
|
const sceneSessionA = manager.createSession("scene");
|
|
const sceneSessionB = manager.createSession("scene");
|
|
const uiSession = manager.createSession("ui");
|
|
|
|
await sceneSessionA.loadBundle("characters");
|
|
await sceneSessionB.loadBundle("background");
|
|
await uiSession.loadBundle("characters");
|
|
|
|
const snapshot = manager.getInspectorSnapshot();
|
|
|
|
expect(snapshot.sessions[sceneSessionA.id]?.owner).toBe("scene");
|
|
expect(snapshot.sessions[sceneSessionB.id]?.owner).toBe("scene");
|
|
expect(snapshot.sessions[uiSession.id]?.owner).toBe("ui");
|
|
expect(snapshot.owners.scene?.sessions).toContain(sceneSessionA.id);
|
|
expect(snapshot.owners.scene?.sessions).toContain(sceneSessionB.id);
|
|
expect(snapshot.owners.ui?.sessions).toContain(uiSession.id);
|
|
expect(snapshot.activeBundles.sort()).toEqual(["background", "characters"]);
|
|
expect(loadCalls).toEqual(["characters", "background"]);
|
|
expect(unloadCalls).toEqual([]);
|
|
});
|
|
|
|
it("clears active bundles after releaseAll", async () => {
|
|
const unloadCalls: string[] = [];
|
|
const manager = new AssetManager({
|
|
init: async () => undefined,
|
|
loadBundle: async (name: string) => ({ name }) as FakeBundle,
|
|
unloadBundle: async (name: string) => {
|
|
unloadCalls.push(name);
|
|
},
|
|
});
|
|
|
|
const session = manager.createSession("battle");
|
|
await session.loadBundle("fx");
|
|
await session.loadBundle("music");
|
|
|
|
expect(manager.getInspectorSnapshot().activeBundles.sort()).toEqual([
|
|
"fx",
|
|
"music",
|
|
]);
|
|
|
|
await session.releaseAll();
|
|
|
|
const snapshot = manager.getInspectorSnapshot();
|
|
expect(snapshot.activeBundles).toEqual([]);
|
|
expect(snapshot.bundles).toEqual({});
|
|
expect(unloadCalls.sort()).toEqual(["fx", "music"]);
|
|
});
|
|
|
|
it("cleans up destroyed sessions and keeps mixed default/explicit semantics consistent", async () => {
|
|
const unloadCalls: string[] = [];
|
|
const manager = new AssetManager({
|
|
init: async () => undefined,
|
|
loadBundle: async (name: string) => ({ name }) as FakeBundle,
|
|
unloadBundle: async (name: string) => {
|
|
unloadCalls.push(name);
|
|
},
|
|
});
|
|
|
|
const explicit = manager.createSession("scene");
|
|
await manager.loadBundle("shared");
|
|
await explicit.loadBundle("shared");
|
|
|
|
await manager.unloadBundle("shared");
|
|
expect(unloadCalls).toEqual([]);
|
|
expect(manager.getInspectorSnapshot().activeBundles).toEqual(["shared"]);
|
|
|
|
await explicit.destroy();
|
|
const snapshot = manager.getInspectorSnapshot();
|
|
|
|
expect(snapshot.sessions[explicit.id]).toBeUndefined();
|
|
expect(snapshot.owners.scene).toBeUndefined();
|
|
expect(snapshot.activeBundles).toEqual([]);
|
|
expect(unloadCalls).toEqual(["shared"]);
|
|
});
|
|
});
|
|
|