import { describe, it, expect, beforeEach } from 'vitest' import { createInitialState, applyAction, checkVittoria, checkVittoriaPartita, punteggio, setVinti, servizio, } from '../../src/gameState.js' // ============================================= // HELPER // Lo stato non memorizza più punteggio/set/servizio direttamente: // si ricavano dalla striscia tramite le funzioni pure esportate. // ============================================= // Punteggio del set in corso const puntDi = (s) => punteggio(s.sp.striscia) // Set vinti nel match const setDi = (s) => setVinti(s.sp.striscia) // true se serve Home const servDi = (s) => servizio(s.sp.striscia) // Imposta chi serve a inizio set (set in corso a 0-0) function setServizioIniziale(state, team) { state.sp.striscia.at(-1).serv = team === 'home' ? 'h' : 'g' } // Imposta il punteggio del set in corso costruendo una ris coerente function setPunteggio(state, home, guest) { state.sp.striscia.at(-1).ris = 'h'.repeat(home) + 'g'.repeat(guest) } // Aggiunge set già conclusi (vinti) PRIMA del set in corso function setSetVinti(state, home, guest) { const conclusi = [] for (let i = 0; i < home; i++) conclusi.push({ serv: 'h', ris: '', vinc: 'h' }) for (let i = 0; i < guest; i++) conclusi.push({ serv: 'g', ris: '', vinc: 'g' }) state.sp.striscia = [...conclusi, state.sp.striscia.at(-1)] } describe('Game Logic (gameState.js)', () => { let state beforeEach(() => { state = createInitialState() }) // ============================================= // STATO INIZIALE // ============================================= describe('Stato iniziale', () => { it('dovrebbe iniziare con 0-0', () => { expect(puntDi(state).home).toBe(0) expect(puntDi(state).guest).toBe(0) }) it('dovrebbe avere i set a 0', () => { expect(setDi(state).home).toBe(0) expect(setDi(state).guest).toBe(0) }) it('dovrebbe avere servizio Home', () => { expect(servDi(state)).toBe(true) }) it('dovrebbe avere formazione di default [1-6]', () => { expect(state.sp.form.home).toEqual(["1", "2", "3", "4", "5", "6"]) expect(state.sp.form.guest).toEqual(["1", "2", "3", "4", "5", "6"]) }) it('dovrebbe avere la striscia iniziale con un set vuoto', () => { expect(state.sp.striscia).toHaveLength(1) expect(state.sp.striscia[0].serv).toBe('h') expect(state.sp.striscia[0].ris).toBe('') }) it('dovrebbe avere modalità 3/5 di default', () => { expect(state.modalitaPartita).toBe("3/5") }) it('dovrebbe avere visuForm false e visuStriscia true', () => { expect(state.visuForm).toBe(false) expect(state.visuStriscia).toBe(true) }) }) // ============================================= // IMMUTABILITÀ // ============================================= describe('Immutabilità', () => { it('applyAction non dovrebbe mutare lo stato originale', () => { const original = JSON.stringify(state) applyAction(state, { type: 'incPunt', team: 'home' }) expect(JSON.stringify(state)).toBe(original) }) it('dovrebbe restituire un nuovo oggetto', () => { const newState = applyAction(state, { type: 'incPunt', team: 'home' }) expect(newState).not.toBe(state) }) }) // ============================================= // INCREMENTO PUNTI (incPunt) // ============================================= describe('incPunt', () => { it('dovrebbe incrementare i punti Home', () => { const newState = applyAction(state, { type: 'incPunt', team: 'home' }) expect(puntDi(newState).home).toBe(1) expect(puntDi(newState).guest).toBe(0) }) it('dovrebbe incrementare i punti Guest', () => { const newState = applyAction(state, { type: 'incPunt', team: 'guest' }) expect(puntDi(newState).guest).toBe(1) expect(puntDi(newState).home).toBe(0) }) it('dovrebbe gestire il cambio palla (Guest segna, batteva Home)', () => { setServizioIniziale(state, 'home') const s1 = applyAction(state, { type: 'incPunt', team: 'guest' }) expect(servDi(s1)).toBe(false) }) it('dovrebbe gestire il cambio palla (Home segna, batteva Guest)', () => { setServizioIniziale(state, 'guest') const s1 = applyAction(state, { type: 'incPunt', team: 'home' }) expect(servDi(s1)).toBe(true) }) it('non dovrebbe cambiare palla se segna chi batte', () => { setServizioIniziale(state, 'home') const s1 = applyAction(state, { type: 'incPunt', team: 'home' }) expect(servDi(s1)).toBe(true) }) it('dovrebbe ruotare la formazione al cambio palla', () => { setServizioIniziale(state, 'home') state.sp.form.guest = ["1", "2", "3", "4", "5", "6"] const newState = applyAction(state, { type: 'incPunt', team: 'guest' }) expect(newState.sp.form.guest).toEqual(["2", "3", "4", "5", "6", "1"]) }) it('non dovrebbe ruotare la formazione se non c\'è cambio palla', () => { setServizioIniziale(state, 'home') state.sp.form.home = ["1", "2", "3", "4", "5", "6"] const newState = applyAction(state, { type: 'incPunt', team: 'home' }) expect(newState.sp.form.home).toEqual(["1", "2", "3", "4", "5", "6"]) }) it('dovrebbe aggiornare la striscia per punto Home', () => { const s = applyAction(state, { type: 'incPunt', team: 'home' }) expect(s.sp.striscia.at(-1).ris).toBe('h') }) it('dovrebbe aggiornare la striscia per punto Guest', () => { const s = applyAction(state, { type: 'incPunt', team: 'guest' }) expect(s.sp.striscia.at(-1).ris).toBe('g') }) it('dovrebbe registrare scorer nella striscia', () => { let s = applyAction(state, { type: 'incPunt', team: 'home' }) s = applyAction(s, { type: 'incPunt', team: 'guest' }) s = applyAction(s, { type: 'incPunt', team: 'home' }) expect(s.sp.striscia.at(-1).ris).toBe('hgh') }) it('non dovrebbe incrementare i punti dopo vittoria', () => { setPunteggio(state, 25, 23) const s = applyAction(state, { type: 'incPunt', team: 'home' }) expect(puntDi(s).home).toBe(25) }) }) // ============================================= // DECREMENTO PUNTI (decPunt) // ============================================= describe('decPunt', () => { it('dovrebbe annullare l\'ultimo punto Home', () => { const s1 = applyAction(state, { type: 'incPunt', team: 'home' }) const s2 = applyAction(s1, { type: 'decPunt' }) expect(puntDi(s2).home).toBe(0) expect(puntDi(s2).guest).toBe(0) }) it('dovrebbe annullare l\'ultimo punto Guest', () => { const s1 = applyAction(state, { type: 'incPunt', team: 'guest' }) const s2 = applyAction(s1, { type: 'decPunt' }) expect(puntDi(s2).home).toBe(0) expect(puntDi(s2).guest).toBe(0) }) it('non dovrebbe fare nulla sullo stato iniziale', () => { const s = applyAction(state, { type: 'decPunt' }) expect(puntDi(s).home).toBe(0) expect(puntDi(s).guest).toBe(0) }) it('dovrebbe ripristinare il servizio dopo undo con cambio palla', () => { setServizioIniziale(state, 'home') const s1 = applyAction(state, { type: 'incPunt', team: 'guest' }) expect(servDi(s1)).toBe(false) const s2 = applyAction(s1, { type: 'decPunt' }) expect(servDi(s2)).toBe(true) }) it('dovrebbe invertire la rotazione dopo undo con cambio palla', () => { setServizioIniziale(state, 'home') state.sp.form.guest = ["1", "2", "3", "4", "5", "6"] const s1 = applyAction(state, { type: 'incPunt', team: 'guest' }) expect(s1.sp.form.guest).toEqual(["2", "3", "4", "5", "6", "1"]) const s2 = applyAction(s1, { type: 'decPunt' }) expect(s2.sp.form.guest).toEqual(["1", "2", "3", "4", "5", "6"]) }) it('dovrebbe ripristinare la striscia', () => { const s1 = applyAction(state, { type: 'incPunt', team: 'home' }) const s2 = applyAction(s1, { type: 'decPunt' }) expect(s2.sp.striscia.at(-1).ris).toBe('') }) it('dovrebbe gestire undo multipli in sequenza', () => { let s = state s = applyAction(s, { type: 'incPunt', team: 'home' }) s = applyAction(s, { type: 'incPunt', team: 'guest' }) s = applyAction(s, { type: 'incPunt', team: 'home' }) expect(puntDi(s).home).toBe(2) expect(puntDi(s).guest).toBe(1) s = applyAction(s, { type: 'decPunt' }) expect(puntDi(s).home).toBe(1) s = applyAction(s, { type: 'decPunt' }) expect(puntDi(s).guest).toBe(0) s = applyAction(s, { type: 'decPunt' }) expect(puntDi(s).home).toBe(0) }) }) // ============================================= // FORMAZIONE DI PARTENZA (formInizio) // ============================================= describe('formInizio', () => { it('dovrebbe salvare la formazione corrente al primo punto del set', () => { const s = applyAction(state, { type: 'incPunt', team: 'home' }) expect(s.sp.striscia.at(-1).formInizio).toEqual({ home: ["1", "2", "3", "4", "5", "6"], guest: ["1", "2", "3", "4", "5", "6"], }) }) it('formInizio è uno snapshot: la rotazione successiva non lo modifica', () => { setServizioIniziale(state, 'home') // 1° punto Home: nessun cambio palla, salva formInizio let s = applyAction(state, { type: 'incPunt', team: 'home' }) // 2° punto Guest: cambio palla → ruota la formazione guest s = applyAction(s, { type: 'incPunt', team: 'guest' }) expect(s.sp.form.guest).toEqual(["2", "3", "4", "5", "6", "1"]) // lo snapshot resta quello iniziale expect(s.sp.striscia.at(-1).formInizio.guest).toEqual(["1", "2", "3", "4", "5", "6"]) }) it('decPunt che riporta il set a 0-0 cancella formInizio', () => { const s1 = applyAction(state, { type: 'incPunt', team: 'home' }) expect(s1.sp.striscia.at(-1).formInizio).toBeDefined() const s2 = applyAction(s1, { type: 'decPunt' }) expect(s2.sp.striscia.at(-1).formInizio).toBeUndefined() }) it('decPunt con punti ancora presenti NON cancella formInizio', () => { let s = applyAction(state, { type: 'incPunt', team: 'home' }) s = applyAction(s, { type: 'incPunt', team: 'home' }) s = applyAction(s, { type: 'decPunt' }) expect(s.sp.striscia.at(-1).ris).toBe('h') expect(s.sp.striscia.at(-1).formInizio).toBeDefined() }) it('ogni set mantiene la propria formInizio', () => { const custom = ['7', '8', '9', '10', '11', '12'] let s = applyAction(state, { type: 'setFormazione', team: 'home', form: custom }) // primo punto del set 1: salva formInizio custom s = applyAction(s, { type: 'incPunt', team: 'home' }) // chiude il set 1 e ne apre uno nuovo (formazioni resettate a default) s = applyAction(s, { type: 'nuovoSet', team: 'home' }) // primo punto del set 2: salva formInizio default s = applyAction(s, { type: 'incPunt', team: 'home' }) expect(s.sp.striscia[0].formInizio.home).toEqual(custom) expect(s.sp.striscia.at(-1).formInizio.home).toEqual(['1', '2', '3', '4', '5', '6']) }) }) // ============================================= // INCREMENTO SET (incSet) // ============================================= describe('incSet', () => { it('dovrebbe incrementare il set Home', () => { const s = applyAction(state, { type: 'incSet', team: 'home' }) expect(setDi(s).home).toBe(1) }) it('dovrebbe incrementare il set Guest', () => { const s = applyAction(state, { type: 'incSet', team: 'guest' }) expect(setDi(s).guest).toBe(1) }) it('dovrebbe fare wrap da 2 a 0', () => { let s = applyAction(state, { type: 'incSet', team: 'home' }) s = applyAction(s, { type: 'incSet', team: 'home' }) expect(setDi(s).home).toBe(2) s = applyAction(s, { type: 'incSet', team: 'home' }) expect(setDi(s).home).toBe(0) }) it('dovrebbe incrementare da 1 a 2', () => { let s = applyAction(state, { type: 'incSet', team: 'home' }) expect(setDi(s).home).toBe(1) s = applyAction(s, { type: 'incSet', team: 'home' }) expect(setDi(s).home).toBe(2) }) }) // ============================================= // NUOVO SET (nuovoSet) // ============================================= describe('nuovoSet', () => { it('dovrebbe incrementare il set della squadra vincente', () => { const s = applyAction(state, { type: 'nuovoSet', team: 'home' }) expect(setDi(s).home).toBe(1) expect(setDi(s).guest).toBe(0) }) it('dovrebbe azzerare i punti nel nuovo set', () => { setPunteggio(state, 25, 10) const s = applyAction(state, { type: 'nuovoSet', team: 'home' }) expect(puntDi(s).home).toBe(0) expect(puntDi(s).guest).toBe(0) }) it('dovrebbe aggiungere un nuovo set vuoto alla striscia', () => { const s = applyAction(state, { type: 'nuovoSet', team: 'home' }) expect(s.sp.striscia).toHaveLength(2) expect(s.sp.striscia.at(-1).ris).toBe('') expect(s.sp.striscia.at(-1).serv).toBe('h') }) it('dovrebbe conservare il set precedente nella striscia', () => { state.sp.striscia[0].ris = 'hgh' const s = applyAction(state, { type: 'nuovoSet', team: 'home' }) expect(s.sp.striscia[0].ris).toBe('hgh') }) it('dovrebbe resettare le formazioni', () => { state.sp.form.home = ['7', '8', '9', '10', '11', '12'] state.sp.form.guest = ['7', '8', '9', '10', '11', '12'] const s = applyAction(state, { type: 'nuovoSet', team: 'home' }) expect(s.sp.form.home).toEqual(['1', '2', '3', '4', '5', '6']) expect(s.sp.form.guest).toEqual(['1', '2', '3', '4', '5', '6']) }) it('dovrebbe ignorare team non valido', () => { const s = applyAction(state, { type: 'nuovoSet', team: 'invalid' }) expect(setDi(s).home).toBe(0) expect(setDi(s).guest).toBe(0) }) it('in 2/3 alla palla match registra il set vincente senza aprirne uno nuovo', () => { state.modalitaPartita = '2/3' setSetVinti(state, 1, 0) setPunteggio(state, 25, 18) const s = applyAction(state, { type: 'nuovoSet', team: 'home' }) expect(setDi(s).home).toBe(2) expect(puntDi(s).home).toBe(25) expect(puntDi(s).guest).toBe(18) }) it('in 3/5 alla palla match registra il set vincente senza aprirne uno nuovo', () => { state.modalitaPartita = '3/5' setSetVinti(state, 2, 0) setPunteggio(state, 25, 20) const s = applyAction(state, { type: 'nuovoSet', team: 'home' }) expect(setDi(s).home).toBe(3) expect(puntDi(s).home).toBe(25) expect(puntDi(s).guest).toBe(20) }) it('dovrebbe ignorare nuovoSet se la partita è già finita', () => { state.modalitaPartita = '2/3' setSetVinti(state, 2, 0) const s = applyAction(state, { type: 'nuovoSet', team: 'home' }) expect(setDi(s).home).toBe(2) }) }) // ============================================= // VITTORIA PARTITA (checkVittoriaPartita) // ============================================= describe('checkVittoriaPartita', () => { it('in 2/3 restituisce false se nessuno ha 2 set', () => { state.modalitaPartita = '2/3' setSetVinti(state, 1, 0) expect(checkVittoriaPartita(state)).toBe(false) }) it('in 2/3 restituisce true se home ha 2 set', () => { state.modalitaPartita = '2/3' setSetVinti(state, 2, 0) expect(checkVittoriaPartita(state)).toBe(true) }) it('in 3/5 restituisce false se nessuno ha 3 set', () => { state.modalitaPartita = '3/5' setSetVinti(state, 2, 2) expect(checkVittoriaPartita(state)).toBe(false) }) it('in 3/5 restituisce true se guest ha 3 set', () => { state.modalitaPartita = '3/5' setSetVinti(state, 0, 3) expect(checkVittoriaPartita(state)).toBe(true) }) it('in amichevole restituisce sempre false', () => { state.modalitaPartita = 'amichevole' setSetVinti(state, 5, 0) expect(checkVittoriaPartita(state)).toBe(false) }) }) // ============================================= // CAMBIO PALLA (cambiaPalla) // ============================================= describe('cambiaPalla', () => { it('dovrebbe invertire il servizio a 0-0', () => { expect(servDi(state)).toBe(true) const s = applyAction(state, { type: 'cambiaPalla' }) expect(servDi(s)).toBe(false) }) it('dovrebbe tornare a Home con doppio toggle', () => { let s = applyAction(state, { type: 'cambiaPalla' }) s = applyAction(s, { type: 'cambiaPalla' }) expect(servDi(s)).toBe(true) }) it('non dovrebbe cambiare palla se il punteggio non è 0-0', () => { setPunteggio(state, 1, 0) const prima = servDi(state) const s = applyAction(state, { type: 'cambiaPalla' }) expect(servDi(s)).toBe(prima) }) it('non dovrebbe cambiare palla se Guest ha punti', () => { setPunteggio(state, 0, 3) const prima = servDi(state) const s = applyAction(state, { type: 'cambiaPalla' }) expect(servDi(s)).toBe(prima) }) }) // ============================================= // TOGGLE (toggleFormazione, toggleStriscia, toggleOrder) // ============================================= describe('Toggle', () => { it('toggleFormazione: false → true', () => { expect(state.visuForm).toBe(false) const s = applyAction(state, { type: 'toggleFormazione' }) expect(s.visuForm).toBe(true) }) it('toggleFormazione: true → false', () => { state.visuForm = true const s = applyAction(state, { type: 'toggleFormazione' }) expect(s.visuForm).toBe(false) }) it('toggleStriscia: true → false', () => { expect(state.visuStriscia).toBe(true) const s = applyAction(state, { type: 'toggleStriscia' }) expect(s.visuStriscia).toBe(false) }) it('toggleOrder: true → false', () => { expect(state.order).toBe(true) const s = applyAction(state, { type: 'toggleOrder' }) expect(s.order).toBe(false) }) }) // ============================================= // NOMI (setNomi) // ============================================= describe('setNomi', () => { it('dovrebbe aggiornare entrambi i nomi', () => { const s = applyAction(state, { type: 'setNomi', home: 'Volley A', guest: 'Volley B' }) expect(s.sp.nomi.home).toBe('Volley A') expect(s.sp.nomi.guest).toBe('Volley B') }) it('dovrebbe aggiornare solo il nome Home se guest è undefined', () => { const s = applyAction(state, { type: 'setNomi', home: 'Volley A' }) expect(s.sp.nomi.home).toBe('Volley A') expect(s.sp.nomi.guest).toBe('Guest') }) it('dovrebbe aggiornare solo il nome Guest se home è undefined', () => { const s = applyAction(state, { type: 'setNomi', guest: 'Volley B' }) expect(s.sp.nomi.home).toBe('Antoniana') expect(s.sp.nomi.guest).toBe('Volley B') }) }) // ============================================= // MODALITÀ (setModalita) // ============================================= describe('setModalita', () => { it('dovrebbe cambiare in 2/3', () => { const s = applyAction(state, { type: 'setModalita', modalita: '2/3' }) expect(s.modalitaPartita).toBe('2/3') }) it('dovrebbe cambiare in 3/5', () => { state.modalitaPartita = '2/3' const s = applyAction(state, { type: 'setModalita', modalita: '3/5' }) expect(s.modalitaPartita).toBe('3/5') }) }) // ============================================= // FORMAZIONE (setFormazione) // ============================================= describe('setFormazione', () => { it('dovrebbe sostituire la formazione Home', () => { const nuova = ["10", "11", "12", "13", "14", "15"] const s = applyAction(state, { type: 'setFormazione', team: 'home', form: nuova }) expect(s.sp.form.home).toEqual(nuova) }) it('dovrebbe sostituire la formazione Guest', () => { const nuova = ["7", "8", "9", "10", "11", "12"] const s = applyAction(state, { type: 'setFormazione', team: 'guest', form: nuova }) expect(s.sp.form.guest).toEqual(nuova) }) it('non dovrebbe modificare se manca team', () => { const s = applyAction(state, { type: 'setFormazione', form: ["7", "8", "9", "10", "11", "12"] }) expect(s.sp.form.home).toEqual(["1", "2", "3", "4", "5", "6"]) }) it('non dovrebbe modificare se manca form', () => { const s = applyAction(state, { type: 'setFormazione', team: 'home' }) expect(s.sp.form.home).toEqual(["1", "2", "3", "4", "5", "6"]) }) }) // ============================================= // CAMBI GIOCATORI (confermaCambi) // ============================================= describe('confermaCambi', () => { it('dovrebbe effettuare una sostituzione valida', () => { state.sp.form.home = ["1", "2", "3", "4", "5", "6"] const s = applyAction(state, { type: 'confermaCambi', team: 'home', cambi: [{ in: "10", out: "3" }] }) expect(s.sp.form.home).toContain("10") expect(s.sp.form.home).not.toContain("3") }) it('dovrebbe gestire doppia sostituzione', () => { state.sp.form.home = ["1", "2", "3", "4", "5", "6"] const s = applyAction(state, { type: 'confermaCambi', team: 'home', cambi: [ { in: "10", out: "1" }, { in: "11", out: "2" } ] }) expect(s.sp.form.home).toContain("10") expect(s.sp.form.home).toContain("11") expect(s.sp.form.home).not.toContain("1") expect(s.sp.form.home).not.toContain("2") }) it('non dovrebbe accettare input non numerico', () => { state.sp.form.home = ["1", "2", "3", "4", "5", "6"] const s = applyAction(state, { type: 'confermaCambi', team: 'home', cambi: [{ in: "abc", out: "1" }] }) expect(s.sp.form.home).toEqual(["1", "2", "3", "4", "5", "6"]) }) it('non dovrebbe accettare in == out', () => { const s = applyAction(state, { type: 'confermaCambi', team: 'home', cambi: [{ in: "1", out: "1" }] }) expect(s.sp.form.home).toEqual(["1", "2", "3", "4", "5", "6"]) }) it('non dovrebbe accettare giocatore IN già in formazione', () => { const s = applyAction(state, { type: 'confermaCambi', team: 'home', cambi: [{ in: "2", out: "1" }] }) expect(s.sp.form.home).toEqual(["1", "2", "3", "4", "5", "6"]) }) it('non dovrebbe accettare giocatore OUT non in formazione', () => { const s = applyAction(state, { type: 'confermaCambi', team: 'home', cambi: [{ in: "10", out: "99" }] }) expect(s.sp.form.home).toEqual(["1", "2", "3", "4", "5", "6"]) }) it('dovrebbe saltare cambi con campo vuoto', () => { const s = applyAction(state, { type: 'confermaCambi', team: 'home', cambi: [ { in: "", out: "" }, { in: "10", out: "1" } ] }) expect(s.sp.form.home).toContain("10") }) it('dovrebbe mantenere la posizione del giocatore sostituito', () => { state.sp.form.home = ["1", "2", "3", "4", "5", "6"] const s = applyAction(state, { type: 'confermaCambi', team: 'home', cambi: [{ in: "10", out: "3" }] }) expect(s.sp.form.home[2]).toBe("10") }) it('dovrebbe gestire cambi sequenziali che dipendono l\'uno dall\'altro', () => { // Sostituisci 1→10, poi 10→20 (il secondo dipende dal risultato del primo) state.sp.form.home = ["1", "2", "3", "4", "5", "6"] const s = applyAction(state, { type: 'confermaCambi', team: 'home', cambi: [ { in: "10", out: "1" }, { in: "20", out: "10" } ] }) expect(s.sp.form.home).toContain("20") expect(s.sp.form.home).not.toContain("1") expect(s.sp.form.home).not.toContain("10") }) }) // ============================================= // VITTORIA SET (checkVittoria) // ============================================= describe('checkVittoria', () => { it('non dovrebbe dare vittoria a 24-24', () => { setPunteggio(state, 24, 24) expect(checkVittoria(state)).toBe(false) }) it('dovrebbe dare vittoria a 25-23', () => { setPunteggio(state, 25, 23) expect(checkVittoria(state)).toBe(true) }) it('non dovrebbe dare vittoria a 25-24 (serve 2 punti di scarto)', () => { setPunteggio(state, 25, 24) expect(checkVittoria(state)).toBe(false) }) it('dovrebbe dare vittoria a 26-24', () => { setPunteggio(state, 26, 24) expect(checkVittoria(state)).toBe(true) }) it('dovrebbe dare vittoria Guest a 25-20', () => { setPunteggio(state, 20, 25) expect(checkVittoria(state)).toBe(true) }) it('dovrebbe dare vittoria ai vantaggi (30-28)', () => { setPunteggio(state, 30, 28) expect(checkVittoria(state)).toBe(true) }) it('non dovrebbe dare vittoria ai vantaggi senza scarto (28-27)', () => { setPunteggio(state, 28, 27) expect(checkVittoria(state)).toBe(false) }) }) // ============================================= // SET DECISIVO (15 punti) // ============================================= describe('Set decisivo', () => { it('modalità 3/5: set decisivo dopo 4 set totali → vittoria a 15', () => { state.modalitaPartita = "3/5" setSetVinti(state, 2, 2) setPunteggio(state, 15, 10) expect(checkVittoria(state)).toBe(true) }) it('modalità 3/5: non vittoria a 14-10 nel set decisivo', () => { state.modalitaPartita = "3/5" setSetVinti(state, 2, 2) setPunteggio(state, 14, 10) expect(checkVittoria(state)).toBe(false) }) it('modalità 3/5: vittoria a 15-13 nel set decisivo', () => { state.modalitaPartita = "3/5" setSetVinti(state, 2, 2) setPunteggio(state, 15, 13) expect(checkVittoria(state)).toBe(true) }) it('modalità 3/5: non vittoria a 15-14 nel set decisivo (serve scarto)', () => { state.modalitaPartita = "3/5" setSetVinti(state, 2, 2) setPunteggio(state, 15, 14) expect(checkVittoria(state)).toBe(false) }) it('modalità 3/5: vittoria a 16-14 nel set decisivo', () => { state.modalitaPartita = "3/5" setSetVinti(state, 2, 2) setPunteggio(state, 16, 14) expect(checkVittoria(state)).toBe(true) }) it('modalità 2/3: set decisivo dopo 2 set totali → vittoria a 15', () => { state.modalitaPartita = "2/3" setSetVinti(state, 1, 1) setPunteggio(state, 15, 10) expect(checkVittoria(state)).toBe(true) }) it('modalità 2/3: non vittoria a 14-10 nel set decisivo (soglia 15)', () => { state.modalitaPartita = "2/3" setSetVinti(state, 1, 1) setPunteggio(state, 14, 10) expect(checkVittoria(state)).toBe(false) }) it('modalità 2/3: set non decisivo (1-0) → soglia 25', () => { state.modalitaPartita = "2/3" setSetVinti(state, 1, 0) setPunteggio(state, 15, 10) expect(checkVittoria(state)).toBe(false) }) it('modalità 3/5: set non decisivo (2-1) → soglia 25', () => { state.modalitaPartita = "3/5" setSetVinti(state, 2, 1) setPunteggio(state, 15, 10) expect(checkVittoria(state)).toBe(false) }) }) // ============================================= // RESET // ============================================= describe('Reset', () => { it('dovrebbe resettare punti e set a zero', () => { setSetVinti(state, 1, 1) setPunteggio(state, 10, 8) const s = applyAction(state, { type: 'resetta' }) expect(puntDi(s).home).toBe(0) expect(puntDi(s).guest).toBe(0) expect(setDi(s).home).toBe(0) expect(setDi(s).guest).toBe(0) }) it('dovrebbe resettare formazioni a default', () => { state.sp.form.home = ["10", "11", "12", "13", "14", "15"] const s = applyAction(state, { type: 'resetta' }) expect(s.sp.form.home).toEqual(["1", "2", "3", "4", "5", "6"]) expect(s.sp.form.guest).toEqual(["1", "2", "3", "4", "5", "6"]) }) it('dovrebbe resettare la striscia a un set vuoto', () => { state.sp.striscia = [{ serv: 'h', ris: 'hgh', vinc: 'h' }, { serv: 'h', ris: 'g', vinc: null }] const s = applyAction(state, { type: 'resetta' }) expect(s.sp.striscia).toHaveLength(1) expect(s.sp.striscia[0].ris).toBe('') }) it('dovrebbe impostare visuForm a false', () => { state.visuForm = true const s = applyAction(state, { type: 'resetta' }) expect(s.visuForm).toBe(false) }) it('dovrebbe mantenere nomi e modalità', () => { state.sp.nomi.home = "Squadra A" state.modalitaPartita = "2/3" const s = applyAction(state, { type: 'resetta' }) expect(s.sp.nomi.home).toBe("Squadra A") expect(s.modalitaPartita).toBe("2/3") }) }) // ============================================= // AZIONE SCONOSCIUTA // ============================================= describe('Azione sconosciuta', () => { it('dovrebbe restituire lo stato invariato con azione non riconosciuta', () => { const s = applyAction(state, { type: 'azioneInesistente' }) expect(puntDi(s).home).toBe(0) expect(puntDi(s).guest).toBe(0) }) }) })