import { render, screen, fireEvent } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest'; // Mock next-intl — returns the real de.json strings for the few keys this // widget actually renders as accessible names/labels, the raw key otherwise // (locale-agnostic fallback for anything not explicitly mapped here). vi.mock('next-intl', () => ({ useTranslations: () => (key: string) => { const map: Record = { 'calculator.name': 'Taschenrechner', 'calculator.displayLabel': 'Anzeige', 'calculator.memoryLabel': 'Speicherfunktionen', 'calculator.backspaceLabel': 'Rückschritt', }; return map[key] ?? key; }, })); // Must import after mocks import { CalculatorWidget } from './calculator-widget'; const defaultProps = { instanceId: 'calc-1', config: {}, isEditMode: false, }; describe('CalculatorWidget', () => { it('renders with initial display "0"', () => { render(); const display = screen.getByLabelText('Anzeige'); expect(display).toHaveTextContent('0'); }); it('calculates 7 + 3 = 10', () => { render(); fireEvent.click(screen.getByRole('button', { name: '7' })); fireEvent.click(screen.getByRole('button', { name: '+' })); fireEvent.click(screen.getByRole('button', { name: '3' })); fireEvent.click(screen.getByRole('button', { name: /gleich/i })); expect(screen.getByLabelText('Anzeige')).toHaveTextContent('10'); }); it('calculates 8 × 2 = 16', () => { render(); fireEvent.click(screen.getByRole('button', { name: '8' })); fireEvent.click(screen.getByRole('button', { name: '×' })); fireEvent.click(screen.getByRole('button', { name: '2' })); fireEvent.click(screen.getByRole('button', { name: /gleich/i })); expect(screen.getByLabelText('Anzeige')).toHaveTextContent('16'); }); it('shows "Fehler" on division by zero', () => { render(); fireEvent.click(screen.getByRole('button', { name: '5' })); fireEvent.click(screen.getByRole('button', { name: '÷' })); fireEvent.click(screen.getByRole('button', { name: '0' })); fireEvent.click(screen.getByRole('button', { name: /gleich/i })); expect(screen.getByLabelText('Anzeige')).toHaveTextContent('Fehler'); }); it('handles keyboard input: 5 * 6 Enter = 30', () => { render(); const container = screen.getByRole('application'); fireEvent.keyDown(container, { key: '5' }); fireEvent.keyDown(container, { key: '*' }); fireEvent.keyDown(container, { key: '6' }); fireEvent.keyDown(container, { key: 'Enter' }); expect(screen.getByLabelText('Anzeige')).toHaveTextContent('30'); }); it('handles decimal comma: 1,5 + 1,5 = 3', () => { render(); fireEvent.click(screen.getByRole('button', { name: '1' })); fireEvent.click(screen.getByRole('button', { name: ',' })); fireEvent.click(screen.getByRole('button', { name: '5' })); fireEvent.click(screen.getByRole('button', { name: '+' })); fireEvent.click(screen.getByRole('button', { name: '1' })); fireEvent.click(screen.getByRole('button', { name: ',' })); fireEvent.click(screen.getByRole('button', { name: '5' })); fireEvent.click(screen.getByRole('button', { name: /gleich/i })); expect(screen.getByLabelText('Anzeige')).toHaveTextContent('3'); }); it('quick-260916-bwo: Anzeige und Tasten tragen Container-Query-Klassen, Tasten fuellen ihre Zelle', () => { render(); expect(screen.getByLabelText('Anzeige').className).toMatch(/cqw/); const seven = screen.getByRole('button', { name: '7' }); expect(seven.className).toMatch(/cqw/); expect(seven.className).toContain('h-full'); expect(screen.getByRole('button', { name: 'CE' }).className).toMatch(/cqw/); }); });