Design system.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

198 lines
4.1 KiB

  1. import * as React from 'react';
  2. import {
  3. cleanup,
  4. render,
  5. screen,
  6. } from '@testing-library/react';
  7. import userEvent from '@testing-library/user-event';
  8. import { Button } from '@tesseract-design/web-base';
  9. import {
  10. vi,
  11. expect,
  12. describe,
  13. it,
  14. afterEach,
  15. } from 'vitest';
  16. import matchers from '@testing-library/jest-dom/matchers';
  17. import { PluginAPI } from 'tailwindcss/types/config';
  18. import {
  19. RadioButton,
  20. RadioButtonDerivedElement,
  21. radioButtonPlugin,
  22. } from '.';
  23. expect.extend(matchers);
  24. describe('radioButtonPlugin', () => {
  25. it('adds component styles', () => {
  26. const pluginApi = {
  27. addComponents: vi.fn(),
  28. } as unknown as PluginAPI;
  29. radioButtonPlugin(pluginApi);
  30. expect(pluginApi.addComponents).toBeCalledTimes(1);
  31. });
  32. });
  33. describe('RadioButton', () => {
  34. afterEach(() => {
  35. cleanup();
  36. });
  37. it('renders a radio button', () => {
  38. render(
  39. <RadioButton />,
  40. );
  41. const checkbox = screen.getByRole('radio');
  42. expect(checkbox).toBeInTheDocument();
  43. });
  44. it('renders a subtext', () => {
  45. render(
  46. <RadioButton
  47. subtext="subtext"
  48. />,
  49. );
  50. const subtext = screen.getByTestId('subtext');
  51. expect(subtext).toBeInTheDocument();
  52. });
  53. it('renders a badge', () => {
  54. render(
  55. <RadioButton
  56. badge="badge"
  57. />,
  58. );
  59. const badge = screen.getByTestId('badge');
  60. expect(badge).toBeInTheDocument();
  61. });
  62. it('renders a compact button', () => {
  63. render(
  64. <RadioButton
  65. compact
  66. />,
  67. );
  68. const button = screen.getByTestId('button');
  69. expect(button).toHaveClass('pl-2 gap-2 pr-2');
  70. });
  71. describe.each`
  72. size | className
  73. ${'small'} | ${'h-10'}
  74. ${'medium'} | ${'h-12'}
  75. ${'large'} | ${'h-16'}
  76. `('on $size size', ({
  77. size,
  78. className,
  79. }: { size: Button.Size, className: string }) => {
  80. it('renders button styles', () => {
  81. render(
  82. <RadioButton
  83. size={size}
  84. />,
  85. );
  86. const button = screen.getByTestId('button');
  87. expect(button).toHaveClass(className);
  88. });
  89. it('renders badge styles', () => {
  90. render(
  91. <RadioButton
  92. size={size}
  93. badge="badge"
  94. />,
  95. );
  96. const badge = screen.getByTestId('badge');
  97. expect(badge).toBeInTheDocument();
  98. });
  99. });
  100. it.each`
  101. variant | className
  102. ${'bare'} | ${'bg-negative'}
  103. ${'outline'} | ${'border-2'}
  104. ${'filled'} | ${'bg-primary'}
  105. `('renders a button with $variant variant', ({
  106. variant,
  107. className,
  108. }: { variant: Button.Variant, className: string }) => {
  109. render(
  110. <RadioButton
  111. variant={variant}
  112. />,
  113. );
  114. const button = screen.getByTestId('button');
  115. expect(button).toHaveClass(className);
  116. });
  117. it('renders a block button', () => {
  118. render(
  119. <RadioButton
  120. block
  121. />,
  122. );
  123. const button = screen.getByTestId('button');
  124. expect(button).toHaveClass('w-full flex');
  125. });
  126. it('renders children', () => {
  127. render(
  128. <RadioButton>
  129. Foo
  130. </RadioButton>,
  131. );
  132. const children = screen.getByTestId('children');
  133. expect(children).toHaveTextContent('Foo');
  134. });
  135. it('renders a disabled button', () => {
  136. render(
  137. <RadioButton
  138. disabled
  139. />,
  140. );
  141. const button = screen.getByRole('radio');
  142. expect(button).toBeDisabled();
  143. });
  144. it('handles click events', async () => {
  145. const onClick = vi.fn().mockImplementationOnce(
  146. (e: React.MouseEvent<RadioButtonDerivedElement>) => {
  147. e.preventDefault();
  148. },
  149. );
  150. render(
  151. <RadioButton
  152. onClick={onClick}
  153. />,
  154. );
  155. const button = screen.getByRole('radio');
  156. await userEvent.click(button);
  157. expect(onClick).toBeCalled();
  158. });
  159. it('handles change events', async () => {
  160. const onChange = vi.fn().mockImplementationOnce(
  161. (e: React.ChangeEvent<RadioButtonDerivedElement>) => {
  162. e.preventDefault();
  163. },
  164. );
  165. render(
  166. <RadioButton
  167. onChange={onChange}
  168. />,
  169. );
  170. const radio: HTMLInputElement = screen.getByRole('radio');
  171. await userEvent.click(radio);
  172. expect(onChange).toBeCalled();
  173. });
  174. });