import React, { useState } from 'react'; import { describe, it, expect, vi } from 'vitest'; import { render, fireEvent, screen } from '@testing-library/react'; import { PixelNumberInput } from '../../forms/PixelNumberInput'; describe('PixelNumberInput', () => { it('renders default value', () => { const { container } = render(); const input = container.querySelector('input[inputmode="decimal"]') as HTMLInputElement; expect(input).toBeTruthy(); expect(input.value).toBe('5'); }); it('up button increments by step', () => { const onChange = vi.fn(); render(); const up = screen.getByRole('button', { name: /increment/i }); fireEvent.click(up); expect(onChange).toHaveBeenCalledWith(5); }); it('down button decrements', () => { const onChange = vi.fn(); render(); const down = screen.getByRole('button', { name: /decrement/i }); fireEvent.click(down); expect(onChange).toHaveBeenCalledWith(2); }); it('min clamps when clampBehavior="strict"', () => { const onChange = vi.fn(); const { container } = render( , ); const input = container.querySelector('input[inputmode="decimal"]') as HTMLInputElement; fireEvent.change(input, { target: { value: '-3' } }); // strict clamps to min expect(onChange).toHaveBeenLastCalledWith(0); }); it('precision=2 formats with 2 decimals on blur', () => { const { container } = render(); const input = container.querySelector('input[inputmode="decimal"]') as HTMLInputElement; fireEvent.focus(input); fireEvent.blur(input); expect(input.value).toBe('3.50'); }); it('prefix renders before input', () => { const { container, getByText } = render(); expect(getByText('$')).toBeTruthy(); const input = container.querySelector('input[inputmode="decimal"]') as HTMLInputElement; expect(input).toBeTruthy(); }); it('allowNegative=false strips minus on input', () => { const onChange = vi.fn(); const { container } = render( , ); const input = container.querySelector('input[inputmode="decimal"]') as HTMLInputElement; fireEvent.change(input, { target: { value: '-42' } }); // minus stripped → 42 expect(onChange).toHaveBeenLastCalledWith(42); expect(input.value).not.toContain('-'); }); it('controlled mode tracks value prop', () => { function Wrap() { const [v, setV] = useState(2); return ( <> ); } const { container, getByText } = render(); const input = container.querySelector('input[inputmode="decimal"]') as HTMLInputElement; expect(input.value).toBe('2'); fireEvent.click(getByText('set99')); expect(input.value).toBe('99'); }); });