513cab81a3
- Delete src/lib/game/constants/guardians.ts (the old static GUARDIANS constant) - Create src/lib/game/data/guardian-data.ts with BASE_GUARDIANS (same data, new home) - Remove GUARDIANS export from constants/index.ts - Update all 11 files that imported GUARDIANS to use getGuardianForFloor() or BASE_GUARDIANS: - useGameDerived.ts, combat-actions.ts, gameStore.ts, prestigeStore.ts - combat-utils.ts, room-utils.ts, floor-utils.ts, spire-utils.ts - SpireCombatPage.tsx, SpireHeader.tsx - Update 4 test files to use getGuardianForFloor() instead of GUARDIANS constant - guardian-encounters.ts now imports BASE_GUARDIANS from guardian-data.ts - Split room-utils.test.ts (505 lines) into room-utils.test.ts + room-utils-floor-state.test.ts
135 lines
5.7 KiB
TypeScript
135 lines
5.7 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
|
|
// ─── Test: GuardianPactsTab barrel export ──────────────────────────────────────
|
|
|
|
describe('GuardianPactsTab module structure', () => {
|
|
it('exports GuardianPactsTab from barrel index', async () => {
|
|
const mod = await import('./GuardianPactsTab');
|
|
expect(mod.GuardianPactsTab).toBeDefined();
|
|
expect(typeof mod.GuardianPactsTab).toBe('function');
|
|
});
|
|
|
|
it('GuardianPactsTab has correct displayName', async () => {
|
|
const { GuardianPactsTab } = await import('./GuardianPactsTab');
|
|
expect(GuardianPactsTab.displayName).toBe('GuardianPactsTab');
|
|
});
|
|
});
|
|
|
|
// ─── Test: Barrel export includes GuardianPactsTab ─────────────────────────────
|
|
|
|
describe('Tab barrel export', () => {
|
|
it('includes GuardianPactsTab in the tabs index', async () => {
|
|
const mod = await import('@/components/game/tabs');
|
|
expect(mod.GuardianPactsTab).toBeDefined();
|
|
expect(typeof mod.GuardianPactsTab).toBe('function');
|
|
});
|
|
});
|
|
|
|
// ─── Test: Guardian data integrity ─────────────────────────────────────────────
|
|
|
|
describe('Guardian data', () => {
|
|
it('all guardians have required fields', async () => {
|
|
const { getGuardianForFloor } = await import('@/lib/game/data/guardian-encounters');
|
|
for (const floor of [10, 20, 30, 40, 50, 60, 80, 90, 100]) {
|
|
const def = getGuardianForFloor(floor)!;
|
|
expect(def.name).toBeTruthy();
|
|
expect(def.element).toBeTruthy();
|
|
expect(def.hp).toBeGreaterThan(0);
|
|
expect(def.power).toBeGreaterThan(0);
|
|
expect(def.boons.length).toBeGreaterThan(0);
|
|
expect(def.pactCost).toBeGreaterThan(0);
|
|
expect(def.pactTime).toBeGreaterThan(0);
|
|
expect(def.uniquePerk).toBeTruthy();
|
|
expect(def.signingCost).toBeTruthy();
|
|
expect(def.signingCost.mana).toBeGreaterThan(0);
|
|
expect(def.signingCost.time).toBeGreaterThan(0);
|
|
expect(def.unlocksMana.length).toBeGreaterThan(0);
|
|
expect(def.damageMultiplier).toBeGreaterThan(0);
|
|
expect(def.insightMultiplier).toBeGreaterThan(0);
|
|
}
|
|
});
|
|
|
|
it('guardians are defined at expected floors', async () => {
|
|
const { getGuardianForFloor } = await import('@/lib/game/data/guardian-encounters');
|
|
const expectedFloors = [10, 20, 30, 40, 50, 60, 80, 90, 100];
|
|
for (const floor of expectedFloors) {
|
|
expect(getGuardianForFloor(floor)).not.toBeNull();
|
|
}
|
|
});
|
|
|
|
it('guardian boons have valid types', async () => {
|
|
const validBoonTypes = [
|
|
'maxMana', 'manaRegen', 'castingSpeed', 'elementalDamage', 'rawDamage',
|
|
'critChance', 'critDamage', 'spellEfficiency', 'manaGain', 'insightGain',
|
|
'studySpeed', 'prestigeInsight',
|
|
];
|
|
const { getGuardianForFloor } = await import('@/lib/game/data/guardian-encounters');
|
|
for (const floor of [10, 20, 30, 40, 50, 60, 80, 90, 100]) {
|
|
const def = getGuardianForFloor(floor)!;
|
|
for (const boon of def.boons) {
|
|
expect(validBoonTypes).toContain(boon.type);
|
|
expect(boon.value).toBeGreaterThan(0);
|
|
expect(boon.desc).toBeTruthy();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
// ─── Test: Prestige store pact state ───────────────────────────────────────────
|
|
|
|
describe('Prestige store pact state', () => {
|
|
it('has correct initial pact state shape', async () => {
|
|
const { usePrestigeStore } = await import('@/lib/game/stores/prestigeStore');
|
|
const state = usePrestigeStore.getState();
|
|
expect(Array.isArray(state.defeatedGuardians)).toBe(true);
|
|
expect(Array.isArray(state.signedPacts)).toBe(true);
|
|
expect(typeof state.pactSlots).toBe('number');
|
|
expect(state.pactSlots).toBeGreaterThanOrEqual(1);
|
|
expect(state.pactRitualFloor).toBeNull();
|
|
expect(state.pactRitualProgress).toBe(0);
|
|
});
|
|
|
|
it('startPactRitual is a function', async () => {
|
|
const { usePrestigeStore } = await import('@/lib/game/stores/prestigeStore');
|
|
const state = usePrestigeStore.getState();
|
|
expect(typeof state.startPactRitual).toBe('function');
|
|
});
|
|
|
|
it('cancelPactRitual is a function', async () => {
|
|
const { usePrestigeStore } = await import('@/lib/game/stores/prestigeStore');
|
|
const state = usePrestigeStore.getState();
|
|
expect(typeof state.cancelPactRitual).toBe('function');
|
|
});
|
|
|
|
it('completePactRitual is a function', async () => {
|
|
const { usePrestigeStore } = await import('@/lib/game/stores/prestigeStore');
|
|
const state = usePrestigeStore.getState();
|
|
expect(typeof state.completePactRitual).toBe('function');
|
|
});
|
|
|
|
it('defeatGuardian is a function', async () => {
|
|
const { usePrestigeStore } = await import('@/lib/game/stores/prestigeStore');
|
|
const state = usePrestigeStore.getState();
|
|
expect(typeof state.defeatGuardian).toBe('function');
|
|
});
|
|
|
|
it('removePact is a function', async () => {
|
|
const { usePrestigeStore } = await import('@/lib/game/stores/prestigeStore');
|
|
const state = usePrestigeStore.getState();
|
|
expect(typeof state.removePact).toBe('function');
|
|
});
|
|
});
|
|
|
|
// ─── Test: File size limit ─────────────────────────────────────────────────────
|
|
|
|
describe('File size limits (400 lines max)', () => {
|
|
it('GuardianPactsTab.tsx is under 400 lines', async () => {
|
|
const fs = await import('fs');
|
|
const path = await import('path');
|
|
const filePath = path.join(__dirname, 'GuardianPactsTab.tsx');
|
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
const lines = content.split('\n').length;
|
|
expect(lines).toBeLessThan(400);
|
|
});
|
|
});
|