|
- import * as React from 'react';
- import {
- cleanup,
- render,
- screen,
- } from '@testing-library/react';
- import { TextControl } from '@tesseract-design/web-base';
- import userEvent from '@testing-library/user-event';
- import {
- afterEach,
- expect,
- vi,
- describe,
- it,
- } from 'vitest';
- import matchers from '@testing-library/jest-dom/matchers';
- import {
- MenuSelect,
- MenuSelectDerivedElement,
- } from '.';
-
- expect.extend(matchers);
-
- describe('MenuSelect', () => {
- afterEach(() => {
- cleanup();
- });
-
- it('renders a listbox', () => {
- render(<MenuSelect />);
- const listbox = screen.getByRole('listbox');
- expect(listbox).toBeInTheDocument();
- });
-
- it('renders a border', () => {
- render(
- <MenuSelect
- border
- />,
- );
- const border = screen.getByTestId('border');
- expect(border).toBeInTheDocument();
- });
-
- it('renders a label', () => {
- render(
- <MenuSelect
- label="foo"
- />,
- );
- const listbox = screen.getByLabelText('foo');
- expect(listbox).toBeInTheDocument();
- const label = screen.getByTestId('label');
- expect(label).toHaveTextContent('foo');
- });
-
- it('renders a hidden label', () => {
- render(
- <MenuSelect
- label="foo"
- hiddenLabel
- />,
- );
- const listbox = screen.getByLabelText('foo');
- expect(listbox).toBeInTheDocument();
- const label = screen.getByTestId('label');
- expect(label).toHaveClass('sr-only');
- });
-
- it('renders a hint', () => {
- render(
- <MenuSelect
- hint="foo"
- />,
- );
- const hint = screen.getByTestId('hint');
- expect(hint).toBeInTheDocument();
- });
-
- it('render options with implicit values', () => {
- render(
- <MenuSelect>
- <option>foo</option>
- <option>bar</option>
- </MenuSelect>,
- );
- const listbox = screen.getByRole('listbox');
- expect(listbox.children).toHaveLength(2);
- });
-
- it('renders valid options', () => {
- render(
- <MenuSelect>
- <option value="foo">foo</option>
- <option value="bar">bar</option>
- </MenuSelect>,
- );
- const listbox = screen.getByRole('listbox');
- expect(listbox.children).toHaveLength(2);
- });
-
- it('renders option groups', () => {
- render(
- <MenuSelect>
- <optgroup label="foo">
- <option value="baz">baz</option>
- </optgroup>
- <optgroup label="bar">
- <option value="quux">quux</option>
- <option value="quuux">quuux</option>
- </optgroup>
- </MenuSelect>,
- );
- const listbox = screen.getByRole('listbox');
- expect(listbox.children).toHaveLength(2);
- expect(listbox.children[0].children).toHaveLength(1);
- expect(listbox.children[1].children).toHaveLength(2);
- });
-
- describe.each`
- size | inputClassNames | hintClassNames | indicatorClassNames
- ${'small'} | ${'min-h-10'} | ${'pr-10'} | ${'w-10'}
- ${'medium'} | ${'min-h-12'} | ${'pr-12'} | ${'w-12'}
- ${'large'} | ${'min-h-16'} | ${'pr-16'} | ${'w-16'}
- `('on $size size', ({
- size,
- inputClassNames,
- hintClassNames,
- indicatorClassNames,
- }: {
- size: TextControl.Size,
- inputClassNames: string,
- hintClassNames: string,
- indicatorClassNames: string,
- }) => {
- it('renders input styles', () => {
- render(
- <MenuSelect
- size={size}
- />,
- );
-
- const listbox = screen.getByRole('listbox');
- expect(listbox).toHaveClass(inputClassNames);
- });
-
- it('renders hint styles with indicator', () => {
- render(
- <MenuSelect
- size={size}
- hint="hint"
- indicator="a"
- />,
- );
-
- const hint = screen.getByTestId('hint');
- expect(hint).toHaveClass(hintClassNames);
- });
-
- it('renders indicator styles', () => {
- render(
- <MenuSelect
- size={size}
- indicator="a"
- />,
- );
-
- const indicator = screen.getByTestId('indicator');
- expect(indicator).toHaveClass(indicatorClassNames);
- });
-
- it('renders indicator styles for label', () => {
- render(
- <MenuSelect
- size={size}
- label="label"
- indicator="a"
- />,
- );
-
- const label = screen.getByTestId('label');
- expect(label).toHaveClass(hintClassNames);
- });
- });
-
- it('renders a block input', () => {
- render(
- <MenuSelect
- block
- />,
- );
-
- const base = screen.getByTestId('base');
- expect(base).toHaveClass('block');
- });
-
- describe.each`
- variant | inputClassNames | hintClassNames
- ${'default'} | ${'pl-4'} | ${'bottom-0 pl-4 pb-1'}
- ${'alternate'} | ${'pl-1.5 pt-5'} | ${'top-0.5'}
- `('on $variant variant', ({
- variant,
- inputClassNames,
- hintClassNames,
- }: {
- variant: TextControl.Variant,
- inputClassNames: string,
- hintClassNames: string,
- }) => {
- it('renders input styles', () => {
- render(
- <MenuSelect
- variant={variant}
- />,
- );
-
- const listbox = screen.getByRole('listbox');
- expect(listbox).toHaveClass(inputClassNames);
- });
-
- it('renders hint styles', () => {
- render(
- <MenuSelect
- variant={variant}
- hint="hint"
- />,
- );
-
- const hint = screen.getByTestId('hint');
- expect(hint).toHaveClass(hintClassNames);
- });
- });
-
- it('handles change events', async () => {
- const onChange = vi.fn().mockImplementationOnce(
- (e: React.ChangeEvent<MenuSelectDerivedElement>) => {
- e.preventDefault();
- },
- );
-
- render(
- <MenuSelect
- onChange={onChange}
- >
- <option value="foo">foo</option>
- <option value="bar">bar</option>
- </MenuSelect>,
- );
- const listbox: HTMLSelectElement = screen.getByRole('listbox');
- const [, secondOption] = screen.getAllByRole('option');
- await userEvent.selectOptions(listbox, secondOption);
- expect(onChange).toBeCalled();
- });
- });
|