188 lines
7.8 KiB
TypeScript
188 lines
7.8 KiB
TypeScript
// ─── Upgraded Tests for floor-utils.ts ──────────────────────────────────────────
|
|
|
|
// This file contains additional edge case tests for floor-utils functions
|
|
// to improve coverage and robustness
|
|
|
|
import { describe, it, expect } from 'vitest';
|
|
import { getFloorMaxHP, getFloorElement, getFloorElements } from '../utils/floor-utils';
|
|
|
|
// Helper: compute expected guardian HP (same formula as guardian-data.ts)
|
|
function guardianHP(floor: number): number {
|
|
const base = 5000;
|
|
const exponent = 1.1 + (floor / 200);
|
|
return Math.floor(base * Math.pow(floor / 10, exponent));
|
|
}
|
|
|
|
// ─── Enhanced getFloorMaxHP Tests ─────────────────────────────────────────────
|
|
|
|
describe('getFloorMaxHP - Enhanced Edge Cases', () => {
|
|
it('should handle floor 0', () => {
|
|
expect(getFloorMaxHP(0)).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should handle negative floors', () => {
|
|
expect(getFloorMaxHP(-5)).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should return exact HP for specific floors', () => {
|
|
// Floor 1: 100 (base) + 1*50 (floorScaling) + 1^1.7 (exponentialScaling) = 151
|
|
expect(getFloorMaxHP(1)).toBe(151);
|
|
|
|
// Floor 2: 100 + 2*50 + 2^1.7 = 100 + 100 + 3.247 ≈ 203
|
|
const hp2 = getFloorMaxHP(2);
|
|
expect(hp2).toBeGreaterThan(200);
|
|
expect(hp2).toBeLessThan(204);
|
|
});
|
|
|
|
it('should handle guardian floor 20 (Aqua Regia)', () => {
|
|
// Should return Aqua Regia's HP computed by the hp() formula
|
|
const hp = getFloorMaxHP(20);
|
|
expect(hp).toBe(guardianHP(20));
|
|
});
|
|
|
|
it('should handle guardian floor 30 (Ventus Rex)', () => {
|
|
const hp = getFloorMaxHP(30);
|
|
expect(hp).toBe(guardianHP(30));
|
|
});
|
|
|
|
it('should handle guardian floor 60 (Umbra Mortis)', () => {
|
|
const hp = getFloorMaxHP(60);
|
|
expect(hp).toBe(guardianHP(60));
|
|
});
|
|
|
|
it('should handle very high floor (99)', () => {
|
|
const hp99 = getFloorMaxHP(99);
|
|
// Not a guardian, should use scaling formula
|
|
expect(hp99).toBeGreaterThan(0);
|
|
expect(hp99).toBeLessThan(1000000);
|
|
});
|
|
|
|
it('should handle non-guardian floors around guardians', () => {
|
|
const hp8 = getFloorMaxHP(8); // Before Ignis Prime (10)
|
|
const hp9 = getFloorMaxHP(9); // Before Ignis Prime (10)
|
|
const hp10_guardian = getFloorMaxHP(10); // Ignis Prime
|
|
const hp11 = getFloorMaxHP(11); // After Ignis Prime
|
|
|
|
expect(hp8).toBeLessThan(hp10_guardian);
|
|
expect(hp9).toBeLessThan(hp10_guardian);
|
|
expect(hp11).toBeLessThan(hp10_guardian);
|
|
});
|
|
|
|
it('should return finite values', () => {
|
|
for (let i = 1; i <= 200; i++) {
|
|
const hp = getFloorMaxHP(i);
|
|
expect(isFinite(hp)).toBe(true);
|
|
}
|
|
});
|
|
});
|
|
|
|
// ─── Enhanced getFloorElement Tests ─────────────────────────────────────────────
|
|
|
|
describe('getFloorElement - Enhanced Edge Cases', () => {
|
|
it('should cycle correctly through all 7 elements for non-guardian floors', () => {
|
|
// Floors 1-9: no guardians, pure cycle based on (floor-1) % 7
|
|
expect(getFloorElement(1)).toBe('fire');
|
|
expect(getFloorElement(2)).toBe('water');
|
|
expect(getFloorElement(3)).toBe('air');
|
|
expect(getFloorElement(4)).toBe('earth');
|
|
expect(getFloorElement(5)).toBe('light');
|
|
expect(getFloorElement(6)).toBe('dark');
|
|
expect(getFloorElement(7)).toBe('death');
|
|
expect(getFloorElement(8)).toBe('fire');
|
|
expect(getFloorElement(9)).toBe('water');
|
|
|
|
// Floor 10 is guardian (fire), floors 11-19 continue cycle from their position
|
|
expect(getFloorElement(10)).toBe('fire'); // guardian override
|
|
expect(getFloorElement(11)).toBe('earth'); // (10 % 7) = 3
|
|
expect(getFloorElement(12)).toBe('light'); // (11 % 7) = 4
|
|
expect(getFloorElement(13)).toBe('dark'); // (12 % 7) = 5
|
|
expect(getFloorElement(14)).toBe('death'); // (13 % 7) = 6
|
|
expect(getFloorElement(15)).toBe('fire'); // (14 % 7) = 0
|
|
expect(getFloorElement(16)).toBe('water'); // (15 % 7) = 1
|
|
expect(getFloorElement(17)).toBe('air'); // (16 % 7) = 2
|
|
expect(getFloorElement(18)).toBe('earth'); // (17 % 7) = 3
|
|
expect(getFloorElement(19)).toBe('light'); // (18 % 7) = 4
|
|
expect(getFloorElement(20)).toBe('water'); // guardian override (Aqua Regia)
|
|
});
|
|
|
|
it('should match element at floor 1 for all cycle positions', () => {
|
|
expect(getFloorElement(1)).toBe('fire');
|
|
expect(getFloorElement(8)).toBe('fire'); // 1 + 7
|
|
expect(getFloorElement(15)).toBe('fire'); // 1 + 2*7
|
|
expect(getFloorElement(22)).toBe('fire'); // 1 + 3*7
|
|
expect(getFloorElement(99)).toBe('fire'); // 1 + 14*7
|
|
});
|
|
|
|
it('should handle edge of cycle boundaries', () => {
|
|
// Last element of cycle (death) should match at floor 7, 14, 21, etc.
|
|
expect(getFloorElement(7)).toBe('death');
|
|
expect(getFloorElement(14)).toBe('death');
|
|
expect(getFloorElement(21)).toBe('death');
|
|
|
|
// First element of next cycle (fire) should match at floor 8, 15, 22, etc.
|
|
expect(getFloorElement(8)).toBe('fire');
|
|
expect(getFloorElement(15)).toBe('fire');
|
|
expect(getFloorElement(22)).toBe('fire');
|
|
});
|
|
|
|
it('should handle guardian floors with guardian elements', () => {
|
|
// Floor 10: Ignis Prime (fire guardian) → returns fire
|
|
expect(getFloorElement(10)).toBe('fire');
|
|
// Floor 20: Aqua Regia (water guardian) → returns water
|
|
expect(getFloorElement(20)).toBe('water');
|
|
// Floor 80: Vinculum Arcana (transference guardian) → returns transference
|
|
expect(getFloorElement(80)).toBe('transference');
|
|
});
|
|
|
|
it('should handle very high floor numbers — guardian floors override cycle', () => {
|
|
// Floor 1000 is a guardian floor (every 10th), returns guardian's first element
|
|
// The test below only checks guardian floors work; exact element depends on tier logic
|
|
const elem1000 = getFloorElement(1000);
|
|
expect(typeof elem1000).toBe('string');
|
|
expect(elem1000.length).toBeGreaterThan(0);
|
|
|
|
// Floor 999: NOT a guardian, cycle: ((999-1) % 7) = 4 → FLOOR_ELEM_CYCLE[4] = 'light'
|
|
expect(getFloorElement(999)).toBe('light');
|
|
|
|
// Floor 1001: NOT a guardian, cycle: ((1001-1) % 7) = 6 → FLOOR_ELEM_CYCLE[6] = 'death'
|
|
expect(getFloorElement(1001)).toBe('death');
|
|
});
|
|
|
|
it('should handle floor 0', () => {
|
|
// ((0-1) % 7 + 7) % 7 = (-1 % 7 + 7) % 7 = (-1 + 7) % 7 = 6
|
|
// FLOOR_ELEM_CYCLE[6] = 'death'
|
|
expect(getFloorElement(0)).toBe('death');
|
|
});
|
|
|
|
it('should handle negative floors', () => {
|
|
// ((-10-1) % 7 + 7) % 7 = (-11 % 7 + 7) % 7 = (-4 + 7) % 7 = 3
|
|
// FLOOR_ELEM_CYCLE[3] = 'earth'
|
|
expect(getFloorElement(-10)).toBe('earth' as string);
|
|
});
|
|
|
|
it('should return only valid element names for non-guardian floors', () => {
|
|
const validElements = ['fire', 'water', 'air', 'earth', 'light', 'dark', 'death'];
|
|
// Non-guardian floors should still return cycle elements
|
|
const nonGuardianFloors = [1,2,3,4,5,6,7,8,9,11,12,13,15,16,17,18,19,22,23,24,999,1001];
|
|
for (const f of nonGuardianFloors) {
|
|
expect(validElements).toContain(getFloorElement(f));
|
|
}
|
|
});
|
|
|
|
it('should maintain consistent cycling for non-guardian sequential calls', () => {
|
|
// Non-guardian floors should still cycle predictably
|
|
// Floors 1-9 (no guardian in this range for non-guardian floors 1-9 except 10)
|
|
const block1 = [1,2,3,4,5,6,7,8,9].map(f => getFloorElement(f));
|
|
expect(block1).toEqual(['fire','water','air','earth','light','dark','death','fire','water']);
|
|
});
|
|
|
|
it('getFloorElements returns array with guardian elements', () => {
|
|
// Floor 10: single-element guardian
|
|
expect(getFloorElements(10)).toEqual(['fire']);
|
|
// Floor 1: non-guardian, single-element array
|
|
expect(getFloorElements(1)).toEqual(['fire']);
|
|
// Floor 0: non-guardian edge case
|
|
expect(getFloorElements(0)).toEqual(['death']);
|
|
});
|
|
});
|