diablo2-web/tests/p0-521-gold-duplication.tes...

67 lines
2.3 KiB
TypeScript

import { describe, it, expect } from 'vitest'
import { GameEngine } from '../src/game/engine.ts'
import { HudManager } from '../src/ui/hud-manager.ts'
describe('Issue #521: Gold Conservation Invariant & Single Source of Truth', () => {
it('maintains strict gold conservation across drop and pickup without duplication', () => {
const engine = new GameEngine('sor')
const hud = new HudManager(engine)
engine.bag.gold = 5000
hud.syncFromEngine()
expect(hud.inventory.gold).toBe(5000)
// Drop 2000 gold via HUD
const dropped = hud.dropInventoryGold(2000)
expect(dropped).toBe(2000)
expect(engine.bag.gold).toBe(3000)
expect(hud.inventory.gold).toBe(3000)
const goldPiles = engine.groundItems.all.filter(g => g.isGold)
expect(goldPiles.length).toBe(1)
expect(goldPiles[0]!.goldAmount).toBe(2000)
// Total gold in system (player + ground) is conserved at 5000
expect(engine.bag.gold + (goldPiles[0]!.goldAmount ?? 0)).toBe(5000)
// Pick up gold pile
const picked = hud.pickupGroundGold(goldPiles[0]!.id)
expect(picked).toBe(2000)
expect(engine.bag.gold).toBe(5000)
expect(hud.inventory.gold).toBe(5000)
expect(engine.groundItems.all.filter(g => g.isGold).length).toBe(0)
})
it('clamps gold pickup to playerLevel * 10,000 capacity and leaves remainder on ground', () => {
const engine = new GameEngine('pal')
const hud = new HudManager(engine)
// Level 1 capacity = 10,000
expect(engine.maxGoldCapacity).toBe(10_000)
engine.bag.gold = 8500
const pile = engine.groundItems.spawnGold(engine.world.player.x, engine.world.player.y, 4000, 0)
const picked = hud.pickupGroundGold(pile.id)
expect(picked).toBe(1500)
expect(engine.bag.gold).toBe(10_000)
expect(hud.inventory.gold).toBe(10_000)
const remainingPile = engine.groundItems.get(pile.id)
expect(remainingPile).toBeDefined()
expect(remainingPile!.goldAmount).toBe(2500)
})
it('rejects negative, zero, or NaN gold drops without mutating state', () => {
const engine = new GameEngine('ama')
const hud = new HudManager(engine)
engine.bag.gold = 1200
expect(hud.dropInventoryGold(0)).toBe(0)
expect(hud.dropInventoryGold(-500)).toBe(0)
expect(hud.dropInventoryGold(Number.NaN)).toBe(0)
expect(engine.bag.gold).toBe(1200)
expect(engine.groundItems.count).toBe(0)
})
})