import { describe, it, expect } from 'vitest'; import { calculateEffectCapacityCost, ENCHANTMENT_EFFECTS } from '../data/enchantment-effects'; import { EQUIPMENT_TYPES } from '../data/equipment'; import { ATTUNEMENTS_DEF, getAttunementConversionRate } from '../data/attunements'; describe('Enchantment Capacity Validation', () => { it('should calculate capacity cost for single stack effects', () => { // Mana Bolt spell effect has base capacity cost of 50 const cost = calculateEffectCapacityCost('spell_manaBolt', 1, 0); expect(cost).toBe(50); }); it('should apply scaling for multiple stacks', () => { // damage_5 has base cost 15, each additional stack costs 20% more const cost1 = calculateEffectCapacityCost('damage_5', 1, 0); const cost2 = calculateEffectCapacityCost('damage_5', 2, 0); // First stack: 15 // Second stack: 15 * 1.2 = 18 // Total: 33 expect(cost1).toBe(15); expect(cost2).toBe(Math.floor(15 + 15 * 1.2)); }); it('should apply efficiency bonus to reduce cost', () => { const costWithoutEfficiency = calculateEffectCapacityCost('spell_manaBolt', 1, 0); const costWithEfficiency = calculateEffectCapacityCost('spell_manaBolt', 1, 0.1); // 10% reduction expect(costWithEfficiency).toBe(Math.floor(costWithoutEfficiency * 0.9)); }); it('should respect equipment base capacity', () => { // Civilian Shirt has base capacity 30 const shirt = EQUIPMENT_TYPES['civilianShirt']; expect(shirt.baseCapacity).toBe(30); // Basic Staff has base capacity 50 const staff = EQUIPMENT_TYPES['basicStaff']; expect(staff.baseCapacity).toBe(50); }); it('should reject enchantment designs exceeding equipment capacity', () => { // Mana Bolt spell effect costs 50 capacity // Civilian Shirt only has 30 capacity const manaBoltCost = calculateEffectCapacityCost('spell_manaBolt', 1, 0); const shirtCapacity = EQUIPMENT_TYPES['civilianShirt'].baseCapacity; expect(manaBoltCost).toBeGreaterThan(shirtCapacity); }); }); describe('Attunement Mana Type Unlocking', () => { it('should define primary mana types for attunements', () => { // Enchanter should have transference as primary mana const enchanter = ATTUNEMENTS_DEF['enchanter']; expect(enchanter.primaryManaType).toBe('transference'); // Fabricator should have earth as primary mana const fabricator = ATTUNEMENTS_DEF['fabricator']; expect(fabricator.primaryManaType).toBe('earth'); }); it('should have conversion rates for attunements with primary mana', () => { // Enchanter should have a conversion rate const enchanter = ATTUNEMENTS_DEF['enchanter']; expect(enchanter.conversionRate).toBeGreaterThan(0); // Get scaled conversion rate at level 1 const level1Rate = getAttunementConversionRate('enchanter', 1); expect(level1Rate).toBe(enchanter.conversionRate); // Higher level should have higher rate const level5Rate = getAttunementConversionRate('enchanter', 5); expect(level5Rate).toBeGreaterThan(level1Rate); }); it('should have raw mana regen for all attunements', () => { Object.values(ATTUNEMENTS_DEF).forEach(attunement => { expect(attunement.rawManaRegen).toBeGreaterThanOrEqual(0); }); }); }); describe('Floor HP State', () => { it('should have getFloorMaxHP function that returns positive values', async () => { const { getFloorMaxHP } = await import('../computed-stats'); for (let floor = 1; floor <= 100; floor++) { const hp = getFloorMaxHP(floor); expect(hp).toBeGreaterThan(0); } }); it('should scale HP correctly with floor progression', async () => { const { getFloorMaxHP } = await import('../computed-stats'); const hp1 = getFloorMaxHP(1); const hp10 = getFloorMaxHP(10); const hp50 = getFloorMaxHP(50); const hp100 = getFloorMaxHP(100); expect(hp10).toBeGreaterThan(hp1); expect(hp50).toBeGreaterThan(hp10); expect(hp100).toBeGreaterThan(hp50); }); }); describe('Element State', () => { it('should have utility elements defined', async () => { const { ELEMENTS } = await import('../constants'); // Check that utility element exists (transference is the only utility element now) expect(ELEMENTS['transference']).toBeDefined(); // Check categories expect(ELEMENTS['transference'].cat).toBe('utility'); }); it('should have composite elements with recipes', async () => { const { ELEMENTS } = await import('../constants'); // Metal is fire + earth expect(ELEMENTS['metal'].cat).toBe('composite'); expect(ELEMENTS['metal'].recipe).toEqual(['fire', 'earth']); // Sand is earth + water expect(ELEMENTS['sand'].cat).toBe('composite'); expect(ELEMENTS['sand'].recipe).toEqual(['earth', 'water']); // Lightning is fire + air expect(ELEMENTS['lightning'].cat).toBe('composite'); expect(ELEMENTS['lightning'].recipe).toEqual(['fire', 'air']); }); });