import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { act, fireEvent, render, screen } from '@testing-library/react'; import { MEMORY_MAX_ATTEMPTS, MemoryGame } from '../../src/components/minigames/MemoryGame'; describe('MemoryGame', () => { beforeEach(() => { vi.useFakeTimers(); vi.spyOn(Math, 'random').mockReturnValue(0); }); afterEach(() => { vi.useRealTimers(); vi.restoreAllMocks(); }); it('renders all 12 cards and the attempt counter', () => { render(); expect(screen.getByText(/Memory Game/i)).toBeTruthy(); expect(screen.getByText(new RegExp(`Attempts: 0/${MEMORY_MAX_ATTEMPTS}`))).toBeTruthy(); expect(screen.getAllByRole('button').length).toBe(12); }); it('increments attempts per resolved turn', () => { render(); const cards = screen.getAllByRole('button'); fireEvent.click(cards[0]); fireEvent.click(cards[1]); act(() => { vi.advanceTimersByTime(850); }); expect(screen.getByText(/Attempts: 1\/18/i)).toBeTruthy(); }); it('fails when the turn budget is exhausted', () => { const onFail = vi.fn(); render(); for (let attempt = 0; attempt < MEMORY_MAX_ATTEMPTS; attempt += 1) { const cards = screen.getAllByRole('button'); fireEvent.click(cards[0]); fireEvent.click(cards[1]); act(() => { vi.advanceTimersByTime(850); }); } act(() => { vi.runOnlyPendingTimers(); }); expect(onFail).toHaveBeenCalledTimes(1); }); });