refactor: complete error handling standardization (issue #101)
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m26s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m26s
Prestige Store: - Convert doPrestige() to return Result<void> with specific error codes (INVALID_PRESTIGE_ID, PRESTIGE_MAX_LEVEL, INSUFFICIENT_INSIGHT) - Convert startPactRitual() to return Result<void> with specific error codes (GUARDIAN_NOT_DEFEATED, PACT_ALREADY_SIGNED, PACT_SLOTS_FULL, INSUFFICIENT_MANA, RITUAL_IN_PROGRESS) Combat Actions: - Add try/catch wrapper inside processCombatTick with safe fallback defaults - Add makeDefaultCombatTickResult helper for error recovery LocalStorage Error Handling: - Create safe-persist.ts utility wrapping localStorage with error handling (corrupted JSON, quota exceeded, unexpected failures) - Update all 8 Zustand stores to use createSafeStorage() in persist middleware UI Updates: - Update GuardianPactsTab to use Result pattern for ritual error messages Tests: - Update store-actions-combat-prestige.test.ts for Result return types - Update store-actions.test.ts ManaStore tests for Result pattern - Remove duplicate Prestige/Discipline sections from store-actions.test.ts - All files under 400 line limit 601 tests pass (3 pre-existing failures in spire-utils.test.ts)
This commit is contained in:
@@ -2,6 +2,7 @@ import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { useCombatStore } from '../stores/combatStore';
|
||||
import { usePrestigeStore } from '../stores/prestigeStore';
|
||||
import { getFloorMaxHP } from '../utils';
|
||||
import { ErrorCode } from '../utils/result';
|
||||
|
||||
function resetCombatStore() {
|
||||
useCombatStore.setState({
|
||||
@@ -188,7 +189,7 @@ describe('PrestigeStore', () => {
|
||||
describe('doPrestige', () => {
|
||||
it('should purchase upgrade when affordable', () => {
|
||||
const result = usePrestigeStore.getState().doPrestige('manaWell');
|
||||
expect(result).toBe(true);
|
||||
expect(result.success).toBe(true);
|
||||
expect(usePrestigeStore.getState().prestigeUpgrades.manaWell).toBe(1);
|
||||
expect(usePrestigeStore.getState().insight).toBeLessThan(500);
|
||||
});
|
||||
@@ -196,18 +197,25 @@ describe('PrestigeStore', () => {
|
||||
it('should return false when cannot afford', () => {
|
||||
usePrestigeStore.setState({ insight: 0 });
|
||||
const result = usePrestigeStore.getState().doPrestige('manaWell');
|
||||
expect(result).toBe(false);
|
||||
expect(result.success).toBe(false);
|
||||
if (!result.success) {
|
||||
expect(result.code).toBe(ErrorCode.INSUFFICIENT_INSIGHT);
|
||||
}
|
||||
});
|
||||
|
||||
it('should return false for invalid upgrade id', () => {
|
||||
it('should fail for invalid upgrade id', () => {
|
||||
const result = usePrestigeStore.getState().doPrestige('nonexistent');
|
||||
expect(result).toBe(false);
|
||||
expect(result.success).toBe(false);
|
||||
if (!result.success) {
|
||||
expect(result.code).toBe(ErrorCode.INVALID_PRESTIGE_ID);
|
||||
}
|
||||
});
|
||||
|
||||
it('should increase memorySlots with deepMemory', () => {
|
||||
usePrestigeStore.setState({ insight: 2000 });
|
||||
const before = usePrestigeStore.getState().memorySlots;
|
||||
usePrestigeStore.getState().doPrestige('deepMemory');
|
||||
const deepResult = usePrestigeStore.getState().doPrestige('deepMemory');
|
||||
expect(deepResult.success).toBe(true);
|
||||
expect(usePrestigeStore.getState().memorySlots).toBe(before + 1);
|
||||
});
|
||||
});
|
||||
@@ -280,31 +288,43 @@ describe('PrestigeStore', () => {
|
||||
it('should start ritual when conditions met', () => {
|
||||
usePrestigeStore.setState({ defeatedGuardians: [10], signedPacts: [], insight: 10000 });
|
||||
const result = usePrestigeStore.getState().startPactRitual(10, 10000);
|
||||
expect(result).toBe(true);
|
||||
expect(result.success).toBe(true);
|
||||
expect(usePrestigeStore.getState().pactRitualFloor).toBe(10);
|
||||
});
|
||||
|
||||
it('should return false when guardian not defeated', () => {
|
||||
const result = usePrestigeStore.getState().startPactRitual(10, 10000);
|
||||
expect(result).toBe(false);
|
||||
expect(result.success).toBe(false);
|
||||
if (!result.success) {
|
||||
expect(result.code).toBe(ErrorCode.GUARDIAN_NOT_DEFEATED);
|
||||
}
|
||||
});
|
||||
|
||||
it('should return false when already signed', () => {
|
||||
it('should fail when already signed', () => {
|
||||
usePrestigeStore.setState({ defeatedGuardians: [10], signedPacts: [10] });
|
||||
const result = usePrestigeStore.getState().startPactRitual(10, 10000);
|
||||
expect(result).toBe(false);
|
||||
expect(result.success).toBe(false);
|
||||
if (!result.success) {
|
||||
expect(result.code).toBe(ErrorCode.PACT_ALREADY_SIGNED);
|
||||
}
|
||||
});
|
||||
|
||||
it('should return false when pact slots full', () => {
|
||||
it('should fail when pact slots full', () => {
|
||||
usePrestigeStore.setState({ defeatedGuardians: [10], signedPacts: [20], pactSlots: 1 });
|
||||
const result = usePrestigeStore.getState().startPactRitual(10, 10000);
|
||||
expect(result).toBe(false);
|
||||
expect(result.success).toBe(false);
|
||||
if (!result.success) {
|
||||
expect(result.code).toBe(ErrorCode.PACT_SLOTS_FULL);
|
||||
}
|
||||
});
|
||||
|
||||
it('should return false when insufficient mana', () => {
|
||||
it('should fail when insufficient mana', () => {
|
||||
usePrestigeStore.setState({ defeatedGuardians: [10], signedPacts: [] });
|
||||
const result = usePrestigeStore.getState().startPactRitual(10, 0);
|
||||
expect(result).toBe(false);
|
||||
expect(result.success).toBe(false);
|
||||
if (!result.success) {
|
||||
expect(result.code).toBe(ErrorCode.INSUFFICIENT_MANA);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user