longevity: test unitari e di sessione per la regola dei gruppi (#13)

motore-fisici-gruppi.test.ts (nuovo): un caso per ogni alternativa che da
punteggio (handgrip/spinta/arti_inferiori/vo2max/hrr/flamingo/back_scratch,
media dx/sx e storico), un lato solo -> nessun punteggio, recenza fra
alternative (pushup/panca in entrambe le direzioni), alternativa piu recente
ma incompleta esclusa (sit-to-stand senza altezza), i test "solo registrati"
non producono chiavi.

motore-fisici-sessione.test.ts: due nuovi casi end-to-end su DB (due sessioni,
due test diversi per la stessa sotto-metrica) che confermano che lo score usa
il test piu recente, in entrambe le direzioni.

Refs #13

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-27 22:48:07 +02:00
parent abd0626ab0
commit f57a07a964
2 changed files with 214 additions and 0 deletions
@@ -16,6 +16,7 @@ import { apriSessione, registraMisure } from '../../src/lib/longevity/misure';
import { calcolaSessione, sottoDominiDellaSessione, misureValideAlla } from '../../src/lib/longevity/motore';
import { sottoDominiFisici } from '../../src/lib/longevity/motore/fisici';
import { campiDelQuestionario } from '../../src/lib/longevity/vista';
import * as F from '../../src/lib/longevity/motore/test-fisici'; // per i valori attesi della regola dei gruppi (#13)
function dbPronto(clientCode: string, sesso: 'M' | 'F' = 'M') {
const db = createLongevityDb(':memory:');
@@ -232,6 +233,40 @@ describe('un check-up e un questionario sono sessioni separate, ma un cliente e
});
});
describe('la regola dei gruppi (#13) su un DB vero: due sessioni, lo score usa il test piu recente', () => {
it('pushup a gennaio, panca a marzo: il check-up di marzo usa la panca', () => {
const db = dbPronto('ISL-0030', 'M');
const sGennaio = apriSessione(db, { client_code: 'ISL-0030', data: '2026-01-15', tipo: 'checkup', eta_alla_data: 38 });
registraMisure(db, sGennaio, 'manuale', [
{ test_id: 'f_peso_kg', valore_num: 80 },
{ test_id: 'f_pushup_rip', valore_num: 24 },
]);
const sMarzo = apriSessione(db, { client_code: 'ISL-0030', data: '2026-03-10', tipo: 'checkup', eta_alla_data: 38 });
registraMisure(db, sMarzo, 'manuale', [
{ test_id: 'f_panca_bil_carico_kg', valore_num: 60 }, { test_id: 'f_panca_bil_rip', valore_num: 8 },
]);
// misureValideAlla porta avanti ANCHE il pushup di gennaio (mai sovrascritto): al check-up
// di marzo il gruppo "spinta" vede entrambe le alternative complete, e vince la piu recente.
const sd = sottoDominiDellaSessione(db, sMarzo);
expect(sd.spinta).toBeCloseTo(F.scoreSollevamentoSuPeso(60, 80, 8, F.TIERS_BENCH_M, F.TIERS_BENCH_F, 'M'), 5);
});
it('panca a gennaio, pushup a marzo: il check-up di marzo usa il pushup (il contrario del caso sopra)', () => {
const db = dbPronto('ISL-0031', 'M');
const sGennaio = apriSessione(db, { client_code: 'ISL-0031', data: '2026-01-15', tipo: 'checkup', eta_alla_data: 38 });
registraMisure(db, sGennaio, 'manuale', [
{ test_id: 'f_peso_kg', valore_num: 80 },
{ test_id: 'f_panca_bil_carico_kg', valore_num: 60 }, { test_id: 'f_panca_bil_rip', valore_num: 8 },
]);
const sMarzo = apriSessione(db, { client_code: 'ISL-0031', data: '2026-03-10', tipo: 'checkup', eta_alla_data: 38 });
registraMisure(db, sMarzo, 'manuale', [{ test_id: 'f_pushup_rip', valore_num: 24 }]);
const sd = sottoDominiDellaSessione(db, sMarzo);
expect(sd.spinta).toBeCloseTo(F.scorePushup(24, 38, 'M'), 5);
});
});
describe('campiDelQuestionario resta un modulo di sole domande', () => {
it('nessun campo f_* (test fisico) compare fra i campi del questionario', () => {
const db = createLongevityDb(':memory:');