import React from 'react' import { render, screen } from '@testing-library/react' import '@testing-library/jest-dom' import { Skeleton, SkeletonText, SkeletonAvatar, SkeletonCard } from '../skeleton' describe('Skeleton Components', () => { describe('Skeleton Component', () => { it('renders correctly with default props', () => { render() const skeleton = screen.getByTestId('skeleton') expect(skeleton).toBeInTheDocument() expect(skeleton).toHaveClass('animate-pulse') expect(skeleton).toHaveClass('rounded-md') expect(skeleton).toHaveClass('bg-muted') }) it('applies custom className', () => { render() const skeleton = screen.getByTestId('skeleton') expect(skeleton).toHaveClass('custom-skeleton') }) it('forwards ref correctly', () => { const ref = React.createRef() render() expect(ref.current).toBeInstanceOf(HTMLDivElement) }) it('applies custom dimensions', () => { render() const skeleton = screen.getByTestId('skeleton') expect(skeleton).toHaveStyle({ height: '100px', width: '200px' }) }) it('renders primary variant', () => { render() const skeleton = screen.getByTestId('skeleton') expect(skeleton).toHaveClass('bg-primary/10') }) it('renders circle shape', () => { render() const skeleton = screen.getByTestId('skeleton') expect(skeleton).toHaveClass('rounded-full') }) it('shows children when loaded', () => { render(Content) expect(screen.getByText('Content')).toBeInTheDocument() }) it('shows skeleton when not loaded', () => { render(Content) const skeleton = screen.getByTestId('skeleton') expect(skeleton).toHaveClass('animate-pulse') expect(screen.queryByText('Content')).not.toBeInTheDocument() }) it('maintains displayName', () => { expect(Skeleton.displayName).toBe('Skeleton') }) }) describe('SkeletonText Component', () => { it('renders correctly with default props', () => { render() const container = screen.getByTestId('skeleton-text') expect(container).toBeInTheDocument() expect(container).toHaveClass('flex') const skeletons = container.querySelectorAll('.animate-pulse') expect(skeletons).toHaveLength(3) // default lines }) it('renders custom number of lines', () => { render() const container = screen.getByTestId('skeleton-text') const skeletons = container.querySelectorAll('.animate-pulse') expect(skeletons).toHaveLength(5) }) it('applies custom line height', () => { render() const container = screen.getByTestId('skeleton-text') const firstLine = container.querySelector('.animate-pulse') expect(firstLine).toHaveStyle({ height: '1rem' }) }) it('applies custom spacing', () => { render() const container = screen.getByTestId('skeleton-text') expect(container).toHaveStyle({ gap: '1rem' }) }) it('forwards ref correctly', () => { const ref = React.createRef() render() expect(ref.current).toBeInstanceOf(HTMLDivElement) }) it('maintains displayName', () => { expect(SkeletonText.displayName).toBe('SkeletonText') }) }) describe('SkeletonAvatar Component', () => { it('renders correctly with default props', () => { render() const avatar = screen.getByTestId('skeleton-avatar') expect(avatar).toBeInTheDocument() expect(avatar).toHaveClass('animate-pulse') expect(avatar).toHaveClass('rounded-full') expect(avatar).toHaveClass('shrink-0') expect(avatar).toHaveStyle({ height: '2.5rem', width: '2.5rem' }) }) it('applies custom size', () => { render() const avatar = screen.getByTestId('skeleton-avatar') expect(avatar).toHaveStyle({ height: '3rem', width: '3rem' }) }) it('applies custom size as number', () => { render() const avatar = screen.getByTestId('skeleton-avatar') expect(avatar).toHaveStyle({ height: '48px', width: '48px' }) }) it('forwards ref correctly', () => { const ref = React.createRef() render() expect(ref.current).toBeInstanceOf(HTMLDivElement) }) it('renders with custom variant', () => { render() const avatar = screen.getByTestId('skeleton-avatar') expect(avatar).toHaveClass('bg-primary/10') }) it('maintains displayName', () => { expect(SkeletonAvatar.displayName).toBe('SkeletonAvatar') }) }) describe('SkeletonCard Component', () => { it('renders correctly with default props', () => { render() const card = screen.getByTestId('skeleton-card') expect(card).toBeInTheDocument() expect(card).toHaveClass('overflow-hidden') expect(card).toHaveClass('rounded-md') expect(card).toHaveClass('border') expect(card).toHaveClass('bg-background') expect(card).toHaveClass('p-4') }) it('shows header by default', () => { render() const card = screen.getByTestId('skeleton-card') // Check for avatar in header const avatar = card.querySelector('.shrink-0.rounded-full') expect(avatar).toBeInTheDocument() }) it('hides header when showHeader is false', () => { render() const card = screen.getByTestId('skeleton-card') // Avatar should not be present const avatar = card.querySelector('.shrink-0.rounded-full') expect(avatar).not.toBeInTheDocument() }) it('renders custom number of content lines', () => { render() const card = screen.getByTestId('skeleton-card') const textContainer = card.querySelector('.flex.flex-col') expect(textContainer).toBeInTheDocument() const contentLines = textContainer?.querySelectorAll('.animate-pulse') expect(contentLines).toHaveLength(5) }) it('shows footer by default', () => { render() const card = screen.getByTestId('skeleton-card') const footer = card.querySelector('.border-t') expect(footer).toBeInTheDocument() }) it('hides footer when showFooter is false', () => { render() const card = screen.getByTestId('skeleton-card') const footer = card.querySelector('.border-t') expect(footer).not.toBeInTheDocument() }) it('forwards ref correctly', () => { const ref = React.createRef() render() expect(ref.current).toBeInstanceOf(HTMLDivElement) }) it('maintains displayName', () => { expect(SkeletonCard.displayName).toBe('SkeletonCard') }) }) describe('Edge Cases', () => { it('handles zero lines in SkeletonText', () => { render() const container = screen.getByTestId('skeleton-text') const skeletons = container.querySelectorAll('.animate-pulse') expect(skeletons).toHaveLength(0) }) it('handles all sections disabled in SkeletonCard', () => { render( ) const card = screen.getByTestId('skeleton-card') // No header avatar const avatar = card.querySelector('.shrink-0.rounded-full') expect(avatar).not.toBeInTheDocument() // No footer const footer = card.querySelector('.border-t') expect(footer).not.toBeInTheDocument() // Only content lines const textContainer = card.querySelector('.flex.flex-col') const contentLines = textContainer?.querySelectorAll('.animate-pulse') expect(contentLines).toHaveLength(1) }) it('passes through HTML attributes', () => { render() const skeleton = screen.getByTestId('skeleton-test') expect(skeleton).toHaveAttribute('id', 'skeleton-1') }) }) })