import React from 'react' import { render, screen, fireEvent } from '@testing-library/react' import '@testing-library/jest-dom' import { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, } from '../table' describe('Table Components', () => { describe('Table Component', () => { describe('Basic Rendering', () => { it('renders correctly with default props', () => { render( Test
) const table = screen.getByTestId('table') expect(table).toBeInTheDocument() expect(table).toHaveClass('w-full', 'caption-bottom', 'text-sm') }) it('applies custom className', () => { render( Test
) const table = screen.getByTestId('table') expect(table).toHaveClass('custom-table') }) it('forwards ref correctly', () => { const ref = React.createRef() render( Test
) expect(ref.current).toBeInstanceOf(HTMLTableElement) }) it('maintains displayName', () => { expect(Table.displayName).toBe('Table') }) }) describe('Variants', () => { it('renders default variant correctly', () => { render( Test
) const table = screen.getByTestId('table') expect(table).toHaveClass('dark:text-gray-200') }) it('renders bordered variant correctly', () => { render( Test
) const table = screen.getByTestId('table') expect(table).toHaveClass('border', 'border-border', 'dark:border-gray-700') }) it('renders striped variant correctly', () => { render( Test
) const table = screen.getByTestId('table') expect(table).toHaveClass('dark:text-gray-200') // TableBody should have the striped class applied const tbody = screen.getByTestId('tbody') expect(tbody).toHaveClass('[&_tr:last-child]:border-0') }) it('renders card variant correctly', () => { render( Test
) const table = screen.getByTestId('table') expect(table).toHaveClass('border', 'border-border', 'dark:border-gray-700', 'rounded-md', 'shadow-sm') }) it('renders minimal variant correctly', () => { render( Test
) const table = screen.getByTestId('table') expect(table).toHaveClass('border-none', 'dark:text-gray-200') }) }) describe('Sizes', () => { it('renders sm size correctly', () => { render( Test
) const table = screen.getByTestId('table') expect(table).toHaveClass('text-xs') }) it('renders default size correctly', () => { render( Test
) const table = screen.getByTestId('table') expect(table).toHaveClass('text-sm') }) it('renders lg size correctly', () => { render( Test
) const table = screen.getByTestId('table') expect(table).toHaveClass('text-base') }) }) describe('Loading State', () => { it('shows loading spinner when loading', () => { render( Test
) const spinner = document.querySelector('.animate-spin') expect(spinner).toBeInTheDocument() const table = screen.getByTestId('table') expect(table).toHaveClass('opacity-70') }) it('does not show loading spinner when not loading', () => { render( Test
) const spinner = document.querySelector('.animate-spin') expect(spinner).not.toBeInTheDocument() }) }) describe('Empty Content', () => { it('shows empty content when no children', () => { render() expect(screen.getByText('No data available')).toBeInTheDocument() }) it('does not show empty content when has children', () => { render(
Test
) expect(screen.queryByText('No data available')).not.toBeInTheDocument() }) }) describe('HTML Attributes', () => { it('passes through HTML attributes', () => { render( Test
) const table = screen.getByTestId('table') expect(table).toHaveAttribute('id', 'test-table') expect(table).toHaveAttribute('role', 'table') }) }) }) describe('TableHeader Component', () => { it('renders correctly with default props', () => { render( Header
) const header = screen.getByTestId('header') expect(header).toBeInTheDocument() expect(header.tagName).toBe('THEAD') }) it('applies custom className', () => { render( Header
) const header = screen.getByTestId('header') expect(header).toHaveClass('custom-header') }) it('forwards ref correctly', () => { const ref = React.createRef() render( Header
) expect(ref.current).toBeInstanceOf(HTMLTableSectionElement) }) it('maintains displayName', () => { expect(TableHeader.displayName).toBe('TableHeader') }) }) describe('TableBody Component', () => { it('renders correctly with default props', () => { render( Body
) const body = screen.getByTestId('body') expect(body).toBeInTheDocument() expect(body.tagName).toBe('TBODY') }) it('applies custom className', () => { render( Body
) const body = screen.getByTestId('body') expect(body).toHaveClass('custom-body') }) it('forwards ref correctly', () => { const ref = React.createRef() render( Body
) expect(ref.current).toBeInstanceOf(HTMLTableSectionElement) }) it('maintains displayName', () => { expect(TableBody.displayName).toBe('TableBody') }) }) describe('TableFooter Component', () => { it('renders correctly with default props', () => { render( Footer
) const footer = screen.getByTestId('footer') expect(footer).toBeInTheDocument() expect(footer.tagName).toBe('TFOOT') expect(footer).toHaveClass('bg-primary', 'text-primary-foreground', 'font-medium') }) it('applies custom className', () => { render( Footer
) const footer = screen.getByTestId('footer') expect(footer).toHaveClass('custom-footer') }) it('forwards ref correctly', () => { const ref = React.createRef() render( Footer
) expect(ref.current).toBeInstanceOf(HTMLTableSectionElement) }) it('maintains displayName', () => { expect(TableFooter.displayName).toBe('TableFooter') }) }) describe('TableRow Component', () => { it('renders correctly with default props', () => { render( Row
) const row = screen.getByTestId('row') expect(row).toBeInTheDocument() expect(row.tagName).toBe('TR') expect(row).toHaveClass('border-b', 'transition-colors', 'hover:bg-muted/50') }) it('applies custom className', () => { render( Row
) const row = screen.getByTestId('row') expect(row).toHaveClass('custom-row') }) it('forwards ref correctly', () => { const ref = React.createRef() render( Row
) expect(ref.current).toBeInstanceOf(HTMLTableRowElement) }) it('maintains displayName', () => { expect(TableRow.displayName).toBe('TableRow') }) }) describe('TableHead Component', () => { it('renders correctly with default props', () => { render( Header
) const head = screen.getByTestId('head') expect(head).toBeInTheDocument() expect(head.tagName).toBe('TH') expect(head).toHaveClass('h-10', 'px-4', 'text-left', 'align-middle', 'font-medium', 'text-muted-foreground') }) it('renders sortable head correctly', () => { const onSort = jest.fn() render( Sortable Header
) const head = screen.getByTestId('head') expect(head).toHaveClass('cursor-pointer', 'hover:text-foreground', 'select-none') // Check for sort icon const sortIcon = head.querySelector('svg') expect(sortIcon).toBeInTheDocument() expect(sortIcon).toHaveClass('opacity-30') }) it('handles sort click', () => { const onSort = jest.fn() render( Sortable Header
) const head = screen.getByTestId('head') fireEvent.click(head) expect(onSort).toHaveBeenCalledTimes(1) }) it('shows ascending sort icon', () => { render( Sorted Header
) const head = screen.getByTestId('head') const sortIcon = head.querySelector('svg') expect(sortIcon).toBeInTheDocument() expect(sortIcon).not.toHaveClass('opacity-30') }) it('shows descending sort icon', () => { render( Sorted Header
) const head = screen.getByTestId('head') const sortIcon = head.querySelector('svg') expect(sortIcon).toBeInTheDocument() expect(sortIcon).not.toHaveClass('opacity-30') }) it('applies custom className', () => { render( Header
) const head = screen.getByTestId('head') expect(head).toHaveClass('custom-head') }) it('forwards ref correctly', () => { const ref = React.createRef() render( Header
) expect(ref.current).toBeInstanceOf(HTMLTableCellElement) }) it('maintains displayName', () => { expect(TableHead.displayName).toBe('TableHead') }) }) describe('TableCell Component', () => { it('renders correctly with default props', () => { render( Cell
) const cell = screen.getByTestId('cell') expect(cell).toBeInTheDocument() expect(cell.tagName).toBe('TD') expect(cell).toHaveClass('p-4', 'align-middle') }) it('applies custom className', () => { render( Cell
) const cell = screen.getByTestId('cell') expect(cell).toHaveClass('custom-cell') }) it('forwards ref correctly', () => { const ref = React.createRef() render( Cell
) expect(ref.current).toBeInstanceOf(HTMLTableCellElement) }) it('maintains displayName', () => { expect(TableCell.displayName).toBe('TableCell') }) }) describe('TableCaption Component', () => { it('renders correctly with default props', () => { render( Table Caption
) const caption = screen.getByTestId('caption') expect(caption).toBeInTheDocument() expect(caption.tagName).toBe('CAPTION') expect(caption).toHaveClass('mt-4', 'text-sm', 'text-muted-foreground') }) it('applies custom className', () => { render( Caption
) const caption = screen.getByTestId('caption') expect(caption).toHaveClass('custom-caption') }) it('forwards ref correctly', () => { const ref = React.createRef() render( Caption
) expect(ref.current).toBeInstanceOf(HTMLTableCaptionElement) }) it('maintains displayName', () => { expect(TableCaption.displayName).toBe('TableCaption') }) }) describe('Complex Combinations', () => { it('renders complete table with all components', () => { render( Complete table example Name Age John 25 Total 1
) expect(screen.getByText('Complete table example')).toBeInTheDocument() expect(screen.getByText('Name')).toBeInTheDocument() expect(screen.getByText('John')).toBeInTheDocument() expect(screen.getByText('Total')).toBeInTheDocument() }) it('handles striped variant with tbody', () => { render( Row 1 Row 2
) const table = screen.getByTestId('table') expect(table).toHaveClass('dark:text-gray-200') const tbody = screen.getByTestId('tbody') expect(tbody).toHaveClass('[&_tr:last-child]:border-0') }) }) describe('Edge Cases', () => { it('handles empty table', () => { render() const table = screen.getByTestId('table') expect(table).toBeInTheDocument() }) it('handles table without tbody', () => { render(
Header
) const table = screen.getByTestId('table') expect(table).toBeInTheDocument() }) it('passes through HTML attributes for all components', () => { render( Header Cell
) expect(screen.getByTestId('table')).toHaveAttribute('id', 'table') expect(screen.getByTestId('header')).toHaveAttribute('id', 'header') expect(screen.getByTestId('header-row')).toHaveAttribute('id', 'header-row') expect(screen.getByTestId('head')).toHaveAttribute('id', 'head') expect(screen.getByTestId('body')).toHaveAttribute('id', 'body') expect(screen.getByTestId('body-row')).toHaveAttribute('id', 'body-row') expect(screen.getByTestId('cell')).toHaveAttribute('id', 'cell') }) }) })