UNPKG

@senka-ai/ui

Version:

A modern, type-safe Svelte 5 UI component library with full theme support, accessibility standards, and robust state management patterns

161 lines (160 loc) 6.62 kB
import { describe, it, expect, vi } from 'vitest'; import { createSafeClickHandler, createKeyboardHandler, KeySets, isInteractiveElement } from '../events'; describe('isInteractiveElement', () => { it('should identify interactive elements', () => { // Create mock elements const button = document.createElement('button'); const input = document.createElement('input'); const link = document.createElement('a'); link.href = 'https://example.com'; const div = document.createElement('div'); const clickableDiv = document.createElement('div'); clickableDiv.setAttribute('role', 'button'); expect(isInteractiveElement(button)).toBe(true); expect(isInteractiveElement(input)).toBe(true); expect(isInteractiveElement(link)).toBe(true); expect(isInteractiveElement(clickableDiv)).toBe(true); expect(isInteractiveElement(div)).toBe(false); }); }); describe('createSafeClickHandler', () => { it('should call onClick when not disabled', () => { const onClick = vi.fn(); const handler = createSafeClickHandler(onClick, false); const event = new MouseEvent('click', { bubbles: true }); Object.defineProperty(event, 'target', { value: document.createElement('div'), writable: false, }); handler(event); expect(onClick).toHaveBeenCalled(); }); it('should not call onClick when disabled', () => { const onClick = vi.fn(); const handler = createSafeClickHandler(onClick, true); const event = new MouseEvent('click', { bubbles: true }); Object.defineProperty(event, 'target', { value: document.createElement('div'), writable: false, }); handler(event); expect(onClick).not.toHaveBeenCalled(); }); it('should not call onClick when clicking interactive child element', () => { const onClick = vi.fn(); const handler = createSafeClickHandler(onClick, false); const button = document.createElement('button'); const event = new MouseEvent('click', { bubbles: true }); Object.defineProperty(event, 'target', { value: button, writable: false, }); handler(event); expect(onClick).not.toHaveBeenCalled(); }); it('should handle undefined onClick gracefully', () => { const mockHandler = vi.fn(); const handler = createSafeClickHandler(mockHandler, false); const event = new MouseEvent('click', { bubbles: true }); Object.defineProperty(event, 'target', { value: document.createElement('div'), writable: false, }); expect(() => handler(event)).not.toThrow(); }); }); describe('createKeyboardHandler', () => { it('should call action for specified keys', () => { const action = vi.fn(); const handler = createKeyboardHandler(action, { keys: ['Enter', ' '], preventDefault: true, disabled: false, }); // Test Enter key const enterEvent = new KeyboardEvent('keydown', { key: 'Enter' }); const preventDefaultSpy = vi.spyOn(enterEvent, 'preventDefault'); handler(enterEvent); expect(action).toHaveBeenCalled(); expect(preventDefaultSpy).toHaveBeenCalled(); // Test Space key action.mockClear(); const spaceEvent = new KeyboardEvent('keydown', { key: ' ' }); handler(spaceEvent); expect(action).toHaveBeenCalled(); }); it('should not call action for non-specified keys', () => { const action = vi.fn(); const handler = createKeyboardHandler(action, { keys: ['Enter'], disabled: false, }); const escapeEvent = new KeyboardEvent('keydown', { key: 'Escape' }); handler(escapeEvent); expect(action).not.toHaveBeenCalled(); }); it('should not call action when disabled', () => { const action = vi.fn(); const handler = createKeyboardHandler(action, { keys: ['Enter'], disabled: true, }); const enterEvent = new KeyboardEvent('keydown', { key: 'Enter' }); handler(enterEvent); expect(action).not.toHaveBeenCalled(); }); it('should not preventDefault when option is false', () => { const action = vi.fn(); const handler = createKeyboardHandler(action, { keys: ['Enter'], preventDefault: false, disabled: false, }); const enterEvent = new KeyboardEvent('keydown', { key: 'Enter' }); const preventDefaultSpy = vi.spyOn(enterEvent, 'preventDefault'); handler(enterEvent); expect(action).toHaveBeenCalled(); expect(preventDefaultSpy).not.toHaveBeenCalled(); }); it('should use KeySets.ACTIVATION correctly', () => { const action = vi.fn(); const keys = [...KeySets.ACTIVATION]; const handler = createKeyboardHandler(action, { keys: keys, disabled: false, }); // Test all activation keys const enterEvent = new KeyboardEvent('keydown', { key: 'Enter' }); const spaceEvent = new KeyboardEvent('keydown', { key: ' ' }); handler(enterEvent); expect(action).toHaveBeenCalled(); action.mockClear(); handler(spaceEvent); expect(action).toHaveBeenCalled(); }); it('should handle undefined action gracefully', () => { const mockAction = vi.fn(); const handler = createKeyboardHandler(mockAction, { keys: ['Enter'], disabled: true, }); const enterEvent = new KeyboardEvent('keydown', { key: 'Enter' }); expect(() => handler(enterEvent)).not.toThrow(); }); }); describe('KeySets', () => { it('should contain expected activation keys', () => { expect(KeySets.ACTIVATION).toContain('Enter'); expect(KeySets.ACTIVATION).toContain(' '); }); it('should contain expected navigation keys', () => { expect(KeySets.NAVIGATION).toContain('ArrowUp'); expect(KeySets.NAVIGATION).toContain('ArrowDown'); expect(KeySets.NAVIGATION).toContain('ArrowLeft'); expect(KeySets.NAVIGATION).toContain('ArrowRight'); }); it('should contain expected horizontal navigation keys', () => { expect(KeySets.HORIZONTAL_NAVIGATION).toContain('ArrowLeft'); expect(KeySets.HORIZONTAL_NAVIGATION).toContain('ArrowRight'); }); });