148 lines
4.7 KiB
TypeScript
148 lines
4.7 KiB
TypeScript
/**
|
|
* Tests for SkillHotkeysHud, speedbars, keybindings, and Attack slot binding (Issue #151).
|
|
*/
|
|
|
|
import { describe, expect, it, beforeEach } from 'vitest'
|
|
import {
|
|
SkillHotkeysHud,
|
|
LEFT_SKILL_BOUNDS,
|
|
RIGHT_SKILL_BOUNDS,
|
|
DEFAULT_SORCERESS_SKILLS,
|
|
resolveSkillIcon,
|
|
getAvailableSkillsForSide,
|
|
} from '../src/ui/hotkeys.ts'
|
|
|
|
describe('SkillHotkeysHud & Dual Slot Mechanics', () => {
|
|
let hud: SkillHotkeysHud
|
|
|
|
beforeEach(() => {
|
|
hud = new SkillHotkeysHud()
|
|
})
|
|
|
|
it('initializes with expected default skills and state', () => {
|
|
expect(hud.leftSkillId).toBe(47) // Fire Ball
|
|
expect(hud.rightSkillId).toBe(64) // Frozen Orb
|
|
expect(hud.selectionOpen).toBeNull()
|
|
expect(hud.availableSkills.length).toBeGreaterThanOrEqual(10)
|
|
|
|
// Skill 0 is available
|
|
const attack = hud.availableSkills.find((s) => s.skillId === 0)
|
|
expect(attack).toBeDefined()
|
|
expect(attack!.leftUsable).toBe(true)
|
|
expect(attack!.rightUsable).toBe(true)
|
|
})
|
|
|
|
it('opens and closes left selection speedbar on click', () => {
|
|
// Click center of left skill icon
|
|
const leftX = LEFT_SKILL_BOUNDS.x + 24
|
|
const leftY = LEFT_SKILL_BOUNDS.y + 24
|
|
|
|
const handled = hud.handleClick(leftX, leftY)
|
|
expect(handled).toBe(true)
|
|
expect(hud.selectionOpen).toBe('left')
|
|
|
|
// Click again to close
|
|
hud.handleClick(leftX, leftY)
|
|
expect(hud.selectionOpen).toBeNull()
|
|
})
|
|
|
|
it('opens and closes right selection speedbar on click', () => {
|
|
// Click center of right skill icon
|
|
const rightX = RIGHT_SKILL_BOUNDS.x + 24
|
|
const rightY = RIGHT_SKILL_BOUNDS.y + 24
|
|
|
|
const handled = hud.handleClick(rightX, rightY)
|
|
expect(handled).toBe(true)
|
|
expect(hud.selectionOpen).toBe('right')
|
|
|
|
// Click outside to close
|
|
hud.handleClick(100, 100)
|
|
expect(hud.selectionOpen).toBeNull()
|
|
})
|
|
|
|
it('allows selecting Normal Attack from left speedbar palette', () => {
|
|
hud.openSpeedbar('left')
|
|
expect(hud.selectionOpen).toBe('left')
|
|
|
|
// Find Attack in speedbar layout
|
|
const speedbarSkills = hud.getSpeedbarSkills('left')
|
|
const attackEntry = speedbarSkills.find((e) => e.skill.skillId === 0)
|
|
expect(attackEntry).toBeDefined()
|
|
|
|
// Click on Attack icon in speedbar
|
|
const clicked = hud.handleClick(attackEntry!.x + 10, attackEntry!.y + 10)
|
|
expect(clicked).toBe(true)
|
|
expect(hud.leftSkillId).toBe(0)
|
|
expect(hud.selectionOpen).toBeNull() // closed after selection
|
|
})
|
|
|
|
it('allows selecting Normal Attack from right speedbar palette', () => {
|
|
hud.openSpeedbar('right')
|
|
expect(hud.selectionOpen).toBe('right')
|
|
|
|
const speedbarSkills = hud.getSpeedbarSkills('right')
|
|
const attackEntry = speedbarSkills.find((e) => e.skill.skillId === 0)
|
|
expect(attackEntry).toBeDefined()
|
|
|
|
const clicked = hud.handleClick(attackEntry!.x + 10, attackEntry!.y + 10)
|
|
expect(clicked).toBe(true)
|
|
expect(hud.rightSkillId).toBe(0)
|
|
expect(hud.selectionOpen).toBeNull()
|
|
})
|
|
|
|
it('supports dual slot binding with Attack on both slots', () => {
|
|
hud.assignSkill('left', 0)
|
|
hud.assignSkill('right', 0)
|
|
|
|
expect(hud.leftSkillId).toBe(0)
|
|
expect(hud.rightSkillId).toBe(0)
|
|
|
|
// Verify resolveSkillIcon works for both slots
|
|
const leftIcon = resolveSkillIcon(hud.leftSkillId)
|
|
const rightIcon = resolveSkillIcon(hud.rightSkillId)
|
|
|
|
expect(leftIcon.skillId).toBe(0)
|
|
expect(rightIcon.skillId).toBe(0)
|
|
expect(leftIcon.name).toBe('Attack')
|
|
expect(rightIcon.name).toBe('Attack')
|
|
expect(leftIcon.iconPath).toBe('/skills/icon_0.png')
|
|
expect(rightIcon.iconPath).toBe('/skills/icon_0.png')
|
|
})
|
|
|
|
it('manages F1-F8 hotkey bindings and key presses', () => {
|
|
// Bind F1 to Attack (0)
|
|
hud.setHotkey('F1', 0)
|
|
expect(hud.getHotkey('F1')).toBe(0)
|
|
|
|
// Bind F2 to Frozen Orb (64)
|
|
hud.setHotkey('F2', 64)
|
|
expect(hud.getHotkey('F2')).toBe(64)
|
|
|
|
// Pressing F1 assigns right skill to 0
|
|
const handledF1 = hud.handleKeyDown('F1')
|
|
expect(handledF1).toBe(true)
|
|
expect(hud.rightSkillId).toBe(0)
|
|
|
|
// Pressing F2 assigns right skill to 64
|
|
const handledF2 = hud.handleKeyDown('F2')
|
|
expect(handledF2).toBe(true)
|
|
expect(hud.rightSkillId).toBe(64)
|
|
})
|
|
|
|
it('handles mouse hover over skill buttons and speedbar icons', () => {
|
|
hud.handleMouseMove(LEFT_SKILL_BOUNDS.x + 10, LEFT_SKILL_BOUNDS.y + 10)
|
|
expect(hud.hoverSkillId).toBe(hud.leftSkillId)
|
|
|
|
hud.handleMouseMove(RIGHT_SKILL_BOUNDS.x + 10, RIGHT_SKILL_BOUNDS.y + 10)
|
|
expect(hud.hoverSkillId).toBe(hud.rightSkillId)
|
|
|
|
hud.openSpeedbar('left')
|
|
const speedbarSkills = hud.getSpeedbarSkills('left')
|
|
const attackEntry = speedbarSkills.find((e) => e.skill.skillId === 0)
|
|
expect(attackEntry).toBeDefined()
|
|
|
|
hud.handleMouseMove(attackEntry!.x + 10, attackEntry!.y + 10)
|
|
expect(hud.hoverSpeedbarSkillId).toBe(0)
|
|
})
|
|
})
|