import React from 'react'
import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom'
import { AspectRatio } from '../aspect-ratio'
describe('AspectRatio Component', () => {
describe('Basic Rendering', () => {
it('renders correctly with default props', () => {
render(
Test Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toBeInTheDocument()
expect(screen.getByText('Test Content')).toBeInTheDocument()
})
it('applies custom className', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('custom-aspect-ratio')
})
it('forwards ref correctly', () => {
const ref = React.createRef()
render(
Content
)
expect(ref.current).toBeInstanceOf(HTMLDivElement)
})
it('maintains displayName', () => {
expect(AspectRatio.displayName).toBe('AspectRatio')
})
})
describe('Variants', () => {
it('renders default variant correctly', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('rounded-md')
expect(aspectRatio).toHaveClass('bg-muted/10')
})
it('renders ghost variant correctly', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('bg-transparent')
})
it('renders outline variant correctly', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('rounded-md')
expect(aspectRatio).toHaveClass('border')
expect(aspectRatio).toHaveClass('border-border')
})
it('renders card variant correctly', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('rounded-md')
expect(aspectRatio).toHaveClass('bg-card')
expect(aspectRatio).toHaveClass('shadow-sm')
})
it('uses default variant as default', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('rounded-md')
expect(aspectRatio).toHaveClass('bg-muted/10')
})
})
describe('Radius', () => {
it('renders none radius correctly', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('rounded-none')
})
it('renders sm radius correctly', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('rounded-sm')
})
it('renders md radius correctly', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('rounded-md')
})
it('renders lg radius correctly', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('rounded-lg')
})
it('renders full radius correctly', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('rounded-full')
})
it('radius overrides variant radius', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('rounded-lg')
expect(aspectRatio).not.toHaveClass('rounded-md')
})
})
describe('Ratio Calculations', () => {
it('applies default ratio (16/9)', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
const expectedPadding = `${(1 / (16 / 9)) * 100}%`
expect(aspectRatio).toHaveStyle(`padding-bottom: ${expectedPadding}`)
})
it('applies custom ratio (4/3)', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
const expectedPadding = `${(1 / (4 / 3)) * 100}%`
expect(aspectRatio).toHaveStyle(`padding-bottom: ${expectedPadding}`)
})
it('applies square ratio (1/1)', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveStyle('padding-bottom: 100%')
})
it('applies wide ratio (21/9)', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
const expectedPadding = `${(1 / (21 / 9)) * 100}%`
expect(aspectRatio).toHaveStyle(`padding-bottom: ${expectedPadding}`)
})
it('applies portrait ratio (9/16)', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
const expectedPadding = `${(1 / (9 / 16)) * 100}%`
expect(aspectRatio).toHaveStyle(`padding-bottom: ${expectedPadding}`)
})
})
describe('Styling and Layout', () => {
it('has correct base styling', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('relative')
expect(aspectRatio).toHaveClass('overflow-hidden')
expect(aspectRatio).toHaveStyle('position: relative')
})
it('renders content wrapper with correct positioning', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
const contentWrapper = aspectRatio.querySelector('div')
expect(contentWrapper).toHaveClass('absolute')
expect(contentWrapper).toHaveClass('inset-0')
expect(screen.getByTestId('content')).toBeInTheDocument()
})
it('applies custom style prop', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveStyle('background-color: rgb(255, 0, 0)')
})
it('merges custom style with ratio style', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveStyle('background-color: rgb(0, 0, 255)')
expect(aspectRatio).toHaveStyle('border: 1px solid red')
expect(aspectRatio).toHaveStyle('padding-bottom: 50%')
})
})
describe('Content Rendering', () => {
it('renders single child correctly', () => {
render(
)
const image = screen.getByAltText('Test')
expect(image).toBeInTheDocument()
})
it('renders multiple children correctly', () => {
render(
Child 1
Child 2
Child 3
)
expect(screen.getByText('Child 1')).toBeInTheDocument()
expect(screen.getByText('Child 2')).toBeInTheDocument()
expect(screen.getByText('Child 3')).toBeInTheDocument()
})
it('renders complex nested content', () => {
render(
)
expect(screen.getByText('Title')).toBeInTheDocument()
expect(screen.getByText('Description')).toBeInTheDocument()
expect(screen.getByText('Action')).toBeInTheDocument()
})
it('handles empty content gracefully', () => {
render()
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toBeInTheDocument()
const contentWrapper = aspectRatio.querySelector('div')
expect(contentWrapper).toBeInTheDocument()
expect(contentWrapper).toBeEmptyDOMElement()
})
})
describe('Complex Combinations', () => {
it('renders with all props correctly', () => {
render(
Complex Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('bg-card')
expect(aspectRatio).toHaveClass('shadow-sm')
expect(aspectRatio).toHaveClass('rounded-lg')
expect(aspectRatio).toHaveClass('custom-class')
expect(aspectRatio).toHaveStyle('border: 2px solid blue')
expect(aspectRatio).toHaveStyle('padding-bottom: 75%')
expect(screen.getByText('Complex Content')).toBeInTheDocument()
})
it('works with image content', () => {
render(
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('border')
expect(aspectRatio).toHaveStyle('padding-bottom: 56.25%')
const image = screen.getByAltText('Test Image')
expect(image).toHaveStyle('width: 100%')
expect(image).toHaveStyle('height: 100%')
})
it('works with video content', () => {
render(
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveClass('bg-card')
const video = aspectRatio.querySelector('video')
expect(video).toBeInTheDocument()
expect(video).toHaveAttribute('controls')
})
})
describe('Edge Cases', () => {
it('passes through HTML attributes', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveAttribute('id', 'custom-id')
expect(aspectRatio).toHaveAttribute('data-custom', 'value')
})
it('handles zero ratio gracefully', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveStyle('padding-bottom: Infinity%')
})
it('handles very small ratio', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveStyle('padding-bottom: 1000%')
})
it('handles very large ratio', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveStyle('padding-bottom: 1%')
})
it('handles negative ratio', () => {
render(
Content
)
const aspectRatio = screen.getByTestId('aspect-ratio')
expect(aspectRatio).toHaveStyle('padding-bottom: -100%')
})
it('handles common aspect ratios', () => {
const commonRatios = [
{ ratio: 16 / 9, expected: '56.25%' },
{ ratio: 4 / 3, expected: '75%' },
{ ratio: 3 / 2, expected: '66.66666666666666%' },
{ ratio: 1 / 1, expected: '100%' },
{ ratio: 2 / 1, expected: '50%' },
]
commonRatios.forEach(({ ratio, expected }, index) => {
render(
Content {index}
)
const aspectRatio = screen.getByTestId(`aspect-ratio-${index}`)
expect(aspectRatio).toHaveStyle(`padding-bottom: ${expected}`)
})
})
})
})