import React from 'react' import { render, screen } from '@testing-library/react' import '@testing-library/jest-dom' import { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbSeparator, BreadcrumbEllipsis } from '../breadcrumb' describe('Breadcrumb Components', () => { describe('Breadcrumb Component', () => { it('renders correctly with default props', () => { render( Home ) const breadcrumb = screen.getByTestId('breadcrumb') expect(breadcrumb).toBeInTheDocument() expect(breadcrumb).toHaveAttribute('aria-label', 'breadcrumb') expect(breadcrumb.tagName).toBe('NAV') }) it('applies custom className', () => { render( Home ) const breadcrumb = screen.getByTestId('breadcrumb') expect(breadcrumb).toHaveClass('custom-breadcrumb') }) it('forwards ref correctly', () => { const ref = React.createRef() render( Home ) expect(ref.current).toBeInstanceOf(HTMLElement) }) it('maintains displayName', () => { expect(Breadcrumb.displayName).toBe('Breadcrumb') }) it('renders default variant correctly', () => { render( Home ) const breadcrumb = screen.getByTestId('breadcrumb') expect(breadcrumb).toHaveClass('dark:text-gray-100') expect(breadcrumb).toHaveClass('transition-colors') }) it('renders muted variant correctly', () => { render( Home ) const breadcrumb = screen.getByTestId('breadcrumb') expect(breadcrumb).toHaveClass('text-muted-foreground') expect(breadcrumb).toHaveClass('dark:text-gray-400') }) it('renders ghost variant correctly', () => { render( Home ) const breadcrumb = screen.getByTestId('breadcrumb') expect(breadcrumb).toHaveClass('text-foreground/60') expect(breadcrumb).toHaveClass('dark:text-gray-300/60') }) it('renders default size correctly', () => { render( Home ) const breadcrumb = screen.getByTestId('breadcrumb') expect(breadcrumb).toHaveClass('text-sm') }) it('renders sm size correctly', () => { render( Home ) const breadcrumb = screen.getByTestId('breadcrumb') expect(breadcrumb).toHaveClass('text-xs') }) it('renders lg size correctly', () => { render( Home ) const breadcrumb = screen.getByTestId('breadcrumb') expect(breadcrumb).toHaveClass('text-base') }) it('passes through HTML attributes', () => { render( Home ) const breadcrumb = screen.getByTestId('breadcrumb') expect(breadcrumb).toHaveAttribute('id', 'custom-id') expect(breadcrumb).toHaveAttribute('data-custom', 'value') }) }) describe('BreadcrumbList Component', () => { it('renders correctly with default props', () => { render( Home Products ) const list = screen.getByTestId('breadcrumb-list') expect(list).toBeInTheDocument() expect(list.tagName).toBe('OL') expect(list).toHaveClass('flex') expect(list).toHaveClass('flex-wrap') expect(list).toHaveClass('items-center') }) it('applies custom className', () => { render( Home ) const list = screen.getByTestId('breadcrumb-list') expect(list).toHaveClass('custom-list') }) it('forwards ref correctly', () => { const ref = React.createRef() render( Home ) expect(ref.current).toBeInstanceOf(HTMLOListElement) }) it('maintains displayName', () => { expect(BreadcrumbList.displayName).toBe('BreadcrumbList') }) it('renders without collapse when items are few', () => { render( Home Products ) expect(screen.getByText('Home')).toBeInTheDocument() expect(screen.getByText('Products')).toBeInTheDocument() expect(screen.queryByText('More pages')).not.toBeInTheDocument() }) it('renders with collapse when items exceed collapsedWidth', () => { render( Home Category Subcategory Product ) expect(screen.getByText('Home')).toBeInTheDocument() expect(screen.getByText('Product')).toBeInTheDocument() expect(screen.getByText('More pages')).toBeInTheDocument() expect(screen.queryByText('Category')).not.toBeInTheDocument() }) it('uses default collapsedWidth when not specified', () => { render( 1 2 3 4 ) expect(screen.getByText('1')).toBeInTheDocument() expect(screen.getByText('4')).toBeInTheDocument() expect(screen.getByText('More pages')).toBeInTheDocument() }) it('passes through HTML attributes', () => { render( Home ) const list = screen.getByTestId('breadcrumb-list') expect(list).toHaveAttribute('id', 'custom-id') expect(list).toHaveAttribute('data-custom', 'value') }) }) describe('BreadcrumbItem Component', () => { it('renders correctly with default props', () => { render( Home ) const item = screen.getByTestId('breadcrumb-item') expect(item).toBeInTheDocument() expect(item.tagName).toBe('LI') expect(screen.getByText('Home')).toBeInTheDocument() }) it('applies custom className', () => { render( Home ) const item = screen.getByTestId('breadcrumb-item') expect(item).toHaveClass('custom-item') }) it('forwards ref correctly', () => { const ref = React.createRef() render( Home ) expect(ref.current).toBeInstanceOf(HTMLLIElement) }) it('maintains displayName', () => { expect(BreadcrumbItem.displayName).toBe('BreadcrumbItem') }) it('renders as span by default', () => { render( Home ) const item = screen.getByTestId('breadcrumb-item') const content = item.querySelector('span') expect(content).toBeInTheDocument() expect(content).toHaveTextContent('Home') }) it('renders as link when href is provided', () => { render( Home ) const item = screen.getByTestId('breadcrumb-item') const link = item.querySelector('a') expect(link).toBeInTheDocument() expect(link).toHaveAttribute('href', '/home') expect(link).toHaveTextContent('Home') }) it('renders as fragment when asChild is true', () => { render( ) const button = screen.getByRole('button') expect(button).toBeInTheDocument() expect(button).toHaveTextContent('Custom Button') }) it('sets aria-current when isCurrent is true', () => { render( Current Page ) const item = screen.getByTestId('breadcrumb-item') expect(item).toHaveAttribute('aria-current', 'page') }) it('does not set aria-current when isCurrent is false', () => { render( Not Current ) const item = screen.getByTestId('breadcrumb-item') expect(item).not.toHaveAttribute('aria-current') }) it('applies current page styling when isCurrent is true', () => { render( Current Page ) const item = screen.getByTestId('breadcrumb-item') const content = item.querySelector('span') expect(content).toHaveClass('font-medium') expect(content).toHaveClass('text-foreground') }) it('applies non-current styling when isCurrent is false', () => { render( Regular Page ) const item = screen.getByTestId('breadcrumb-item') const content = item.querySelector('span') expect(content).toHaveClass('text-muted-foreground') expect(content).toHaveClass('hover:text-foreground') }) it('passes through HTML attributes', () => { render( Home ) const item = screen.getByTestId('breadcrumb-item') expect(item).toHaveAttribute('id', 'custom-id') expect(item).toHaveAttribute('data-custom', 'value') }) }) describe('BreadcrumbSeparator Component', () => { it('renders correctly with default props', () => { render() const separator = screen.getByTestId('breadcrumb-separator') expect(separator).toBeInTheDocument() expect(separator.tagName).toBe('LI') expect(separator).toHaveAttribute('role', 'presentation') expect(separator).toHaveAttribute('aria-hidden', 'true') }) it('applies custom className', () => { render() const separator = screen.getByTestId('breadcrumb-separator') expect(separator).toHaveClass('custom-separator') }) it('maintains displayName', () => { expect(BreadcrumbSeparator.displayName).toBe('BreadcrumbSeparator') }) it('renders default ChevronRight icon', () => { render() const separator = screen.getByTestId('breadcrumb-separator') const icon = separator.querySelector('svg') expect(icon).toBeInTheDocument() expect(icon).toHaveClass('h-3.5') expect(icon).toHaveClass('w-3.5') }) it('renders custom children instead of default icon', () => { render( / ) const separator = screen.getByTestId('breadcrumb-separator') expect(screen.getByText('/')).toBeInTheDocument() expect(separator.querySelector('svg')).not.toBeInTheDocument() }) it('has correct default styling', () => { render() const separator = screen.getByTestId('breadcrumb-separator') expect(separator).toHaveClass('text-muted-foreground') expect(separator).toHaveClass('dark:text-gray-500') expect(separator).toHaveClass('opacity-70') }) it('passes through HTML attributes', () => { render( ) const separator = screen.getByTestId('breadcrumb-separator') expect(separator).toHaveAttribute('id', 'custom-id') expect(separator).toHaveAttribute('data-custom', 'value') }) }) describe('BreadcrumbEllipsis Component', () => { it('renders correctly with default props', () => { render() const ellipsis = screen.getByTestId('breadcrumb-ellipsis') expect(ellipsis).toBeInTheDocument() expect(ellipsis.tagName).toBe('LI') expect(ellipsis).toHaveAttribute('role', 'presentation') expect(ellipsis).toHaveAttribute('aria-hidden', 'true') }) it('applies custom className', () => { render() const ellipsis = screen.getByTestId('breadcrumb-ellipsis') expect(ellipsis).toHaveClass('custom-ellipsis') }) it('maintains displayName', () => { expect(BreadcrumbEllipsis.displayName).toBe('BreadcrumbEllipsis') }) it('renders MoreHorizontal icon', () => { render() const ellipsis = screen.getByTestId('breadcrumb-ellipsis') const icon = ellipsis.querySelector('svg') expect(icon).toBeInTheDocument() expect(icon).toHaveClass('h-4') expect(icon).toHaveClass('w-4') }) it('renders screen reader text', () => { render() expect(screen.getByText('More pages')).toBeInTheDocument() const srText = screen.getByText('More pages') expect(srText).toHaveClass('sr-only') }) it('has correct default styling', () => { render() const ellipsis = screen.getByTestId('breadcrumb-ellipsis') expect(ellipsis).toHaveClass('flex') expect(ellipsis).toHaveClass('items-center') expect(ellipsis).toHaveClass('text-muted-foreground') expect(ellipsis).toHaveClass('dark:text-gray-500') }) it('passes through HTML attributes', () => { render( ) const ellipsis = screen.getByTestId('breadcrumb-ellipsis') expect(ellipsis).toHaveAttribute('id', 'custom-id') expect(ellipsis).toHaveAttribute('data-custom', 'value') }) }) describe('Complex Combinations', () => { it('renders complete breadcrumb navigation', () => { render( Home Products Current Product ) expect(screen.getByText('Home')).toBeInTheDocument() expect(screen.getByText('Products')).toBeInTheDocument() expect(screen.getByText('Current Product')).toBeInTheDocument() const homeLink = screen.getByText('Home').closest('a') const productsLink = screen.getByText('Products').closest('a') const currentItem = screen.getByText('Current Product').closest('li') expect(homeLink).toHaveAttribute('href', '/') expect(productsLink).toHaveAttribute('href', '/products') expect(currentItem).toHaveAttribute('aria-current', 'page') }) it('renders with custom separators', () => { render( Home Products Current ) const arrows = screen.getAllByText('→') expect(arrows).toHaveLength(2) }) it('renders with collapsed list', () => { render( Home Category Subcategory Product ) expect(screen.getByText('Home')).toBeInTheDocument() expect(screen.getByText('Product')).toBeInTheDocument() expect(screen.getByText('More pages')).toBeInTheDocument() expect(screen.queryByText('Category')).not.toBeInTheDocument() expect(screen.queryByText('Subcategory')).not.toBeInTheDocument() }) it('renders with all props and variants', () => { render( Home Current ) const breadcrumb = screen.getByTestId('breadcrumb') expect(breadcrumb).toHaveClass('text-muted-foreground') expect(breadcrumb).toHaveClass('text-base') expect(breadcrumb).toHaveClass('custom-breadcrumb') }) }) describe('Edge Cases', () => { it('handles empty breadcrumb list', () => { render( ) const list = screen.getByTestId('breadcrumb-list') expect(list).toBeInTheDocument() expect(list).toBeEmptyDOMElement() }) it('handles single breadcrumb item', () => { render( Only Item ) expect(screen.getByText('Only Item')).toBeInTheDocument() const item = screen.getByText('Only Item').closest('li') expect(item).toHaveAttribute('aria-current', 'page') }) it('handles breadcrumb with only separators', () => { const { container } = render( ) const separators = container.querySelectorAll('[role="presentation"]') expect(separators).toHaveLength(3) }) it('handles asChild with complex children', () => { render(
Complex Child
) expect(screen.getByText('Complex')).toBeInTheDocument() expect(screen.getByText('Child')).toBeInTheDocument() }) it('handles null and undefined children', () => { render( Valid Item {null} {undefined} ) expect(screen.getByText('Valid Item')).toBeInTheDocument() }) }) })