refactor: eliminate as any type casts across 18 source files
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m34s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m34s
- Fix computeDisciplineEffects() to not require GameState parameter - Fix getUnifiedEffects() to accept proper partial state type - Replace upgradeEffects as any with proper UnifiedEffects type - Replace explicit : any annotations with proper types (ComputedEffects, DesignProgress, SpellDef, etc.) - Fix activity-log.ts eventType casting - Fix crafting-design.ts computedEffects and designProgress types - Fix page.tsx grimoire spell rendering with proper SpellDef property names - Fix StatsTab ManaStatsSection with proper ManaStatsEffects interface - Remove unused imports (useDisciplineStore from page.tsx, LeftPanel.tsx) Remaining: 1 as any in craftingStore.ts (pre-existing CraftingStore/GameState architectural mismatch)
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
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('elemental-attunement');
|
||||
expect(useDisciplineStore.getState().activeIds.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should activate when no prior discipline state (optimistic)', () => {
|
||||
// canProceedDiscipline returns true when disciplineState is undefined
|
||||
useDisciplineStore.getState().activate('elemental-attunement', {
|
||||
elements: { fire: { unlocked: false } },
|
||||
});
|
||||
expect(useDisciplineStore.getState().activeIds).toContain('elemental-attunement');
|
||||
});
|
||||
|
||||
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('elemental-attunement', {
|
||||
elements: { fire: { unlocked: true } },
|
||||
});
|
||||
expect(useDisciplineStore.getState().activeIds).toContain('elemental-attunement');
|
||||
});
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user