import { describe, it, expect } from 'vitest' import { resolveMonsterArtSpec, MONSTER_ART_MAP, ACT_MONSTER_SPECS } from '../src/game/monster-mapping.ts' describe('monster-mapping', () => { it('resolves standard Act 1 monsters', () => { expect(resolveMonsterArtSpec('fallen1')).toEqual({ token: 'FA', weapon: 'hth' }) expect(resolveMonsterArtSpec('zombie1')).toEqual({ token: 'ZM', weapon: 'hth' }) expect(resolveMonsterArtSpec('quillrat1')).toEqual({ token: 'SI', weapon: 'hth' }) expect(resolveMonsterArtSpec('corruptrogue1')).toEqual({ token: 'CR', weapon: '1hs' }) expect(resolveMonsterArtSpec('cr_archer1')).toEqual({ token: 'CR', weapon: 'bow' }) }) it('resolves numbered variants through exact or base lookup without prefix iteration order', () => { expect(resolveMonsterArtSpec('fallen3')?.token).toBe('FA') expect(resolveMonsterArtSpec('zombie5')?.token).toBe('ZM') expect(resolveMonsterArtSpec('quillrat6')?.token).toBe('SI') // Suffix with arbitrary letters must not prefix-match expect(resolveMonsterArtSpec('fallen_fake')).toBeNull() }) it('resolves hellbovine to EC token instead of CW', () => { expect(resolveMonsterArtSpec('hellbovine')).toEqual({ token: 'EC', weapon: 'hth' }) expect(MONSTER_ART_MAP.hellbovine).toEqual({ token: 'EC', weapon: 'hth' }) }) it('does not leak XX tokens or crash on cut monsters', () => { const cutMonsters = ['bloodmage1', 'darkguard1', 'lightningbeast', 'minion1', 'spiritmummy'] for (const id of cutMonsters) { expect(resolveMonsterArtSpec(id)).toBeNull() } }) it('ACT_MONSTER_SPECS does not contain any XX tokens in any act', () => { for (const [act, specs] of Object.entries(ACT_MONSTER_SPECS)) { for (const spec of specs) { expect(spec.token, `Act ${act} contains invalid token ${spec.token}`).not.toBe('XX') } } }) it('returns null for unknown monsters', () => { expect(resolveMonsterArtSpec('non_existent_monster_xyz')).toBeNull() }) })