/* eslint-disable @typescript-eslint/no-explicit-any */
import React from 'react'
import { render, screen, fireEvent } from '@testing-library/react'
import '@testing-library/jest-dom'
import {
Command,
CommandDialog,
CommandInput,
CommandList,
CommandEmpty,
CommandGroup,
CommandItem,
CommandShortcut,
CommandSeparator,
commandVariants,
commandInputVariants,
commandListVariants,
commandGroupVariants,
commandItemVariants,
} from '../command'
// Mock Dialog component
jest.mock('./dialog', () => ({
Dialog: ({ children, open, ...props }: any) => (
{children}
),
DialogContent: ({ children, className, ...props }: React.ComponentProps<'div'>) => (
{children}
),
}))
describe('Command Components', () => {
describe('Command Component', () => {
it('renders correctly with default props', () => {
render(Content)
const command = screen.getByTestId('command')
expect(command).toBeInTheDocument()
expect(command).toHaveClass('flex h-full w-full flex-col')
})
it('applies custom className', () => {
render(Content)
const command = screen.getByTestId('command')
expect(command).toHaveClass('custom-class')
})
it('forwards ref correctly', () => {
const ref = React.createRef()
render(Content)
expect(ref.current).toBeInstanceOf(HTMLDivElement)
})
it('maintains displayName', () => {
expect(Command.displayName).toBe('Command')
})
it('renders default variant correctly', () => {
render(Content)
const command = screen.getByTestId('command')
expect(command).toHaveClass('bg-popover text-popover-foreground')
})
it('renders glass variant correctly', () => {
render(Content)
const command = screen.getByTestId('command')
expect(command).toHaveClass('bg-background/80 backdrop-blur-sm')
})
it('renders bordered variant correctly', () => {
render(Content)
const command = screen.getByTestId('command')
expect(command).toHaveClass('border border-border')
})
it('renders sm size correctly', () => {
render(Content)
const command = screen.getByTestId('command')
expect(command).toHaveClass('p-2')
})
it('renders default size correctly', () => {
render(Content)
const command = screen.getByTestId('command')
expect(command).toHaveClass('p-4')
})
it('renders lg size correctly', () => {
render(Content)
const command = screen.getByTestId('command')
expect(command).toHaveClass('p-6')
})
it('passes through HTML attributes', () => {
render(Content)
const command = screen.getByTestId('command')
expect(command).toHaveAttribute('id', 'command-1')
})
})
describe('CommandDialog Component', () => {
it('renders correctly with default props', () => {
render(
Dialog Content
)
const dialog = screen.getByTestId('dialog')
const dialogContent = screen.getByTestId('dialog-content')
expect(dialog).toBeInTheDocument()
expect(dialogContent).toBeInTheDocument()
})
it('applies custom commandClassName', () => {
render(
Dialog Content
)
const dialogContent = screen.getByTestId('dialog-content')
expect(dialogContent.querySelector('[class*="custom-command"]')).toBeInTheDocument()
})
it('passes through dialog props', () => {
const onOpenChange = jest.fn()
render(
Dialog Content
)
const dialog = screen.getByTestId('dialog')
expect(dialog).toHaveAttribute('data-open', 'true')
})
})
describe('CommandInput Component', () => {
it('renders correctly with default props', () => {
render()
const input = screen.getByTestId('command-input')
expect(input).toBeInTheDocument()
expect(input).toHaveClass('flex')
expect(input).toHaveClass('h-11')
expect(input).toHaveClass('w-full')
})
it('renders search icon', () => {
render()
const searchIcon = document.querySelector('svg')
expect(searchIcon).toBeInTheDocument()
expect(searchIcon).toHaveClass('h-4 w-4 shrink-0 opacity-50')
})
it('applies custom className', () => {
render()
const input = screen.getByTestId('command-input')
expect(input).toHaveClass('custom-input')
})
it('forwards ref correctly', () => {
const ref = React.createRef()
render()
expect(ref.current).toBeInstanceOf(HTMLInputElement)
})
it('maintains displayName', () => {
expect(CommandInput.displayName).toBe('CommandInput')
})
it('renders minimal variant correctly', () => {
render()
const input = screen.getByTestId('command-input')
expect(input).toHaveClass('h-9')
})
it('renders bordered variant correctly', () => {
render()
const input = screen.getByTestId('command-input')
expect(input).toHaveClass('border-b border-border')
})
it('handles input events', () => {
const onChange = jest.fn()
render()
const input = screen.getByRole('textbox')
fireEvent.change(input, { target: { value: 'test' } })
expect(onChange).toHaveBeenCalled()
})
it('passes through HTML attributes', () => {
render()
const input = screen.getByRole('textbox')
expect(input).toHaveAttribute('placeholder', 'Search...')
expect(input).toHaveAttribute('id', 'search-input')
})
})
describe('CommandList Component', () => {
it('renders correctly with default props', () => {
render(List Content)
const list = screen.getByTestId('command-list')
expect(list).toBeInTheDocument()
expect(list).toHaveClass('max-h-[300px] overflow-y-auto')
expect(list).toHaveAttribute('role', 'listbox')
})
it('applies custom className', () => {
render(Content)
const list = screen.getByTestId('command-list')
expect(list).toHaveClass('custom-list')
})
it('forwards ref correctly', () => {
const ref = React.createRef()
render(Content)
expect(ref.current).toBeInstanceOf(HTMLDivElement)
})
it('maintains displayName', () => {
expect(CommandList.displayName).toBe('CommandList')
})
it('renders scrollable variant correctly', () => {
render(Content)
const list = screen.getByTestId('command-list')
expect(list).toHaveClass('max-h-[400px]')
})
it('renders compact variant correctly', () => {
render(Content)
const list = screen.getByTestId('command-list')
expect(list).toHaveClass('max-h-[200px]')
})
it('passes through HTML attributes', () => {
render(Content)
const list = screen.getByTestId('command-list')
expect(list).toHaveAttribute('id', 'list-1')
})
})
describe('CommandEmpty Component', () => {
it('renders correctly with default props', () => {
render(No results)
const empty = screen.getByTestId('command-empty')
expect(empty).toBeInTheDocument()
expect(empty).toHaveClass('py-6 text-center text-sm text-muted-foreground')
})
it('applies custom className', () => {
render(No results)
const empty = screen.getByTestId('command-empty')
expect(empty).toHaveClass('custom-empty')
})
it('forwards ref correctly', () => {
const ref = React.createRef()
render(No results)
expect(ref.current).toBeInstanceOf(HTMLDivElement)
})
it('maintains displayName', () => {
expect(CommandEmpty.displayName).toBe('CommandEmpty')
})
it('passes through HTML attributes', () => {
render(No results)
const empty = screen.getByTestId('command-empty')
expect(empty).toHaveAttribute('id', 'empty-1')
})
})
describe('CommandGroup Component', () => {
it('renders correctly with default props', () => {
render(Group Content)
const group = screen.getByTestId('command-group')
expect(group).toBeInTheDocument()
expect(group).toHaveClass('overflow-hidden p-1 text-foreground')
})
it('applies custom className', () => {
render(Content)
const group = screen.getByTestId('command-group')
expect(group).toHaveClass('custom-group')
})
it('forwards ref correctly', () => {
const ref = React.createRef()
render(Content)
expect(ref.current).toBeInstanceOf(HTMLDivElement)
})
it('maintains displayName', () => {
expect(CommandGroup.displayName).toBe('CommandGroup')
})
it('renders heading when provided', () => {
render(
Group Content
)
expect(screen.getByText('Group Title')).toBeInTheDocument()
const heading = screen.getByText('Group Title')
expect(heading).toHaveClass('px-2 py-1.5 text-xs font-medium text-muted-foreground')
})
it('renders without heading', () => {
render(Group Content)
const group = screen.getByTestId('command-group')
expect(group.querySelector('.px-2.py-1\\.5')).not.toBeInTheDocument()
})
it('renders separated variant correctly', () => {
render(Content)
const group = screen.getByTestId('command-group')
expect(group).toHaveClass('mt-2 border-t border-border pt-2')
})
it('renders indented variant correctly', () => {
render(Content)
const group = screen.getByTestId('command-group')
expect(group).toHaveClass('pl-4')
})
it('passes through HTML attributes', () => {
render(Content)
const group = screen.getByTestId('command-group')
expect(group).toHaveAttribute('id', 'group-1')
})
})
describe('CommandItem Component', () => {
it('renders correctly with default props', () => {
render(Item Content)
const item = screen.getByTestId('command-item')
expect(item).toBeInTheDocument()
expect(item).toHaveClass('relative flex cursor-default select-none')
expect(item).toHaveAttribute('role', 'option')
})
it('applies custom className', () => {
render(Content)
const item = screen.getByTestId('command-item')
expect(item).toHaveClass('custom-item')
})
it('forwards ref correctly', () => {
const ref = React.createRef()
render(Content)
expect(ref.current).toBeInstanceOf(HTMLDivElement)
})
it('maintains displayName', () => {
expect(CommandItem.displayName).toBe('CommandItem')
})
it('handles selected state', () => {
render(Content)
const item = screen.getByTestId('command-item')
expect(item).toHaveAttribute('aria-selected', 'true')
})
it('handles disabled state', () => {
render(Content)
const item = screen.getByTestId('command-item')
expect(item).toHaveAttribute('data-disabled', '')
})
it('handles click events with onSelect', () => {
const onSelect = jest.fn()
render(
Content
)
const item = screen.getByTestId('command-item')
fireEvent.click(item)
expect(onSelect).toHaveBeenCalledWith('test-value')
})
it('does not call onSelect when disabled', () => {
const onSelect = jest.fn()
render(
Content
)
const item = screen.getByTestId('command-item')
fireEvent.click(item)
expect(onSelect).not.toHaveBeenCalled()
})
it('renders subtle variant correctly', () => {
render(Content)
const item = screen.getByTestId('command-item')
expect(item).toHaveClass('aria-selected:bg-accent/10')
})
it('renders ghost variant correctly', () => {
render(Content)
const item = screen.getByTestId('command-item')
expect(item).toHaveClass('hover:bg-muted/10')
})
it('passes through HTML attributes', () => {
render(Content)
const item = screen.getByTestId('command-item')
expect(item).toHaveAttribute('id', 'item-1')
})
})
describe('CommandShortcut Component', () => {
it('renders correctly with default props', () => {
render(⌘K)
const shortcut = screen.getByTestId('command-shortcut')
expect(shortcut).toBeInTheDocument()
expect(shortcut).toHaveClass('ml-auto text-xs tracking-widest text-muted-foreground')
})
it('applies custom className', () => {
render(⌘K)
const shortcut = screen.getByTestId('command-shortcut')
expect(shortcut).toHaveClass('custom-shortcut')
})
it('maintains displayName', () => {
expect(CommandShortcut.displayName).toBe('CommandShortcut')
})
it('passes through HTML attributes', () => {
render(⌘K)
const shortcut = screen.getByTestId('command-shortcut')
expect(shortcut).toHaveAttribute('id', 'shortcut-1')
})
})
describe('CommandSeparator Component', () => {
it('renders correctly with default props', () => {
render()
const separator = screen.getByTestId('command-separator')
expect(separator).toBeInTheDocument()
expect(separator).toHaveClass('-mx-1 h-px bg-border')
})
it('applies custom className', () => {
render()
const separator = screen.getByTestId('command-separator')
expect(separator).toHaveClass('custom-separator')
})
it('forwards ref correctly', () => {
const ref = React.createRef()
render()
expect(ref.current).toBeInstanceOf(HTMLDivElement)
})
it('maintains displayName', () => {
expect(CommandSeparator.displayName).toBe('CommandSeparator')
})
it('passes through HTML attributes', () => {
render()
const separator = screen.getByTestId('command-separator')
expect(separator).toHaveAttribute('id', 'separator-1')
})
})
describe('Variant Functions', () => {
it('commandVariants generates correct classes', () => {
expect(commandVariants()).toContain('flex h-full w-full flex-col')
expect(commandVariants({ variant: 'glass' })).toContain('bg-background/80')
expect(commandVariants({ size: 'lg' })).toContain('p-6')
})
it('commandInputVariants generates correct classes', () => {
expect(commandInputVariants()).toContain('flex h-11 w-full')
expect(commandInputVariants({ variant: 'minimal' })).toContain('h-9')
expect(commandInputVariants({ variant: 'bordered' })).toContain('border-b')
})
it('commandListVariants generates correct classes', () => {
expect(commandListVariants()).toContain('max-h-[300px]')
expect(commandListVariants({ variant: 'scrollable' })).toContain('max-h-[400px]')
expect(commandListVariants({ variant: 'compact' })).toContain('max-h-[200px]')
})
it('commandGroupVariants generates correct classes', () => {
expect(commandGroupVariants()).toContain('overflow-hidden p-1')
expect(commandGroupVariants({ variant: 'separated' })).toContain('border-t')
expect(commandGroupVariants({ variant: 'indented' })).toContain('pl-4')
})
it('commandItemVariants generates correct classes', () => {
expect(commandItemVariants()).toContain('relative flex cursor-default')
expect(commandItemVariants({ variant: 'subtle' })).toContain('aria-selected:bg-accent/10')
expect(commandItemVariants({ variant: 'ghost' })).toContain('hover:bg-muted/10')
})
})
describe('Complex Combinations', () => {
it('renders complete command palette', () => {
render(
No results found.
Calendar
⌘C
Search
⌘S
Profile
Billing
)
expect(screen.getByTestId('command')).toBeInTheDocument()
expect(screen.getByPlaceholderText('Type a command...')).toBeInTheDocument()
expect(screen.getByText('Suggestions')).toBeInTheDocument()
expect(screen.getByText('Calendar')).toBeInTheDocument()
expect(screen.getByText('⌘C')).toBeInTheDocument()
})
it('renders command dialog with all components', () => {
render(
No results.
Action 1
Action 2
)
expect(screen.getByTestId('dialog')).toBeInTheDocument()
expect(screen.getByPlaceholderText('Search...')).toBeInTheDocument()
expect(screen.getByText('Actions')).toBeInTheDocument()
})
it('handles all props and variants together', () => {
render(
Test Item
⌘T
)
const command = screen.getByTestId('command')
expect(command).toHaveClass('custom-command border p-6')
})
})
describe('Edge Cases', () => {
it('handles empty command', () => {
render()
const command = screen.getByTestId('command')
expect(command).toBeInTheDocument()
})
it('handles command item without value', () => {
const onSelect = jest.fn()
render(Item)
const item = screen.getByTestId('command-item')
fireEvent.click(item)
expect(onSelect).not.toHaveBeenCalled()
})
it('handles command group with complex heading', () => {
render(
Complex Heading}>
Content
)
expect(screen.getByText('Complex Heading')).toBeInTheDocument()
expect(document.querySelector('.custom-heading')).toBeInTheDocument()
})
it('handles null and undefined children', () => {
render(
{null}
{undefined}
{null}
)
expect(screen.getByRole('textbox')).toBeInTheDocument()
})
it('handles disabled input', () => {
render()
const input = screen.getByRole('textbox')
expect(input).toBeDisabled()
expect(input).toHaveClass('disabled:cursor-not-allowed disabled:opacity-50')
})
})
})