import React from 'react' import { render, screen, fireEvent } from '@testing-library/react' import '@testing-library/jest-dom' import { RadioGroup, RadioGroupItem, RadioLabel, RadioItemWithLabel, } from '../radio-group' describe('RadioGroup Components', () => { describe('RadioGroup Component', () => { it('renders correctly with default props', () => { render( ) const radioGroup = screen.getByTestId('radio-group') expect(radioGroup).toBeInTheDocument() expect(radioGroup).toHaveAttribute('role', 'radiogroup') expect(radioGroup).toHaveClass('grid', 'gap-2') }) it('applies custom className', () => { render( ) const radioGroup = screen.getByTestId('radio-group') expect(radioGroup).toHaveClass('custom-class') }) it('forwards ref correctly', () => { const ref = React.createRef() render( ) expect(ref.current).toBeInstanceOf(HTMLDivElement) }) it('handles controlled state', () => { const onValueChange = jest.fn() render( ) const option1 = screen.getByDisplayValue('option1') const option2 = screen.getByDisplayValue('option2') expect(option1).not.toBeChecked() expect(option2).toBeChecked() fireEvent.click(option1) expect(onValueChange).toHaveBeenCalledWith('option1') }) it('handles disabled state', () => { render( ) const option1 = screen.getByDisplayValue('option1') const option2 = screen.getByDisplayValue('option2') expect(option1).toBeDisabled() expect(option2).toBeDisabled() }) it('passes through HTML attributes', () => { render( ) const radioGroup = screen.getByTestId('radio-group') expect(radioGroup).toHaveAttribute('id', 'radio-group-1') }) it('maintains displayName', () => { expect(RadioGroup.displayName).toBe('RadioGroup') }) }) describe('RadioGroupItem Component', () => { it('renders correctly with default props', () => { render( ) const radioItem = screen.getByDisplayValue('test') expect(radioItem).toBeInTheDocument() expect(radioItem).toHaveAttribute('type', 'radio') expect(radioItem).toHaveAttribute('value', 'test') }) it('applies custom className to label', () => { render( ) const label = screen.getByDisplayValue('test').nextElementSibling expect(label).toHaveClass('custom-radio') }) it('forwards ref correctly', () => { const ref = React.createRef() render( ) expect(ref.current).toBeInstanceOf(HTMLInputElement) }) it('maintains displayName', () => { expect(RadioGroupItem.displayName).toBe('RadioGroupItem') }) it('renders default variant correctly', () => { render( ) const label = screen.getByDisplayValue('test').nextElementSibling expect(label).toHaveClass('border-border', 'bg-background', 'text-primary') }) it('renders outline variant correctly', () => { render( ) const label = screen.getByDisplayValue('test').nextElementSibling expect(label).toHaveClass('border-border', 'bg-transparent', 'text-primary') }) it('renders filled variant correctly', () => { render( ) const label = screen.getByDisplayValue('test').nextElementSibling expect(label).toHaveClass('border-primary', 'bg-primary/10', 'text-primary') }) it('renders sm size correctly', () => { render( ) const label = screen.getByDisplayValue('test').nextElementSibling expect(label).toHaveClass('h-3.5', 'w-3.5') }) it('renders default size correctly', () => { render( ) const label = screen.getByDisplayValue('test').nextElementSibling expect(label).toHaveClass('h-4', 'w-4') }) it('renders md size correctly', () => { render( ) const label = screen.getByDisplayValue('test').nextElementSibling expect(label).toHaveClass('h-5', 'w-5') }) it('renders lg size correctly', () => { render( ) const label = screen.getByDisplayValue('test').nextElementSibling expect(label).toHaveClass('h-6', 'w-6') }) it('renders custom indicator when checked', () => { const CustomIndicator = () => render( } /> ) expect(screen.getByTestId('custom-indicator')).toBeInTheDocument() }) it('renders default Circle indicator when checked', () => { render( ) const label = screen.getByDisplayValue('test').nextElementSibling const indicator = label?.querySelector('svg') expect(indicator).toBeInTheDocument() }) it('handles disabled state', () => { render( ) const radioItem = screen.getByDisplayValue('test') expect(radioItem).toBeDisabled() const label = radioItem.nextElementSibling expect(label).toHaveClass('cursor-not-allowed', 'opacity-50') }) it('handles click events', () => { const onValueChange = jest.fn() render( ) const radioItem = screen.getByDisplayValue('test') fireEvent.click(radioItem) expect(onValueChange).toHaveBeenCalledWith('test') }) it('handles onChange callback integration', () => { const onValueChange = jest.fn() render( ) const radioItem = screen.getByDisplayValue('test') // Click the radio item to trigger change fireEvent.click(radioItem) // onValueChange should be called with the value expect(onValueChange).toHaveBeenCalledWith('test') }) it('passes through HTML attributes', () => { render( ) const radioItem = screen.getByDisplayValue('test') expect(radioItem).toHaveAttribute('id', 'radio-1') expect(radioItem).toHaveAttribute('data-custom', 'value') }) }) describe('RadioLabel Component', () => { it('renders correctly with default props', () => { render(Test Label) const label = screen.getByText('Test Label') expect(label).toBeInTheDocument() expect(label).toHaveAttribute('for', 'radio-1') expect(label).toHaveClass('text-sm', 'font-medium', 'leading-none', 'ml-2', 'text-foreground') }) it('applies custom className', () => { render(Test Label) const label = screen.getByText('Test Label') expect(label).toHaveClass('custom-label') }) it('forwards ref correctly', () => { const ref = React.createRef() render(Test Label) expect(ref.current).toBeInstanceOf(HTMLLabelElement) }) it('handles disabled state', () => { render(Test Label) const label = screen.getByText('Test Label') expect(label).toHaveClass('cursor-not-allowed', 'opacity-70') }) it('passes through HTML attributes', () => { render(Test Label) const label = screen.getByText('Test Label') expect(label).toHaveAttribute('id', 'label-1') expect(label).toHaveAttribute('data-custom', 'value') }) it('maintains displayName', () => { expect(RadioLabel.displayName).toBe('RadioLabel') }) }) describe('RadioItemWithLabel Component', () => { it('renders correctly with default props', () => { render( ) const radioItem = screen.getByDisplayValue('test') const label = screen.getByText('Test Option') expect(radioItem).toBeInTheDocument() expect(label).toBeInTheDocument() expect(label).toHaveAttribute('for', radioItem.id) }) it('applies custom labelClassName', () => { render( ) const label = screen.getByText('Test Option') expect(label).toHaveClass('custom-label') }) it('forwards ref correctly', () => { const ref = React.createRef() render( ) expect(ref.current).toBeInstanceOf(HTMLInputElement) }) it('handles disabled state', () => { render( ) const radioItem = screen.getByDisplayValue('test') const label = screen.getByText('Test Option') expect(radioItem).toBeDisabled() expect(label).toHaveClass('cursor-not-allowed', 'opacity-70') }) it('uses custom id when provided', () => { render( ) const radioItem = screen.getByDisplayValue('test') const label = screen.getByText('Test Option') expect(radioItem).toHaveAttribute('id', 'custom-id') expect(label).toHaveAttribute('for', 'custom-id') }) it('generates unique id when not provided', () => { render( ) const radioItem1 = screen.getByDisplayValue('test1') const radioItem2 = screen.getByDisplayValue('test2') const label1 = screen.getByText('Test Option 1') const label2 = screen.getByText('Test Option 2') expect(radioItem1.id).not.toBe(radioItem2.id) expect(label1.getAttribute('for')).toBe(radioItem1.id) expect(label2.getAttribute('for')).toBe(radioItem2.id) }) it('maintains displayName', () => { expect(RadioItemWithLabel.displayName).toBe('RadioItemWithLabel') }) }) describe('Complex Combinations', () => { it('renders complete radio group with all components', () => { const onValueChange = jest.fn() render(
Option 3
) const option1 = screen.getByDisplayValue('option1') const option2 = screen.getByDisplayValue('option2') const option3 = screen.getByDisplayValue('option3') expect(option1).not.toBeChecked() expect(option2).toBeChecked() expect(option3).not.toBeChecked() fireEvent.click(option3) expect(onValueChange).toHaveBeenCalledWith('option3') }) it('handles all variants and sizes together', () => { render( ) const defaultItem = screen.getByDisplayValue('default').nextElementSibling const outlineItem = screen.getByDisplayValue('outline').nextElementSibling const filledItem = screen.getByDisplayValue('filled').nextElementSibling expect(defaultItem).toHaveClass('h-3.5', 'w-3.5', 'border-border', 'bg-background') expect(outlineItem).toHaveClass('h-5', 'w-5', 'border-border', 'bg-transparent') expect(filledItem).toHaveClass('h-6', 'w-6', 'border-primary', 'bg-primary/10') }) it('handles name attribute for form submission', () => { render( ) const option1 = screen.getByDisplayValue('option1') const option2 = screen.getByDisplayValue('option2') expect(option1).toHaveAttribute('name', 'test-group') expect(option2).toHaveAttribute('name', 'test-group') }) }) describe('Edge Cases', () => { it('handles empty radio group', () => { render() const radioGroup = screen.getByTestId('radio-group') expect(radioGroup).toBeInTheDocument() expect(radioGroup).toBeEmptyDOMElement() }) it('handles radio item without context', () => { // RadioGroupItem outside of RadioGroup context render() const radioItem = screen.getByDisplayValue('test') expect(radioItem).toBeInTheDocument() expect(radioItem).not.toBeChecked() }) it('handles null and undefined children', () => { render( {null} {undefined} ) const radioItem = screen.getByDisplayValue('test') expect(radioItem).toBeInTheDocument() }) it('handles complex label content', () => { render( Complex Label

With description

} />
) expect(screen.getByText('Complex Label')).toBeInTheDocument() expect(screen.getByText('With description')).toBeInTheDocument() }) it('handles disabled radio group with individual enabled items', () => { render( ) const option1 = screen.getByDisplayValue('option1') const option2 = screen.getByDisplayValue('option2') // Both should be disabled because group is disabled expect(option1).toBeDisabled() expect(option2).toBeDisabled() }) }) })