import { describe, it, expect, vi } from 'vitest' import { mount } from '@vue/test-utils' import BasePill from '../../components/BasePill.vue' describe('BasePill', () => { describe('rendering with default props', () => { it('should render pill with default variant and size', () => { const wrapper = mount(BasePill, { slots: { default: 'Label' }, }) expect(wrapper.find('.mint-pill').exists()).toBe(true) expect(wrapper.find('.mint-pill--default').exists()).toBe(true) expect(wrapper.find('.mint-pill--md').exists()).toBe(true) }) it('should render label content', () => { const wrapper = mount(BasePill, { slots: { default: 'Test Label' }, }) expect(wrapper.find('.mint-pill__label').text()).toBe('Test Label') }) it('should not show remove button by default', () => { const wrapper = mount(BasePill, { slots: { default: 'Label' }, }) expect(wrapper.find('.mint-pill__remove').exists()).toBe(false) }) it('should not show icon slot by default', () => { const wrapper = mount(BasePill, { slots: { default: 'Label' }, }) expect(wrapper.find('.mint-pill__icon').exists()).toBe(false) }) }) describe('variant prop', () => { it('should apply primary variant class', () => { const wrapper = mount(BasePill, { props: { variant: 'primary' }, slots: { default: 'Primary' }, }) expect(wrapper.find('.mint-pill--primary').exists()).toBe(true) }) it('should apply success variant class', () => { const wrapper = mount(BasePill, { props: { variant: 'success' }, slots: { default: 'Success' }, }) expect(wrapper.find('.mint-pill--success').exists()).toBe(true) }) it('should apply warning variant class', () => { const wrapper = mount(BasePill, { props: { variant: 'warning' }, slots: { default: 'Warning' }, }) expect(wrapper.find('.mint-pill--warning').exists()).toBe(true) }) it('should apply error variant class', () => { const wrapper = mount(BasePill, { props: { variant: 'error' }, slots: { default: 'Error' }, }) expect(wrapper.find('.mint-pill--error').exists()).toBe(true) }) it('should apply info variant class', () => { const wrapper = mount(BasePill, { props: { variant: 'info' }, slots: { default: 'Info' }, }) expect(wrapper.find('.mint-pill--info').exists()).toBe(true) }) it('should apply outline variant class', () => { const wrapper = mount(BasePill, { props: { variant: 'outline' }, slots: { default: 'Outline' }, }) expect(wrapper.find('.mint-pill--outline').exists()).toBe(true) }) }) describe('size prop', () => { it('should apply small size class', () => { const wrapper = mount(BasePill, { props: { size: 'sm' }, slots: { default: 'Small' }, }) expect(wrapper.find('.mint-pill--sm').exists()).toBe(true) }) it('should apply medium size class', () => { const wrapper = mount(BasePill, { props: { size: 'md' }, slots: { default: 'Medium' }, }) expect(wrapper.find('.mint-pill--md').exists()).toBe(true) }) it('should apply large size class', () => { const wrapper = mount(BasePill, { props: { size: 'lg' }, slots: { default: 'Large' }, }) expect(wrapper.find('.mint-pill--lg').exists()).toBe(true) }) }) describe('removable prop', () => { it('should show remove button when removable is true', () => { const wrapper = mount(BasePill, { props: { removable: true }, slots: { default: 'Removable' }, }) expect(wrapper.find('.mint-pill__remove').exists()).toBe(true) }) it('should emit remove event when remove button is clicked', async () => { const wrapper = mount(BasePill, { props: { removable: true }, slots: { default: 'Removable' }, }) await wrapper.find('.mint-pill__remove').trigger('click') expect(wrapper.emitted('remove')).toHaveLength(1) }) it('should not show remove button when disabled', () => { const wrapper = mount(BasePill, { props: { removable: true, disabled: true }, slots: { default: 'Disabled' }, }) expect(wrapper.find('.mint-pill__remove').exists()).toBe(false) }) it('should stop event propagation on remove click', async () => { const wrapper = mount(BasePill, { props: { removable: true }, slots: { default: 'Removable' }, }) const button = wrapper.find('.mint-pill__remove') const clickEvent = new MouseEvent('click', { bubbles: true }) const stopPropagationSpy = vi.spyOn(clickEvent, 'stopPropagation') await button.element.dispatchEvent(clickEvent) expect(stopPropagationSpy).toHaveBeenCalled() }) }) describe('disabled prop', () => { it('should apply disabled class when disabled is true', () => { const wrapper = mount(BasePill, { props: { disabled: true }, slots: { default: 'Disabled' }, }) expect(wrapper.find('.mint-pill--disabled').exists()).toBe(true) }) it('should not emit remove event when disabled', async () => { const wrapper = mount(BasePill, { props: { removable: true, disabled: true }, slots: { default: 'Disabled' }, }) // Remove button shouldn't exist when disabled + removable expect(wrapper.find('.mint-pill__remove').exists()).toBe(false) }) }) describe('icon prop and slot', () => { it('should show icon slot when icon is true', () => { const wrapper = mount(BasePill, { props: { icon: true }, slots: { default: 'With Icon', icon: '', }, }) expect(wrapper.find('.mint-pill__icon').exists()).toBe(true) expect(wrapper.find('.test-icon').exists()).toBe(true) }) it('should apply with-icon class when icon is true', () => { const wrapper = mount(BasePill, { props: { icon: true }, slots: { default: 'With Icon', icon: '', }, }) expect(wrapper.find('.mint-pill--with-icon').exists()).toBe(true) }) it('should not show icon slot when icon is false', () => { const wrapper = mount(BasePill, { props: { icon: false }, slots: { default: 'No Icon', icon: '', }, }) expect(wrapper.find('.mint-pill__icon').exists()).toBe(false) }) }) describe('combined props', () => { it('should apply multiple classes correctly', () => { const wrapper = mount(BasePill, { props: { variant: 'success', size: 'sm', disabled: true, icon: true, }, slots: { default: 'Combined', icon: '', }, }) const pill = wrapper.find('.mint-pill') expect(pill.classes()).toContain('mint-pill--success') expect(pill.classes()).toContain('mint-pill--sm') expect(pill.classes()).toContain('mint-pill--disabled') expect(pill.classes()).toContain('mint-pill--with-icon') }) it('should render with icon and remove button', () => { const wrapper = mount(BasePill, { props: { icon: true, removable: true, }, slots: { default: 'Full Featured', icon: '', }, }) expect(wrapper.find('.mint-pill__icon').exists()).toBe(true) expect(wrapper.find('.mint-pill__remove').exists()).toBe(true) }) }) describe('accessibility', () => { it('should have aria-label on remove button', () => { const wrapper = mount(BasePill, { props: { removable: true }, slots: { default: 'Removable' }, }) const button = wrapper.find('.mint-pill__remove') expect(button.attributes('aria-label')).toBe('Remove') }) it('should have proper button type', () => { const wrapper = mount(BasePill, { props: { removable: true }, slots: { default: 'Removable' }, }) const button = wrapper.find('.mint-pill__remove') expect(button.attributes('type')).toBe('button') }) }) describe('edge cases', () => { it('should handle empty label', () => { const wrapper = mount(BasePill) expect(wrapper.find('.mint-pill__label').exists()).toBe(true) expect(wrapper.find('.mint-pill__label').text()).toBe('') }) it('should handle long text labels', () => { const longText = 'This is a very long label that might need to wrap or be truncated' const wrapper = mount(BasePill, { slots: { default: longText }, }) expect(wrapper.find('.mint-pill__label').text()).toBe(longText) }) it('should render SVG icon in remove button', () => { const wrapper = mount(BasePill, { props: { removable: true }, slots: { default: 'Test' }, }) const svg = wrapper.find('.mint-pill__remove-icon') expect(svg.exists()).toBe(true) expect(svg.element.tagName).toBe('svg') }) }) })