import { describe, it, expect, beforeEach } from "vitest"; import { ItemManager } from "../../scenes/systems/ItemManager"; import type { World, CombatantActor, Item, EntityId } from "../../core/types"; import { EntityAccessor } from "../../engine/EntityAccessor"; import { ECSWorld } from "../../engine/ecs/World"; describe("ItemManager - Stacking Logic", () => { let itemManager: ItemManager; let accessor: EntityAccessor; let world: World; let player: CombatantActor; let ecsWorld: ECSWorld; beforeEach(() => { world = { width: 10, height: 10, tiles: new Array(100).fill(0), exit: { x: 9, y: 9 } } as any; ecsWorld = new ECSWorld(); accessor = new EntityAccessor(world, 0 as EntityId, ecsWorld); itemManager = new ItemManager(world, accessor, ecsWorld); player = { id: 0 as EntityId, pos: { x: 1, y: 1 }, category: "combatant", isPlayer: true, type: "player", inventory: { gold: 0, items: [] }, stats: { hp: 10, maxHp: 10 } as any, equipment: {} as any, speed: 100, energy: 0 }; // Sync player to ECS ecsWorld.addComponent(player.id, "position", player.pos); ecsWorld.addComponent(player.id, "player", {}); ecsWorld.addComponent(player.id, "stats", player.stats); ecsWorld.addComponent(player.id, "actorType", { type: "player" }); ecsWorld.addComponent(player.id, "inventory", player.inventory!); ecsWorld.addComponent(player.id, "energy", { current: 0, speed: 100 }); }); it("should stack stackable items when picked up", () => { const potion: Item = { id: "potion", name: "Potion", type: "Consumable", textureKey: "items", spriteIndex: 0, stackable: true, quantity: 1 }; const playerActor = accessor.getPlayer()!; // First potion itemManager.spawnItem(potion, { x: 1, y: 1 }); itemManager.tryPickup(playerActor); expect(playerActor.inventory!.items.length).toBe(1); expect(playerActor.inventory!.items[0].quantity).toBe(1); // Second potion itemManager.spawnItem(potion, { x: 1, y: 1 }); itemManager.tryPickup(playerActor); expect(playerActor.inventory!.items.length).toBe(1); expect(playerActor.inventory!.items[0].quantity).toBe(2); }); it("should NOT stack non-stackable items", () => { const sword: Item = { id: "iron_sword", name: "Iron Sword", type: "Weapon", weaponType: "melee", textureKey: "items", spriteIndex: 1, stackable: false, stats: { attack: 1 } } as any; const playerActor = accessor.getPlayer()!; // First sword itemManager.spawnItem(sword, { x: 1, y: 1 }); itemManager.tryPickup(playerActor); expect(playerActor.inventory!.items.length).toBe(1); // Second sword itemManager.spawnItem(sword, { x: 1, y: 1 }); itemManager.tryPickup(playerActor); expect(playerActor.inventory!.items.length).toBe(2); }); it("should sum quantities of stackable items correctly", () => { const ammo: Item = { id: "9mm_ammo", name: "9mm Ammo", type: "Ammo", textureKey: "items", spriteIndex: 2, stackable: true, quantity: 10, ammoType: "9mm" } as any; const playerActor = accessor.getPlayer()!; itemManager.spawnItem(ammo, { x: 1, y: 1 }); itemManager.tryPickup(playerActor); expect(playerActor.inventory!.items[0].quantity).toBe(10); const moreAmmo = { ...ammo, quantity: 5 }; itemManager.spawnItem(moreAmmo, { x: 1, y: 1 }); itemManager.tryPickup(playerActor); expect(playerActor.inventory!.items[0].quantity).toBe(15); }); });