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.
 
 

109 lines
2.7 KiB

import { beforeEach, describe, expect, it, vi } from "vitest";
import { SceneType } from "@/enums/SceneType";
import type { IBaseScene } from "@/scene/types";
class MockContainer {
visible = true;
label = "";
_isHolderLast?: boolean;
children: MockContainer[] = [];
destroyed = false;
addChild(child: MockContainer): MockContainer {
this.children.push(child);
return child;
}
removeChild(child: MockContainer): MockContainer {
this.children = this.children.filter((item) => item !== child);
return child;
}
destroy(): void {
this.destroyed = true;
}
}
vi.mock("pixi.js", () => ({
Container: MockContainer,
}));
vi.mock("@/core/Game", () => {
class MockGame {
private static instance: MockGame;
readonly stage = new MockContainer();
static getInstance(): MockGame {
if (!MockGame.instance) {
MockGame.instance = new MockGame();
}
return MockGame.instance;
}
}
return {
default: MockGame,
};
});
function createScene(
name: string,
type: SceneType = SceneType.Normal,
onLoad?: () => Promise<void> | void
): IBaseScene {
const stage = new MockContainer();
stage.label = name;
return {
name,
type,
stage: stage as never,
_assetsLoaded: true,
_layoutDone: true,
changeScene: () => {},
onLoad,
onUnLoad: async () => {},
loadBundle: async () => {},
unLoadBundle: async () => {},
layout: async () => {},
};
}
describe("SceneManager rollback consistency", () => {
beforeEach(async () => {
vi.resetModules();
const module = await import("@/scene/SceneManager");
(module.default as unknown as { instance?: unknown }).instance = undefined;
});
it("restores previous scene visibility and mount when transition fails", async () => {
const module = await import("@/scene/SceneManager");
const SceneManager = module.default;
const manager = SceneManager.getInstance();
const previous = createScene("previous");
const target = createScene("target", SceneType.Normal, async () => {
throw new Error("target onLoad failed");
});
manager.registerScene(previous);
manager.registerScene(target);
await manager.initScene("previous");
expect(previous.stage.visible).toBe(true);
expect(manager.currentScene).toBe(previous);
await expect(
manager.changeScene("target", { isHolderLast: true })
).rejects.toThrowError("target onLoad failed");
expect(manager.currentScene).toBe(previous);
expect(previous.stage.visible).toBe(true);
expect(manager["game"].stage.children.includes(previous.stage as never)).toBe(
true
);
expect(manager["game"].stage.children.includes(target.stage as never)).toBe(
false
);
});
});