import { describe, it, expect, beforeEach } from 'vitest'; import { useDisciplineStore } from '../stores/discipline-slice'; function resetDisciplineStore() { useDisciplineStore.setState({ disciplines: {}, activeIds: [], concurrentLimit: 1, totalXP: 0, }); } describe('DisciplineStore', () => { beforeEach(resetDisciplineStore); describe('activate', () => { it('should activate raw discipline', () => { useDisciplineStore.getState().activate('raw-mastery'); expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery'); expect(useDisciplineStore.getState().disciplines['raw-mastery'].paused).toBe(false); }); it('should not activate same discipline twice', () => { useDisciplineStore.getState().activate('raw-mastery'); useDisciplineStore.getState().activate('raw-mastery'); expect(useDisciplineStore.getState().activeIds.filter(id => id === 'raw-mastery').length).toBe(1); }); it('should not activate when concurrent limit reached', () => { useDisciplineStore.getState().activate('raw-mastery'); useDisciplineStore.getState().activate('attune-fire'); expect(useDisciplineStore.getState().activeIds.length).toBe(1); }); it('should not activate capacity discipline when mana type is locked', () => { // capacity disciplines now require the mana type to be unlocked useDisciplineStore.getState().activate('attune-fire', { elements: { fire: { unlocked: false, current: 100, max: 100 } }, }); expect(useDisciplineStore.getState().activeIds).not.toContain('attune-fire'); }); it('should activate capacity discipline when mana type element is unlocked', () => { useDisciplineStore.getState().activate('attune-fire', { elements: { fire: { unlocked: true, current: 100, max: 100 } }, }); expect(useDisciplineStore.getState().activeIds).toContain('attune-fire'); }); it('should not activate when existing state has insufficient mana', () => { useDisciplineStore.setState({ disciplines: { 'raw-mastery': { id: 'raw-mastery', xp: 1000, paused: false } }, }); useDisciplineStore.getState().activate('raw-mastery', { elements: {} }); expect(useDisciplineStore.getState().activeIds).not.toContain('raw-mastery'); }); it('should activate when required element is unlocked', () => { useDisciplineStore.getState().activate('attune-fire', { elements: { fire: { unlocked: true, current: 100, max: 100 } }, }); expect(useDisciplineStore.getState().activeIds).toContain('attune-fire'); }); }); describe('deactivate', () => { it('should remove discipline from active list', () => { useDisciplineStore.getState().activate('raw-mastery'); useDisciplineStore.getState().deactivate('raw-mastery'); expect(useDisciplineStore.getState().activeIds).not.toContain('raw-mastery'); }); }); describe('processTick', () => { it('should accrue XP for active discipline', () => { useDisciplineStore.getState().activate('raw-mastery'); useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} }); expect(useDisciplineStore.getState().disciplines['raw-mastery'].xp).toBe(1); expect(useDisciplineStore.getState().totalXP).toBe(1); }); it('should drain raw mana for raw discipline', () => { useDisciplineStore.getState().activate('raw-mastery'); const result = useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} }); expect(result.rawMana).toBeLessThan(1000); }); it('should pause discipline when insufficient mana', () => { useDisciplineStore.getState().activate('raw-mastery'); useDisciplineStore.getState().processTick({ rawMana: 0, elements: {} }); expect(useDisciplineStore.getState().disciplines['raw-mastery'].paused).toBe(true); }); it('should increase concurrent limit at 500 total XP', () => { useDisciplineStore.setState({ totalXP: 499 }); useDisciplineStore.getState().activate('raw-mastery'); useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} }); expect(useDisciplineStore.getState().totalXP).toBe(500); expect(useDisciplineStore.getState().concurrentLimit).toBeGreaterThan(1); }); }); });