44 lines
1.7 KiB
TypeScript
44 lines
1.7 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
const characterModelSource = readFileSync(
|
|
new URL("./CharacterModel.tsx", import.meta.url),
|
|
"utf8",
|
|
);
|
|
const equipmentAttachmentSource = readFileSync(
|
|
new URL("./equipmentAttachments.tsx", import.meta.url),
|
|
"utf8",
|
|
);
|
|
const gameSceneSource = readFileSync(
|
|
new URL("../scene/GameScene.tsx", import.meta.url),
|
|
"utf8",
|
|
);
|
|
|
|
describe("avatar rendering integration invariants", () => {
|
|
it("keeps starter weapons connected to loaded and fallback characters", () => {
|
|
expect(characterModelSource).toContain("<StarterWeaponAttachments");
|
|
expect(characterModelSource).toContain("<ApproximateStarterEquipment");
|
|
expect(characterModelSource).toContain("<EquipmentAttachments");
|
|
});
|
|
|
|
it("uses manifest sockets while the loaded skeleton owns weapon motion", () => {
|
|
const loadedStarterAttachment = characterModelSource.match(
|
|
/<StarterWeaponAttachments[\s\S]*?\/>/,
|
|
)?.[0] ?? "";
|
|
expect(loadedStarterAttachment).toContain("entry={entry}");
|
|
expect(loadedStarterAttachment).not.toContain("attackPulseRef=");
|
|
expect(characterModelSource).not.toContain("equipmentAttackPulseRef");
|
|
});
|
|
|
|
it("isolates each optional gear model behind its own loading and error boundary", () => {
|
|
expect(equipmentAttachmentSource).toContain("<AvatarErrorBoundary");
|
|
expect(equipmentAttachmentSource).toContain("<Suspense fallback={fallback}>");
|
|
expect(equipmentAttachmentSource).toContain("<AttachedEquipmentModel");
|
|
});
|
|
|
|
it("uses popup-free right-mouse drag instead of requesting Pointer Lock", () => {
|
|
expect(gameSceneSource).toContain("beginMouseLookDrag(");
|
|
expect(gameSceneSource).not.toContain("requestPointerLock(");
|
|
});
|
|
});
|