/**
* Tests for Skeleton component
*/
import { describe, it, expect } from 'vitest';
import { render } from '@testing-library/react';
import {
Skeleton,
SkeletonText,
SkeletonCard,
SkeletonTable,
SkeletonAvatar,
SkeletonButton,
} from './Skeleton';
describe('Skeleton', () => {
describe('base Skeleton', () => {
it('should render with default props', () => {
const { container } = render();
const skeleton = container.firstChild as HTMLElement;
expect(skeleton).toBeInTheDocument();
expect(skeleton).toHaveClass('bg-gray-200', 'dark:bg-gray-700');
expect(skeleton).toHaveClass('animate-pulse');
expect(skeleton).toHaveClass('rounded'); // text variant default
});
it('should apply rectangular variant', () => {
const { container } = render();
const skeleton = container.firstChild as HTMLElement;
expect(skeleton).toHaveClass('rounded-md');
});
it('should apply circular variant', () => {
const { container } = render();
const skeleton = container.firstChild as HTMLElement;
expect(skeleton).toHaveClass('rounded-full');
});
it('should apply wave animation', () => {
const { container } = render();
const skeleton = container.firstChild as HTMLElement;
expect(skeleton).toHaveClass('animate-shimmer');
expect(skeleton).not.toHaveClass('animate-pulse');
});
it('should not animate with none', () => {
const { container } = render();
const skeleton = container.firstChild as HTMLElement;
expect(skeleton).not.toHaveClass('animate-pulse');
expect(skeleton).not.toHaveClass('animate-shimmer');
});
it('should apply custom width and height as numbers', () => {
const { container } = render();
const skeleton = container.firstChild as HTMLElement;
expect(skeleton).toHaveStyle({ width: '100px', height: '50px' });
});
it('should apply custom width and height as strings', () => {
const { container } = render();
const skeleton = container.firstChild as HTMLElement;
expect(skeleton).toHaveStyle({ width: '50%', height: '2rem' });
});
it('should be aria-hidden', () => {
const { container } = render();
const skeleton = container.firstChild as HTMLElement;
expect(skeleton).toHaveAttribute('aria-hidden', 'true');
});
it('should apply custom className', () => {
const { container } = render();
const skeleton = container.firstChild as HTMLElement;
expect(skeleton).toHaveClass('my-custom-class');
});
});
describe('SkeletonText', () => {
it('should render default 3 lines', () => {
const { container } = render();
const wrapper = container.firstChild as HTMLElement;
const lines = wrapper.querySelectorAll('[aria-hidden="true"]');
expect(lines).toHaveLength(3);
});
it('should render custom number of lines', () => {
const { container } = render();
const wrapper = container.firstChild as HTMLElement;
const lines = wrapper.querySelectorAll('[aria-hidden="true"]');
expect(lines).toHaveLength(5);
});
it('should apply gap classes', () => {
const { container } = render();
const wrapper = container.firstChild as HTMLElement;
expect(wrapper).toHaveClass('gap-3');
});
});
describe('SkeletonCard', () => {
it('should render with header by default', () => {
const { container } = render();
const skeletons = container.querySelectorAll('[aria-hidden="true"]');
// Header (2 skeletons) + content lines (3) = 5
expect(skeletons.length).toBeGreaterThanOrEqual(5);
});
it('should render avatar when showAvatar is true', () => {
const { container } = render();
const circular = container.querySelector('.rounded-full');
expect(circular).toBeInTheDocument();
});
it('should render footer when showFooter is true', () => {
const { container } = render();
const rectangles = container.querySelectorAll('.rounded-md');
expect(rectangles.length).toBeGreaterThanOrEqual(2);
});
});
describe('SkeletonTable', () => {
it('should render correct number of rows', () => {
const { container } = render();
const rows = container.querySelectorAll('.divide-y > div');
expect(rows).toHaveLength(3);
});
it('should render header when showHeader is true', () => {
const { container } = render();
const header = container.querySelector('.bg-background-subtle');
expect(header).toBeInTheDocument();
});
});
describe('SkeletonAvatar', () => {
it('should render with correct size', () => {
const { container } = render();
const avatar = container.firstChild as HTMLElement;
expect(avatar).toHaveStyle({ width: '48px', height: '48px' });
});
it('should be circular', () => {
const { container } = render();
const avatar = container.firstChild as HTMLElement;
expect(avatar).toHaveClass('rounded-full');
});
});
describe('SkeletonButton', () => {
it('should render with correct height for size', () => {
const { container } = render();
const button = container.firstChild as HTMLElement;
expect(button).toHaveStyle({ height: '48px' });
});
it('should apply custom width', () => {
const { container } = render();
const button = container.firstChild as HTMLElement;
expect(button).toHaveStyle({ width: '200px' });
});
});
});