UNPKG

@datametria/vue-components

Version:

DATAMETRIA Vue.js 3 Component Library with Multi-Brand Theming - 51 components + 10 composables with theming support, WCAG 2.2 AA, dark mode, responsive system

367 lines (299 loc) 11.2 kB
import { describe, it, expect, vi, beforeEach } from 'vitest' import { mount } from '@vue/test-utils' import DatametriaMenu from '../DatametriaMenu.vue' describe('DatametriaMenu', () => { const mockItems = [ { key: '1', label: 'Item 1', action: vi.fn() }, { key: '2', label: 'Item 2', description: 'Description 2' }, { key: '3', label: 'Item 3', disabled: true }, { key: 'divider', divider: true }, { key: '4', label: 'Item 4', shortcut: '⌘K' } ] beforeEach(() => { vi.clearAllMocks() }) describe('Renderização', () => { it('renderiza corretamente', () => { const wrapper = mount(DatametriaMenu) expect(wrapper.find('.dm-menu').exists()).toBe(true) }) it('renderiza trigger padrão', () => { const wrapper = mount(DatametriaMenu, { props: { triggerText: 'Abrir Menu' } }) expect(wrapper.find('.dm-menu__button').text()).toContain('Abrir Menu') }) it('renderiza items quando aberto', async () => { const wrapper = mount(DatametriaMenu, { props: { items: mockItems }, attachTo: document.body }) await wrapper.find('.dm-menu__button').trigger('click') await wrapper.vm.$nextTick() expect(wrapper.emitted('open')).toBeTruthy() }) it('renderiza chevron icon', () => { const wrapper = mount(DatametriaMenu) expect(wrapper.find('.dm-menu__chevron').exists()).toBe(true) }) }) describe('Props', () => { it('aceita triggerText customizado', () => { const wrapper = mount(DatametriaMenu, { props: { triggerText: 'Custom Text' } }) expect(wrapper.find('.dm-menu__button').text()).toContain('Custom Text') }) it('aceita items array', () => { const wrapper = mount(DatametriaMenu, { props: { items: mockItems } }) expect(wrapper.props('items')).toEqual(mockItems) }) it('aceita placement', () => { const wrapper = mount(DatametriaMenu, { props: { placement: 'bottom-end' } }) expect(wrapper.props('placement')).toBe('bottom-end') }) it('aceita disabled', () => { const wrapper = mount(DatametriaMenu, { props: { disabled: true } }) expect(wrapper.find('.dm-menu').classes()).toContain('dm-menu--disabled') expect(wrapper.find('.dm-menu__button').element.disabled).toBe(true) }) it('aceita fullWidth', () => { const wrapper = mount(DatametriaMenu, { props: { fullWidth: true } }) expect(wrapper.props('fullWidth')).toBe(true) }) it('aceita showBackdrop', () => { const wrapper = mount(DatametriaMenu, { props: { showBackdrop: true } }) expect(wrapper.props('showBackdrop')).toBe(true) }) it('aceita closeOnItemClick', () => { const wrapper = mount(DatametriaMenu, { props: { closeOnItemClick: false } }) expect(wrapper.props('closeOnItemClick')).toBe(false) }) it('aceita offset customizado', () => { const wrapper = mount(DatametriaMenu, { props: { offset: 8 } }) expect(wrapper.props('offset')).toBe(8) }) }) describe('Interação', () => { it('abre menu ao clicar no trigger', async () => { const wrapper = mount(DatametriaMenu, { attachTo: document.body }) await wrapper.find('.dm-menu__button').trigger('click') expect(wrapper.emitted('open')).toBeTruthy() }) it('fecha menu ao clicar novamente no trigger', async () => { const wrapper = mount(DatametriaMenu, { attachTo: document.body }) const button = wrapper.find('.dm-menu__button') await button.trigger('click') await button.trigger('click') expect(wrapper.emitted('close')).toBeTruthy() }) it('emite item-click ao clicar em item', async () => { const wrapper = mount(DatametriaMenu, { props: { items: mockItems }, attachTo: document.body }) await wrapper.find('.dm-menu__button').trigger('click') await wrapper.vm.$nextTick() const exposed = wrapper.vm as any exposed.handleItemClick(mockItems[0], 0) expect(wrapper.emitted('item-click')).toBeTruthy() expect(wrapper.emitted('item-click')?.[0]).toEqual([mockItems[0], 0]) }) it('executa action do item ao clicar', async () => { const wrapper = mount(DatametriaMenu, { props: { items: mockItems }, attachTo: document.body }) const exposed = wrapper.vm as any exposed.handleItemClick(mockItems[0], 0) expect(mockItems[0].action).toHaveBeenCalled() }) it('não executa action de item disabled', async () => { const disabledItem = { ...mockItems[2], action: vi.fn() } const wrapper = mount(DatametriaMenu, { props: { items: [disabledItem] }, attachTo: document.body }) const exposed = wrapper.vm as any exposed.handleItemClick(disabledItem, 0) expect(wrapper.emitted('item-click')).toBeFalsy() }) it('fecha menu após clicar em item quando closeOnItemClick=true', async () => { const wrapper = mount(DatametriaMenu, { props: { items: mockItems, closeOnItemClick: true }, attachTo: document.body }) await wrapper.find('.dm-menu__button').trigger('click') const exposed = wrapper.vm as any exposed.handleItemClick(mockItems[0], 0) expect(wrapper.emitted('close')).toBeTruthy() }) it('não fecha menu após clicar em item quando closeOnItemClick=false', async () => { const wrapper = mount(DatametriaMenu, { props: { items: mockItems, closeOnItemClick: false }, attachTo: document.body }) await wrapper.find('.dm-menu__button').trigger('click') const exposed = wrapper.vm as any exposed.handleItemClick(mockItems[0], 0) expect(wrapper.emitted('close')).toBeFalsy() }) }) describe('Teclado', () => { it('abre menu com Enter', async () => { const wrapper = mount(DatametriaMenu, { attachTo: document.body }) await wrapper.find('.dm-menu__trigger').trigger('keydown', { key: 'Enter' }) expect(wrapper.emitted('open')).toBeTruthy() }) it('abre menu com Space', async () => { const wrapper = mount(DatametriaMenu, { attachTo: document.body }) await wrapper.find('.dm-menu__trigger').trigger('keydown', { key: ' ' }) expect(wrapper.emitted('open')).toBeTruthy() }) it('abre menu com ArrowDown', async () => { const wrapper = mount(DatametriaMenu, { attachTo: document.body }) await wrapper.find('.dm-menu__trigger').trigger('keydown', { key: 'ArrowDown' }) expect(wrapper.emitted('open')).toBeTruthy() }) it('fecha menu com Escape', async () => { const wrapper = mount(DatametriaMenu, { attachTo: document.body }) await wrapper.find('.dm-menu__button').trigger('click') await wrapper.find('.dm-menu__trigger').trigger('keydown', { key: 'Escape' }) expect(wrapper.emitted('close')).toBeTruthy() }) }) describe('Acessibilidade', () => { it('tem atributos ARIA corretos no trigger', () => { const wrapper = mount(DatametriaMenu) const trigger = wrapper.find('.dm-menu__trigger') expect(trigger.attributes('aria-expanded')).toBe('false') expect(trigger.attributes('aria-haspopup')).toBe('true') expect(trigger.attributes('aria-controls')).toBeDefined() }) it('atualiza aria-expanded quando abre', async () => { const wrapper = mount(DatametriaMenu, { attachTo: document.body }) await wrapper.find('.dm-menu__button').trigger('click') expect(wrapper.find('.dm-menu__trigger').attributes('aria-expanded')).toBe('true') }) it('button tem type="button"', () => { const wrapper = mount(DatametriaMenu) expect(wrapper.find('.dm-menu__button').attributes('type')).toBe('button') }) }) describe('Estados', () => { it('aplica classe disabled quando disabled=true', () => { const wrapper = mount(DatametriaMenu, { props: { disabled: true } }) expect(wrapper.find('.dm-menu').classes()).toContain('dm-menu--disabled') }) it('não abre quando disabled', async () => { const wrapper = mount(DatametriaMenu, { props: { disabled: true }, attachTo: document.body }) await wrapper.find('.dm-menu__button').trigger('click') expect(wrapper.emitted('open')).toBeFalsy() }) it('rotaciona chevron quando aberto', async () => { const wrapper = mount(DatametriaMenu, { attachTo: document.body }) await wrapper.find('.dm-menu__button').trigger('click') expect(wrapper.find('.dm-menu__chevron').classes()).toContain('dm-menu__chevron--open') }) }) describe('CSS Variables', () => { it('usa CSS Variables padronizadas', () => { const wrapper = mount(DatametriaMenu) const button = wrapper.find('.dm-menu__button') const styles = button.element.style // Verifica que o componente está pronto para usar CSS Variables expect(button.exists()).toBe(true) }) it('aplica estilos com fallbacks', () => { const wrapper = mount(DatametriaMenu) expect(wrapper.find('.dm-menu__button').exists()).toBe(true) }) }) describe('Métodos Expostos', () => { it('expõe método open', () => { const wrapper = mount(DatametriaMenu, { attachTo: document.body }) const exposed = wrapper.vm as any expect(typeof exposed.open).toBe('function') }) it('expõe método close', () => { const wrapper = mount(DatametriaMenu, { attachTo: document.body }) const exposed = wrapper.vm as any expect(typeof exposed.close).toBe('function') }) it('expõe método toggle', () => { const wrapper = mount(DatametriaMenu, { attachTo: document.body }) const exposed = wrapper.vm as any expect(typeof exposed.toggle).toBe('function') }) it('expõe computed isOpen', () => { const wrapper = mount(DatametriaMenu, { attachTo: document.body }) const exposed = wrapper.vm as any expect(exposed.isOpen).toBeDefined() }) }) describe('Slots', () => { it('aceita slot trigger customizado', () => { const wrapper = mount(DatametriaMenu, { slots: { trigger: '<button class="custom-trigger">Custom</button>' } }) expect(wrapper.find('.custom-trigger').exists()).toBe(true) }) it('aceita slot default para items customizados', async () => { const wrapper = mount(DatametriaMenu, { slots: { default: '<div class="custom-items">Custom Items</div>' }, attachTo: document.body }) await wrapper.find('.dm-menu__button').trigger('click') await wrapper.vm.$nextTick() // Slot default só aparece quando menu está aberto (dentro do Teleport) expect(wrapper.emitted('open')).toBeTruthy() }) }) })