Applique .gitattributes sur tous les fichiers existants. Élimine les différences fantômes entre WSL et Windows. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
165 lines
6.1 KiB
TypeScript
Executable File
165 lines
6.1 KiB
TypeScript
Executable File
import { describe, it, expect } from 'vitest';
|
|
import { computeGaugeLive, enclosGlobalState, calcLevelEtaLive } from '@presentation/helpers/gauge-live';
|
|
import { xpForLevel } from '@domain/value-objects/XpTable';
|
|
import { timeToGain } from '@domain/services/GaugeCalculator';
|
|
import { createDragodinde } from '@domain/entities/Dragodinde';
|
|
import type { Enclos } from '@domain/entities/Enclos';
|
|
|
|
function makeEnclos(overrides: Partial<Enclos> = {}): Enclos {
|
|
return {
|
|
id: 1,
|
|
name: 'Test',
|
|
activeGauges: ['mangeoire'],
|
|
gaugeLevels: { baffeur: 0, caresseur: 0, foudroyeur: 0, abreuvoir: 0, dragofesse: 0, mangeoire: 50000 },
|
|
dragodindes: [createDragodinde(1)],
|
|
nextDdId: 2,
|
|
timer: { running: false, startTime: null, pausedAt: null, pausedMs: 0, snapGauges: {}, snapStats: {}, gaugeRecharges: {} },
|
|
alerted: {},
|
|
...overrides,
|
|
} as Enclos;
|
|
}
|
|
|
|
describe('Regression: timer prend en compte levelTarget', () => {
|
|
|
|
it('computeGaugeLive utilise levelTarget pour le countdown mangeoire', () => {
|
|
const enc = makeEnclos();
|
|
const dd = { ...enc.dragodindes[0]!, levelTarget: 10 };
|
|
|
|
const r = computeGaugeLive(enc, dd, 'mangeoire', 0, false);
|
|
|
|
// Avec levelTarget=10, xpNeeded = xpForLevel(10) - xpForLevel(1) = 809
|
|
const xpNeeded = xpForLevel(10) - xpForLevel(1);
|
|
expect(xpNeeded).toBe(809);
|
|
|
|
// Le countdown devrait être timeToGain(50000, 809)
|
|
const expectedSec = timeToGain(50000, 809);
|
|
expect(r.cntDown).toBe(expectedSec);
|
|
expect(r.done).toBe(false);
|
|
});
|
|
|
|
it('computeGaugeLive sans levelTarget utilise 200 par défaut', () => {
|
|
const enc = makeEnclos();
|
|
const dd = { ...enc.dragodindes[0]!, levelTarget: null };
|
|
|
|
const r = computeGaugeLive(enc, dd, 'mangeoire', 0, false);
|
|
|
|
// Avec levelTarget=null → 200, xpNeeded >> gauge level
|
|
// cntDown = timeToGain(50000, 50000) = drain time
|
|
const drainTime = timeToGain(50000, 50000);
|
|
expect(r.cntDown).toBe(drainTime);
|
|
});
|
|
|
|
it('levelTarget=10 donne un countdown beaucoup plus court que levelTarget=null', () => {
|
|
const enc = makeEnclos();
|
|
const ddWithTarget = { ...enc.dragodindes[0]!, levelTarget: 10 };
|
|
const ddWithoutTarget = { ...enc.dragodindes[0]!, levelTarget: null };
|
|
|
|
const rWith = computeGaugeLive(enc, ddWithTarget, 'mangeoire', 0, false);
|
|
const rWithout = computeGaugeLive(enc, ddWithoutTarget, 'mangeoire', 0, false);
|
|
|
|
// Avec target 10 : ~410 sec. Sans target (200) : ~45000 sec.
|
|
expect(rWith.cntDown).toBeLessThan(1000); // < ~16 minutes
|
|
expect(rWithout.cntDown).toBeGreaterThan(40000); // > ~11 heures
|
|
});
|
|
|
|
it('enclosGlobalState reflète le levelTarget dans globalMax', () => {
|
|
const enc = makeEnclos();
|
|
enc.dragodindes[0]!.levelTarget = 10;
|
|
|
|
const state = enclosGlobalState(enc);
|
|
// Avant démarrage, started=false → globalMax devrait refléter le target 10
|
|
expect(state.globalMax).toBeLessThan(1000);
|
|
});
|
|
|
|
it('enclosGlobalState sans levelTarget a un globalMax plus élevé', () => {
|
|
const enc = makeEnclos();
|
|
enc.dragodindes[0]!.levelTarget = null;
|
|
|
|
const state = enclosGlobalState(enc);
|
|
expect(state.globalMax).toBeGreaterThan(40000);
|
|
});
|
|
|
|
it('calcLevelEtaLive utilise levelTarget', () => {
|
|
const enc = makeEnclos();
|
|
const dd = { ...enc.dragodindes[0]!, levelTarget: 5 };
|
|
|
|
const eta = calcLevelEtaLive(enc, dd, 0, false);
|
|
// Level 1→5 needs 161 XP, timeToGain(50000, 161) = 90 sec
|
|
expect(eta).toContain('1m');
|
|
});
|
|
|
|
it('done=true quand estLevel >= levelTarget', () => {
|
|
const enc = makeEnclos();
|
|
// DD déjà au level 50, target 50
|
|
const dd = { ...enc.dragodindes[0]!, stats: { ...enc.dragodindes[0]!.stats, xp: 50 }, levelTarget: 50 };
|
|
|
|
const r = computeGaugeLive(enc, dd, 'mangeoire', 0, false);
|
|
expect(r.done).toBe(true);
|
|
expect(r.cntDown).toBe(0);
|
|
});
|
|
|
|
it('done=true quand estLevel > levelTarget', () => {
|
|
const enc = makeEnclos();
|
|
const dd = { ...enc.dragodindes[0]!, stats: { ...enc.dragodindes[0]!.stats, xp: 100 }, levelTarget: 50 };
|
|
|
|
const r = computeGaugeLive(enc, dd, 'mangeoire', 0, false);
|
|
expect(r.done).toBe(true);
|
|
});
|
|
|
|
it('timer en cours avec levelTarget=10 : countdown reflète le target', () => {
|
|
const now = Date.now();
|
|
const enc = makeEnclos({
|
|
timer: {
|
|
running: true,
|
|
startTime: now - 100_000, // 100 sec écoulées
|
|
pausedAt: null,
|
|
pausedMs: 0,
|
|
snapGauges: { mangeoire: 50000 },
|
|
snapStats: { '1': { serenite: 0, endurance: 0, maturite: 0, amour: 0, xp: 1 } },
|
|
gaugeRecharges: {},
|
|
},
|
|
});
|
|
|
|
const ddWithTarget = { ...enc.dragodindes[0]!, levelTarget: 10 };
|
|
const ddNoTarget = { ...enc.dragodindes[0]!, levelTarget: null };
|
|
|
|
const rWith = computeGaugeLive(enc, ddWithTarget, 'mangeoire', 100, true);
|
|
const rNo = computeGaugeLive(enc, ddNoTarget, 'mangeoire', 100, true);
|
|
|
|
// Avec target 10 : cntDown devrait être < 1000 (beaucoup moins que sans target)
|
|
// Sans target (200) : cntDown devrait être > 30000
|
|
expect(rWith.cntDown).toBeLessThan(rNo.cntDown);
|
|
// Plus spécifiquement, avec target 10 après 100sec, le target devrait presque être atteint
|
|
// xpNeeded = 809, et en 100sec (10 ticks) on gagne 10*20 = 200xp (tier 2)
|
|
// xpRestante = 809 - 200 = 609
|
|
expect(rWith.cntDown).toBeLessThan(500); // < 500 sec restantes
|
|
});
|
|
|
|
it('changer levelTarget pendant le timer met à jour le globalMax', () => {
|
|
const now = Date.now();
|
|
const enc = makeEnclos({
|
|
timer: {
|
|
running: true,
|
|
startTime: now - 50_000, // 50 sec écoulées
|
|
pausedAt: null,
|
|
pausedMs: 0,
|
|
snapGauges: { mangeoire: 50000 },
|
|
snapStats: { '1': { serenite: 0, endurance: 0, maturite: 0, amour: 0, xp: 1 } },
|
|
gaugeRecharges: {},
|
|
},
|
|
});
|
|
|
|
// D'abord sans target (level 200 par défaut)
|
|
enc.dragodindes[0]!.levelTarget = null;
|
|
const state1 = enclosGlobalState(enc);
|
|
|
|
// Puis avec target 10
|
|
enc.dragodindes[0]!.levelTarget = 10;
|
|
const state2 = enclosGlobalState(enc);
|
|
|
|
// Le globalMax devrait diminuer drastiquement
|
|
expect(state2.globalMax).toBeLessThan(state1.globalMax);
|
|
expect(state2.globalMax).toBeLessThan(1000);
|
|
});
|
|
});
|