UNPKG

@coreui/vue

Version:

UI Components Library for Vue.js

368 lines (306 loc) 10.2 kB
import { mount } from '@vue/test-utils' import { CChipInput } from '../../../index' describe('CChipInput', () => { it('has correct name', () => { expect(CChipInput.name).toBe('CChipInput') }) it('renders correctly', () => { const wrapper = mount(CChipInput) expect(wrapper.html()).toMatchSnapshot() expect(wrapper.classes()).toContain('chip-input') }) it('renders with initial defaultValue', async () => { const wrapper = mount(CChipInput, { props: { defaultValue: ['test1', 'test2'], }, }) await wrapper.vm.$nextTick() const chips = wrapper.findAll('.chip') expect(chips.length).toBe(2) expect(chips[0].text()).toBe('test1') expect(chips[1].text()).toBe('test2') }) it('renders with controlled modelValue', async () => { const wrapper = mount(CChipInput, { props: { modelValue: ['chip1', 'chip2', 'chip3'], }, }) await wrapper.vm.$nextTick() const chips = wrapper.findAll('.chip') expect(chips.length).toBe(3) }) it('creates chip on Enter key', async () => { const wrapper = mount(CChipInput) const input = wrapper.find('input[type="text"]') await input.setValue('newchip') await input.trigger('keydown', { key: 'Enter' }) expect(wrapper.emitted('add')?.[0]).toEqual(['newchip']) expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([['newchip']]) expect(wrapper.emitted('change')?.[0]).toEqual([['newchip']]) expect((input.element as HTMLInputElement).value).toBe('') }) it('creates chips on separator', async () => { const wrapper = mount(CChipInput, { props: { separator: ',', }, }) const input = wrapper.find('input[type="text"]') await input.setValue('one,two,three') expect(wrapper.emitted('add')?.length).toBe(2) expect(wrapper.emitted('add')?.[0]).toEqual(['one']) expect(wrapper.emitted('add')?.[1]).toEqual(['two']) expect((input.element as HTMLInputElement).value).toBe('three') }) it('respects maxChips limit', async () => { const wrapper = mount(CChipInput, { props: { maxChips: 2, modelValue: ['one', 'two'], }, }) const input = wrapper.find('input[type="text"]') await input.setValue('three') await input.trigger('keydown', { key: 'Enter' }) expect(wrapper.emitted('add')).toBeFalsy() expect((input.element as HTMLInputElement).value).toBe('three') }) it('removes chip on remove button click', async () => { const wrapper = mount(CChipInput, { props: { modelValue: ['test'], removable: true, }, }) const removeBtn = wrapper.find('.chip-remove') await removeBtn.trigger('click') expect(wrapper.emitted('remove')?.[0]).toEqual(['test']) expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([[]]) }) it('does not allow duplicate values', async () => { const wrapper = mount(CChipInput, { props: { modelValue: ['existing'], }, }) const input = wrapper.find('input[type="text"]') await input.setValue('existing') await input.trigger('keydown', { key: 'Enter' }) expect(wrapper.emitted('add')).toBeFalsy() expect(wrapper.emitted('update:modelValue')).toBeFalsy() }) it('trims and filters empty values', async () => { const wrapper = mount(CChipInput) const input = wrapper.find('input[type="text"]') await input.setValue(' ') await input.trigger('keydown', { key: 'Enter' }) expect(wrapper.emitted('add')).toBeFalsy() }) it('creates chip on blur when createOnBlur is true', async () => { const wrapper = mount(CChipInput, { props: { createOnBlur: true, }, }) const input = wrapper.find('input[type="text"]') await input.setValue('onblur') await input.trigger('blur') expect(wrapper.emitted('add')?.[0]).toEqual(['onblur']) }) it('does not create chip on blur when createOnBlur is false', async () => { const wrapper = mount(CChipInput, { props: { createOnBlur: false, }, }) const input = wrapper.find('input[type="text"]') await input.setValue('noblur') await input.trigger('blur') expect(wrapper.emitted('add')).toBeFalsy() }) it('renders with label', () => { const wrapper = mount(CChipInput, { props: { label: 'Tags', id: 'tags-input', }, }) const label = wrapper.find('label') expect(label.exists()).toBe(true) expect(label.text()).toBe('Tags') expect(label.attributes('for')).toBe('tags-input') }) it('renders with placeholder', () => { const wrapper = mount(CChipInput, { props: { placeholder: 'Enter tags', }, }) const input = wrapper.find('input[type="text"]') expect(input.attributes('placeholder')).toBe('Enter tags') }) it('renders hidden input for form submission', () => { const wrapper = mount(CChipInput, { props: { name: 'tags', modelValue: ['tag1', 'tag2'], }, }) const hiddenInput = wrapper.find('input[type="hidden"]') expect(hiddenInput.exists()).toBe(true) expect(hiddenInput.attributes('name')).toBe('tags') expect(hiddenInput.attributes('value')).toBe('tag1,tag2') }) it('applies size classes', () => { const wrapperSm = mount(CChipInput, { props: { size: 'sm', }, }) expect(wrapperSm.classes()).toContain('chip-input-sm') const wrapperLg = mount(CChipInput, { props: { size: 'lg', }, }) expect(wrapperLg.classes()).toContain('chip-input-lg') }) it('handles disabled state', () => { const wrapper = mount(CChipInput, { props: { disabled: true, }, }) const input = wrapper.find('input[type="text"]') expect(wrapper.classes()).toContain('disabled') expect(input.attributes('disabled')).toBeDefined() expect(wrapper.attributes('aria-disabled')).toBe('true') }) it('handles readonly state', () => { const wrapper = mount(CChipInput, { props: { readOnly: true, }, }) const input = wrapper.find('input[type="text"]') expect(input.attributes('readonly')).toBeDefined() expect(wrapper.attributes('aria-readonly')).toBe('true') }) it('does not add chips when disabled', async () => { const wrapper = mount(CChipInput, { props: { disabled: true, }, }) const input = wrapper.find('input[type="text"]') await input.setValue('test') await input.trigger('keydown', { key: 'Enter' }) expect(wrapper.emitted('add')).toBeFalsy() }) it('does not remove chips when disabled', async () => { const wrapper = mount(CChipInput, { props: { disabled: true, modelValue: ['test'], }, }) const removeBtn = wrapper.find('.chip-remove') expect(removeBtn.exists()).toBe(false) }) it('emits input event on text input change', async () => { const wrapper = mount(CChipInput) const input = wrapper.find('input[type="text"]') await input.setValue('typing') expect(wrapper.emitted('input')?.[0]).toEqual(['typing']) }) it('handles selectable chips', async () => { const wrapper = mount(CChipInput, { props: { selectable: true, modelValue: ['chip1', 'chip2'], }, }) const chips = wrapper.findAllComponents({ name: 'CChip' }) expect(chips[0].props('selectable')).toBe(true) }) it('handles paste with separator', async () => { const wrapper = mount(CChipInput, { props: { separator: ',', }, }) const input = wrapper.find('input[type="text"]') // Create a mock clipboard data const clipboardData = { getData: jest.fn().mockReturnValue('one,two,three'), } await input.trigger('paste', { clipboardData, }) expect(wrapper.emitted('add')?.length).toBe(3) expect(wrapper.emitted('add')?.[0]).toEqual(['one']) expect(wrapper.emitted('add')?.[1]).toEqual(['two']) expect(wrapper.emitted('add')?.[2]).toEqual(['three']) }) it('applies chipClassName as string', async () => { const wrapper = mount(CChipInput, { props: { chipClassName: 'custom-chip', modelValue: ['test'], }, }) await wrapper.vm.$nextTick() const chip = wrapper.find('.chip') expect(chip.classes()).toContain('custom-chip') }) it('applies chipClassName as function', async () => { const classNameFn = (value: string) => `chip-${value}` const wrapper = mount(CChipInput, { props: { chipClassName: classNameFn, modelValue: ['primary', 'secondary'], }, }) await wrapper.vm.$nextTick() const chips = wrapper.findAll('.chip') expect(chips[0].classes()).toContain('chip-primary') expect(chips[1].classes()).toContain('chip-secondary') }) it('focuses input on container click', async () => { const wrapper = mount(CChipInput, { attachTo: document.body, }) await wrapper.trigger('click') const input = wrapper.find('input[type="text"]').element as HTMLInputElement expect(document.activeElement).toBe(input) wrapper.unmount() }) it('clears input on Escape key', async () => { const wrapper = mount(CChipInput) const input = wrapper.find('input[type="text"]') await input.setValue('test') await input.trigger('keydown', { key: 'Escape' }) expect((input.element as HTMLInputElement).value).toBe('') }) it('focuses input when typing in container', async () => { const wrapper = mount(CChipInput, { attachTo: document.body, }) await wrapper.trigger('keydown', { key: 'a' }) const input = wrapper.find('input[type="text"]').element as HTMLInputElement expect(document.activeElement).toBe(input) wrapper.unmount() }) it('does not show remove buttons when removable is false', () => { const wrapper = mount(CChipInput, { props: { removable: false, modelValue: ['test'], }, }) const removeBtn = wrapper.find('.chip-remove') expect(removeBtn.exists()).toBe(false) }) })