import { render, screen } from '@testing-library/react' import { describe, it, expect } from 'vitest' import { axe } from 'vitest-axe' import { Spinner } from './spinner' describe('Spinner', () => { it('exposes a status region with a default accessible name', () => { render() expect(screen.getByRole('status')).toHaveAttribute('aria-label', 'Loading') }) it('forwards a custom aria-label', () => { render() expect(screen.getByRole('status')).toHaveAttribute('aria-label', 'Fetching results') }) it('renders the status region as a so it nests inside

without invalid HTML', () => { render() expect(screen.getByRole('status').tagName).toBe('SPAN') }) it.each(['circular', 'dots', 'sparkle'] as const)('renders the %s variant without throwing', (variant) => { render() expect(screen.getByRole('status')).toBeInTheDocument() }) it('uses primary palette by default', () => { const { container } = render() const svg = container.querySelector('svg')! expect(svg.getAttribute('class')).toContain('text-primary') }) it('switches to currentColor when the prop is set', () => { const { container } = render() const svg = container.querySelector('svg')! expect(svg.getAttribute('class')).toContain('text-current') expect(svg.getAttribute('class')).not.toContain('text-primary') }) it('lets className override the default size via tailwind-merge', () => { render() const status = screen.getByRole('status') expect(status.className).toContain('text-xl') expect(status.className).not.toContain('text-[2.5rem]') }) it('forwards arbitrary span props', () => { render() const status = screen.getByTestId('busy') expect(status).toHaveAttribute('id', 'spinner-1') }) it('has no accessibility violations', async () => { const { container } = render() expect(await axe(container)).toHaveNoViolations() }) })