134 lines
6.0 KiB
TypeScript
134 lines
6.0 KiB
TypeScript
import { describe, it, expect, beforeEach } from 'vitest';
|
|
import { useDisciplineStore } from '../stores/discipline-slice';
|
|
import { useManaStore } from '../stores/manaStore';
|
|
|
|
function resetDisciplineStore() {
|
|
useDisciplineStore.setState({
|
|
disciplines: {},
|
|
activeIds: [],
|
|
concurrentLimit: 1,
|
|
totalXP: 0,
|
|
processedPerks: [],
|
|
practicingCallbacks: null,
|
|
});
|
|
}
|
|
|
|
describe('DisciplineStore — reactivate after deactivate', () => {
|
|
beforeEach(resetDisciplineStore);
|
|
|
|
it('should reactivate a raw discipline after deactivate when rawMana is sufficient', () => {
|
|
// Set up mana store with sufficient raw mana
|
|
useManaStore.setState({ rawMana: 1000, elements: {} });
|
|
|
|
// First activation succeeds (reads rawMana from mana store)
|
|
useDisciplineStore.getState().activate('raw-mastery');
|
|
expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');
|
|
|
|
// Deactivate
|
|
useDisciplineStore.getState().deactivate('raw-mastery');
|
|
expect(useDisciplineStore.getState().activeIds).not.toContain('raw-mastery');
|
|
expect(useDisciplineStore.getState().disciplines['raw-mastery'].paused).toBe(true);
|
|
|
|
// Reactivate — reads rawMana=1000 from mana store, should succeed
|
|
useDisciplineStore.getState().activate('raw-mastery');
|
|
expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');
|
|
expect(useDisciplineStore.getState().disciplines['raw-mastery'].paused).toBe(false);
|
|
});
|
|
|
|
it('should NOT reactivate a raw discipline when rawMana is insufficient', () => {
|
|
// Activate with sufficient mana
|
|
useManaStore.setState({ rawMana: 1000, elements: {} });
|
|
useDisciplineStore.getState().activate('raw-mastery');
|
|
expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');
|
|
|
|
// Build up XP via ticks
|
|
useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
|
|
useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
|
|
const xp = useDisciplineStore.getState().disciplines['raw-mastery'].xp;
|
|
expect(xp).toBeGreaterThan(0);
|
|
|
|
// Deactivate
|
|
useDisciplineStore.getState().deactivate('raw-mastery');
|
|
expect(useDisciplineStore.getState().activeIds).not.toContain('raw-mastery');
|
|
|
|
// Set rawMana to 0 — reactivation should fail
|
|
useManaStore.setState({ rawMana: 0, elements: {} });
|
|
useDisciplineStore.getState().activate('raw-mastery');
|
|
expect(useDisciplineStore.getState().activeIds).not.toContain('raw-mastery');
|
|
});
|
|
|
|
it('should reactivate a discipline with elements after deactivating it', () => {
|
|
useManaStore.setState({
|
|
rawMana: 0,
|
|
elements: { fire: { unlocked: true, current: 100, max: 100, baseMax: 100 } },
|
|
});
|
|
|
|
useDisciplineStore.getState().activate('attune-fire');
|
|
expect(useDisciplineStore.getState().activeIds).toContain('attune-fire');
|
|
|
|
useDisciplineStore.getState().deactivate('attune-fire');
|
|
expect(useDisciplineStore.getState().activeIds).not.toContain('attune-fire');
|
|
|
|
// Reactivate — reads elements from mana store
|
|
useDisciplineStore.getState().activate('attune-fire');
|
|
expect(useDisciplineStore.getState().activeIds).toContain('attune-fire');
|
|
expect(useDisciplineStore.getState().disciplines['attune-fire'].paused).toBe(false);
|
|
});
|
|
|
|
it('should reactivate after processTick auto-pauses due to no mana', () => {
|
|
useManaStore.setState({ rawMana: 100, elements: {} });
|
|
useDisciplineStore.getState().activate('raw-mastery');
|
|
expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');
|
|
|
|
// Tick with no mana — discipline auto-pauses
|
|
useDisciplineStore.getState().processTick({ rawMana: 0, elements: {} });
|
|
expect(useDisciplineStore.getState().activeIds).not.toContain('raw-mastery');
|
|
expect(useDisciplineStore.getState().disciplines['raw-mastery'].paused).toBe(true);
|
|
|
|
// Restore mana and reactivate
|
|
useManaStore.setState({ rawMana: 1000, elements: {} });
|
|
useDisciplineStore.getState().activate('raw-mastery');
|
|
expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');
|
|
expect(useDisciplineStore.getState().disciplines['raw-mastery'].paused).toBe(false);
|
|
});
|
|
|
|
it('should preserve XP when deactivating and reactivating', () => {
|
|
useManaStore.setState({ rawMana: 1000, elements: {} });
|
|
useDisciplineStore.getState().activate('raw-mastery');
|
|
useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
|
|
useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
|
|
useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
|
|
expect(useDisciplineStore.getState().disciplines['raw-mastery'].xp).toBe(3);
|
|
|
|
useDisciplineStore.getState().deactivate('raw-mastery');
|
|
expect(useDisciplineStore.getState().disciplines['raw-mastery'].xp).toBe(3);
|
|
expect(useDisciplineStore.getState().disciplines['raw-mastery'].paused).toBe(true);
|
|
|
|
useDisciplineStore.getState().activate('raw-mastery');
|
|
expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');
|
|
expect(useDisciplineStore.getState().disciplines['raw-mastery'].xp).toBe(3);
|
|
|
|
useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
|
|
expect(useDisciplineStore.getState().disciplines['raw-mastery'].xp).toBe(4);
|
|
});
|
|
|
|
it('should use gameState overrides when explicitly provided (for test control)', () => {
|
|
// Even though mana store has no mana, explicit override should work
|
|
useManaStore.setState({ rawMana: 0, elements: {} });
|
|
|
|
// First activation: no state yet, so canProceed returns true (optimistic)
|
|
useDisciplineStore.getState().activate('raw-mastery');
|
|
expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');
|
|
|
|
useDisciplineStore.getState().deactivate('raw-mastery');
|
|
|
|
// Reactivate with explicit override — bypasses store reads
|
|
useDisciplineStore.getState().activate('raw-mastery', {
|
|
rawMana: 1000,
|
|
elements: {},
|
|
signedPacts: [],
|
|
});
|
|
expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');
|
|
});
|
|
});
|