import { describe, it, expect } from 'vitest'; import { ReapproCalculator } from '@domain/services/ReapproCalculator'; describe('ReapproCalculator', () => { const calc = new ReapproCalculator(); it('empty target returns empty', () => { const r = calc.compute({ target: '', qty: 1, repro: {}, inverted: {} }); expect(r.steps).toHaveLength(0); expect(r.gen1Needs).toHaveLength(0); }); it('unknown target returns empty', () => { const r = calc.compute({ target: 'Unknown', qty: 1, repro: {}, inverted: {} }); expect(r.steps).toHaveLength(0); }); it('gen2 race needs 2 gen1 parents', () => { const r = calc.compute({ target: 'Dorée et Rousse', qty: 4, repro: {}, inverted: {} }); expect(r.steps).toHaveLength(1); expect(r.steps[0]!.parentA).toBe('Rousse'); expect(r.steps[0]!.parentB).toBe('Dorée'); expect(r.steps[0]!.couples).toBe(4); expect(r.gen1Needs).toHaveLength(2); expect(r.totalGen1).toBe(8); // 4 Rousse + 4 Dorée }); it('gender inversion swaps parents', () => { const r = calc.compute({ target: 'Dorée et Rousse', qty: 4, repro: {}, inverted: { 'Dorée et Rousse': true } }); expect(r.steps[0]!.parentA).toBe('Dorée'); expect(r.steps[0]!.parentB).toBe('Rousse'); }); it('breeders reduce couple count', () => { const r = calc.compute({ target: 'Dorée et Rousse', qty: 4, repro: { 'Dorée et Rousse': 2 }, inverted: {} }); expect(r.steps[0]!.couples).toBe(2); }); it('gen1 needs include male/female split', () => { const r = calc.compute({ target: 'Dorée et Rousse', qty: 2, repro: {}, inverted: {} }); const rousse = r.gen1Needs.find(n => n.name === 'Rousse'); const doree = r.gen1Needs.find(n => n.name === 'Dorée'); expect(rousse).toBeDefined(); expect(doree).toBeDefined(); // Default: parentA (Rousse) = male, parentB (Dorée) = female expect(rousse!.m).toBe(2); expect(doree!.f).toBe(2); }); });