Files
CRAPP/test/unit/molla.test.ts
T
davideandClaude Opus 5 1ff650ecd5 Aggiunge i test della proiezione del momento
`proietta()` decide dove atterra uno swipe, quindi è la funzione che rompe il
gesto se sbaglia: il test copre segno, simmetria, linearità nella velocità e
il valore atteso della decelerazione esponenziale (1000 px/s -> ~499 px).
Copre anche i preset di `molla`, per evitare che un rimbalzo finisca per
sbaglio sul default o che una durata esca dalla scala utile.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 12:42:11 +02:00

37 lines
1.8 KiB
TypeScript

/** Check della proiezione del momento: `bun test/unit/molla.test.ts`. */
import assert from "node:assert/strict";
import { molla, proietta } from "@/lib/molla";
// --- proietta: da fermo non si va da nessuna parte ----------------------------
assert.equal(proietta(0), 0, "velocità zero non proietta nulla");
// --- proietta: il segno segue la direzione del gesto --------------------------
assert.ok(proietta(500) > 0, "un gesto verso destra proietta a destra");
assert.ok(proietta(-500) < 0, "un gesto verso sinistra proietta a sinistra");
assert.equal(proietta(-500), -proietta(500), "la proiezione è simmetrica");
// --- proietta: più veloce vai, più lontano arrivi (proporzionale) -------------
assert.ok(proietta(1000) > proietta(500), "più velocità, più distanza");
assert.equal(proietta(1000), 2 * proietta(500), "la distanza è lineare nella velocità");
// --- proietta: i valori sono quelli della decelerazione esponenziale di iOS ----
// v/1000 * d / (1 - d) con d = 0.998 → 1000 px/s proietta 499 px.
assert.ok(
Math.abs(proietta(1000) - 499) < 0.5,
`1000 px/s deve proiettare ~499 px, non ${proietta(1000)}`,
);
// Una decelerazione più bassa frena prima: serve per gesti più "corti".
assert.ok(proietta(1000, 0.99) < proietta(1000, 0.998), "meno decelerazione, meno corsa");
// --- molla: i preset restano nel dominio utile di bounce/duration -------------
for (const [nome, preset] of Object.entries(molla)) {
assert.equal(preset.type, "spring", `${nome} deve essere una molla`);
assert.ok(preset.bounce >= 0 && preset.bounce < 1, `${nome}: bounce fuori scala`);
assert.ok(preset.duration > 0 && preset.duration <= 1, `${nome}: duration fuori scala`);
}
assert.equal(molla.ui.bounce, 0, "il default non deve sorpassare il target");
assert.ok(molla.slancio.bounce > 0, "il preset da gesto ha un rimbalzo");
console.log("molla: ok");