Files
Mana-Loop/src/components/game/tabs/EquipmentTab.test.ts
T
n8n-gitea 25ba565467
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m25s
chore: remove unused imports, vars, and params — 84 imports, 7 vars, 16 params across 45+ files
2026-05-25 20:18:39 +02:00

216 lines
9.3 KiB
TypeScript

import { describe, it, expect } from 'vitest';
// ─── Test: EquipmentTab barrel export ──────────────────────────────────────────
describe('EquipmentTab module structure', () => {
it('exports EquipmentTab from barrel index', async () => {
const mod = await import('./EquipmentTab');
expect(mod.EquipmentTab).toBeDefined();
expect(typeof mod.EquipmentTab).toBe('function');
});
it('EquipmentTab has correct displayName', async () => {
const { EquipmentTab } = await import('./EquipmentTab');
expect(EquipmentTab.displayName).toBe('EquipmentTab');
});
});
// ─── Test: Barrel export includes EquipmentTab ─────────────────────────────────
describe('Tab barrel export', () => {
it('includes EquipmentTab in the tabs index', async () => {
const mod = await import('@/components/game/tabs');
expect(mod.EquipmentTab).toBeDefined();
expect(typeof mod.EquipmentTab).toBe('function');
});
});
// ─── Test: Equipment slot definitions ──────────────────────────────────────────
describe('Equipment slot definitions', () => {
it('has exactly 8 equipment slots', async () => {
const { EQUIPMENT_SLOTS } = await import('@/lib/game/data/equipment');
expect(EQUIPMENT_SLOTS).toHaveLength(8);
});
it('all slots have display names', async () => {
const { SLOT_NAMES, EQUIPMENT_SLOTS } = await import('@/lib/game/data/equipment');
for (const slot of EQUIPMENT_SLOTS) {
expect(SLOT_NAMES[slot]).toBeDefined();
expect(SLOT_NAMES[slot].length).toBeGreaterThan(0);
}
});
it('includes mainHand, offHand, head, body, hands, feet, accessory1, accessory2', async () => {
const { EQUIPMENT_SLOTS } = await import('@/lib/game/data/equipment');
expect(EQUIPMENT_SLOTS).toContain('mainHand');
expect(EQUIPMENT_SLOTS).toContain('offHand');
expect(EQUIPMENT_SLOTS).toContain('head');
expect(EQUIPMENT_SLOTS).toContain('body');
expect(EQUIPMENT_SLOTS).toContain('hands');
expect(EQUIPMENT_SLOTS).toContain('feet');
expect(EQUIPMENT_SLOTS).toContain('accessory1');
expect(EQUIPMENT_SLOTS).toContain('accessory2');
});
});
// ─── Test: Equipment type definitions ──────────────────────────────────────────
describe('Equipment type definitions', () => {
it('all equipment types have required fields', async () => {
const { EQUIPMENT_TYPES } = await import('@/lib/game/data/equipment');
for (const [id, type] of Object.entries(EQUIPMENT_TYPES)) {
expect(type.id).toBe(id);
expect(type.name).toBeTruthy();
expect(type.category).toBeTruthy();
expect(type.slot).toBeTruthy();
expect(type.baseCapacity).toBeGreaterThan(0);
}
});
it('accessory category types can equip in accessory slots', async () => {
const { EQUIPMENT_TYPES, getValidSlotsForEquipmentType } = await import('@/lib/game/data/equipment');
const accessories = Object.values(EQUIPMENT_TYPES).filter((t) => t.category === 'accessory');
expect(accessories.length).toBeGreaterThan(0);
for (const acc of accessories) {
const slots = getValidSlotsForEquipmentType(acc);
expect(slots).toContain('accessory1');
expect(slots).toContain('accessory2');
}
});
});
// ─── Test: Starting equipment ──────────────────────────────────────────────────
describe('Starting equipment', () => {
it('crafting store initial state has valid equippedInstances', async () => {
const { useCraftingStore } = await import('@/lib/game/stores/craftingStore');
const state = useCraftingStore.getState();
expect(state.equippedInstances.mainHand).toBeTruthy();
expect(state.equippedInstances.body).toBeTruthy();
expect(state.equippedInstances.feet).toBeTruthy();
expect(state.equippedInstances.offHand).toBeNull();
expect(state.equippedInstances.head).toBeNull();
expect(state.equippedInstances.hands).toBeNull();
expect(state.equippedInstances.accessory1).toBeNull();
expect(state.equippedInstances.accessory2).toBeNull();
expect(Object.keys(state.equipmentInstances).length).toBe(3);
});
it('starting equipment instances have valid fields', async () => {
const { useCraftingStore } = await import('@/lib/game/stores/craftingStore');
const { equipmentInstances } = useCraftingStore.getState();
for (const instance of Object.values(equipmentInstances)) {
expect(instance.instanceId).toBeTruthy();
expect(instance.typeId).toBeTruthy();
expect(instance.name).toBeTruthy();
expect(instance.rarity).toBe('common');
expect(instance.quality).toBe(100);
expect(instance.usedCapacity).toBeGreaterThanOrEqual(0);
expect(instance.totalCapacity).toBeGreaterThan(0);
}
});
});
// ─── Test: Equipment actions ───────────────────────────────────────────────────
describe('Equipment actions', () => {
it('equipItem is a function', async () => {
const { equipItem } = await import('@/lib/game/crafting-actions/equipment-actions');
expect(typeof equipItem).toBe('function');
});
it('unequipItem is a function', async () => {
const { unequipItem } = await import('@/lib/game/crafting-actions/equipment-actions');
expect(typeof unequipItem).toBe('function');
});
it('deleteEquipmentInstance is a function', async () => {
const { deleteEquipmentInstance } = await import('@/lib/game/crafting-actions/equipment-actions');
expect(typeof deleteEquipmentInstance).toBe('function');
});
it('createEquipmentInstance is a function', async () => {
const { createEquipmentInstance } = await import('@/lib/game/crafting-actions/equipment-actions');
expect(typeof createEquipmentInstance).toBe('function');
});
});
// ─── Test: Equipment effects ───────────────────────────────────────────────────
describe('Equipment effects computation', () => {
it('computeEquipmentEffects returns empty for no equipment', async () => {
const { computeEquipmentEffects } = await import('@/lib/game/effects');
const result = computeEquipmentEffects({}, { mainHand: null, offHand: null, head: null, body: null, hands: null, feet: null, accessory1: null, accessory2: null });
expect(Object.keys(result.bonuses)).toHaveLength(0);
expect(Object.keys(result.multipliers)).toHaveLength(0);
expect(result.specials.size).toBe(0);
});
it('computeEquipmentEffects detects enchantment bonuses', async () => {
const { computeEquipmentEffects } = await import('@/lib/game/effects');
const instances = {
test1: {
instanceId: 'test1',
typeId: 'basicStaff',
name: 'Test Staff',
enchantments: [{ effectId: 'spell_manaBolt', stacks: 1, actualCost: 50 }],
usedCapacity: 50,
totalCapacity: 50,
rarity: 'common' as const,
quality: 100,
tags: [],
},
};
const equipped = { mainHand: 'test1', offHand: null, head: null, body: null, hands: null, feet: null, accessory1: null, accessory2: null };
const result = computeEquipmentEffects(instances, equipped);
// Should at least not crash and return a valid structure
expect(result).toHaveProperty('bonuses');
expect(result).toHaveProperty('multipliers');
expect(result).toHaveProperty('specials');
});
});
// ─── Test: File size limits ────────────────────────────────────────────────────
describe('File size limits (400 lines max)', () => {
it('EquipmentTab.tsx is under 400 lines', async () => {
const fs = await import('fs');
const path = await import('path');
const filePath = path.join(__dirname, 'EquipmentTab.tsx');
const content = fs.readFileSync(filePath, 'utf-8');
const lines = content.split('\n').length;
expect(lines).toBeLessThan(400);
});
it('EquipmentSlotGrid.tsx is under 400 lines', async () => {
const fs = await import('fs');
const path = await import('path');
const filePath = path.join(__dirname, 'EquipmentTab/EquipmentSlotGrid.tsx');
const content = fs.readFileSync(filePath, 'utf-8');
const lines = content.split('\n').length;
expect(lines).toBeLessThan(400);
});
it('InventoryList.tsx is under 400 lines', async () => {
const fs = await import('fs');
const path = await import('path');
const filePath = path.join(__dirname, 'EquipmentTab/InventoryList.tsx');
const content = fs.readFileSync(filePath, 'utf-8');
const lines = content.split('\n').length;
expect(lines).toBeLessThan(400);
});
it('EquipmentEffectsSummary.tsx is under 400 lines', async () => {
const fs = await import('fs');
const path = await import('path');
const filePath = path.join(__dirname, 'EquipmentTab/EquipmentEffectsSummary.tsx');
const content = fs.readFileSync(filePath, 'utf-8');
const lines = content.split('\n').length;
expect(lines).toBeLessThan(400);
});
});