import * as React from 'react'; import { cleanup, render, screen, } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { TextControl } from '@tesseract-design/web-base'; import { vi, expect, describe, it, afterEach, } from 'vitest'; import matchers from '@testing-library/jest-dom/matchers'; import { NumberSpinner, NumberSpinnerDerivedElement, } from '.'; expect.extend(matchers); describe('NumberSpinner', () => { afterEach(() => { cleanup(); }); it('renders a number input', () => { render( , ); const textbox = screen.getByTestId('input'); expect(textbox).toBeInTheDocument(); expect(textbox).toHaveProperty('type', 'number'); }); it('renders a border', () => { render( , ); const border = screen.getByTestId('border'); expect(border).toBeInTheDocument(); }); it('renders a label', () => { render( , ); const textbox = screen.getByLabelText('foo'); expect(textbox).toBeInTheDocument(); const label = screen.getByTestId('label'); expect(label).toHaveTextContent('foo'); }); it('renders a hidden label', () => { render( , ); const textbox = screen.getByLabelText('foo'); expect(textbox).toBeInTheDocument(); const label = screen.queryByTestId('label'); expect(label).toBeInTheDocument(); expect(label).toHaveClass('sr-only'); }); it('renders a hint', () => { render( , ); const hint = screen.getByTestId('hint'); expect(hint).toBeInTheDocument(); }); it('renders an indicator', () => { render( , ); const indicator = screen.getByTestId('indicator'); expect(indicator).toBeInTheDocument(); }); describe.each` size | inputClassName | hintClassName | indicatorClassName ${'small'} | ${'h-10'} | ${'pr-10'} | ${'w-10'} ${'medium'} | ${'h-12'} | ${'pr-12'} | ${'w-12'} ${'large'} | ${'h-16'} | ${'pr-16'} | ${'w-16'} `('on $size size', ({ size, inputClassName, hintClassName, indicatorClassName, }: { size: TextControl.Size, inputClassName: string, hintClassName: string, indicatorClassName: string, }) => { it('renders input styles', () => { render( , ); const input = screen.getByTestId('input'); expect(input).toHaveClass(inputClassName); }); it('renders label styles with indicator', () => { render( , ); const label = screen.getByTestId('label'); expect(label).toHaveClass(hintClassName); }); it('renders hint styles when indicator is present', () => { render( , ); const hint = screen.getByTestId('hint'); expect(hint).toHaveClass(hintClassName); }); it('renders indicator styles', () => { render( , ); const indicator = screen.getByTestId('indicator'); expect(indicator).toHaveClass(indicatorClassName); }); }); it('renders a block textbox', () => { render( , ); const base = screen.getByTestId('base'); expect(base).toHaveClass('block'); }); describe.each` variant | inputClassName | hintClassName ${'default'} | ${'pl-4'} | ${'bottom-0 pl-4 pb-1'} ${'alternate'} | ${'pl-1.5 pt-4'} | ${'top-0.5'} `('on $variant style', ({ variant, inputClassName, hintClassName, }: { variant: TextControl.Variant, inputClassName: string, hintClassName: string, }) => { it('renders input styles', () => { render( , ); const input = screen.getByTestId('input'); expect(input).toHaveClass(inputClassName); }); it('renders hint styles', () => { render( , ); const hint = screen.getByTestId('hint'); expect(hint).toHaveClass(hintClassName); }); }); it('handles change events', async () => { const onChange = vi.fn().mockImplementationOnce( (e: React.ChangeEvent) => { e.preventDefault(); }, ); render( , ); const textbox = screen.getByTestId('input'); await userEvent.type(textbox, '69420'); expect(onChange).toBeCalled(); }); it('handles input events', async () => { const onInput = vi.fn().mockImplementationOnce( (e: React.SyntheticEvent) => { e.preventDefault(); }, ); render( , ); const textbox = screen.getByTestId('input'); await userEvent.type(textbox, '69420'); expect(onInput).toBeCalled(); }); });