UNPKG

vue3-multilang-country-selector

Version:

A Vue 3 multilingual country selector component with internationalization, search and customization options | Vue 3 多语言国家选择器组件,支持国际化、搜索和自定义选项

227 lines (171 loc) 7.75 kB
import { describe, it, expect, beforeEach } from 'vitest' import { mount, type VueWrapper } from '@vue/test-utils' import CountrySelector from '../CountrySelector.vue' import type { Country } from '../../types' const mockCountries: Country[] = [ { code: 'US', name: 'United States', flag: '🇺🇸', dialCode: '+1' }, { code: 'CA', name: 'Canada', flag: '🇨🇦', dialCode: '+1' }, { code: 'GB', name: 'United Kingdom', flag: '🇬🇧', dialCode: '+44' } ] describe('CountrySelector', () => { let wrapper: VueWrapper<any> beforeEach(() => { wrapper = mount(CountrySelector, { props: { countries: mockCountries } }) }) it('renders correctly', () => { expect(wrapper.find('.country-selector').exists()).toBe(true) expect(wrapper.find('.country-selector__placeholder').text()).toBe('Select a country') }) it('shows placeholder when no country is selected', () => { expect(wrapper.find('.country-selector__placeholder').exists()).toBe(true) expect(wrapper.find('.country-selector__selected').exists()).toBe(false) }) it('displays selected country when modelValue is provided', async () => { await wrapper.setProps({ modelValue: 'US' }) expect(wrapper.find('.country-selector__selected').exists()).toBe(true) expect(wrapper.find('.country-selector__name').text()).toBe('United States') expect(wrapper.find('.country-selector__flag').text()).toBe('🇺🇸') }) it('shows dial code when showDialCode is true', async () => { await wrapper.setProps({ modelValue: 'US', showDialCode: true }) expect(wrapper.find('.country-selector__dial-code').text()).toBe('+1') }) it('hides flag when showFlag is false', async () => { await wrapper.setProps({ modelValue: 'US', showFlag: false }) expect(wrapper.find('.country-selector__flag').exists()).toBe(false) }) it('opens dropdown when clicked', async () => { await wrapper.find('.country-selector__input-wrapper').trigger('click') expect(wrapper.find('.country-selector__dropdown').exists()).toBe(true) expect(wrapper.vm.isOpen).toBe(true) }) it('shows search input when searchable is true', async () => { await wrapper.find('.country-selector__input-wrapper').trigger('click') expect(wrapper.find('.country-selector__search-input').exists()).toBe(true) }) it('hides search input when searchable is false', async () => { await wrapper.setProps({ searchable: false }) await wrapper.find('.country-selector__input-wrapper').trigger('click') expect(wrapper.find('.country-selector__search-input').exists()).toBe(false) }) it('filters countries based on search query', async () => { await wrapper.find('.country-selector__input-wrapper').trigger('click') const searchInput = wrapper.find('.country-selector__search-input') await searchInput.setValue('United') const options = wrapper.findAll('.country-selector__option') expect(options).toHaveLength(2) // United States and United Kingdom }) it('emits update:modelValue when country is selected', async () => { await wrapper.find('.country-selector__input-wrapper').trigger('click') const firstOption = wrapper.find('.country-selector__option') await firstOption.trigger('click') const emittedEvents = wrapper.emitted('update:modelValue') expect(emittedEvents).toBeTruthy() expect(emittedEvents?.[0]).toEqual(['US']) }) it('emits change event when country is selected', async () => { await wrapper.find('.country-selector__input-wrapper').trigger('click') const firstOption = wrapper.find('.country-selector__option') await firstOption.trigger('click') const emittedEvents = wrapper.emitted('change') expect(emittedEvents).toBeTruthy() expect(emittedEvents?.[0]?.[0]).toEqual(mockCountries[0]) }) it('shows clear button when clearable is true and country is selected', async () => { await wrapper.setProps({ modelValue: 'US', clearable: true }) expect(wrapper.find('.country-selector__clear').exists()).toBe(true) }) it('clears selection when clear button is clicked', async () => { await wrapper.setProps({ modelValue: 'US', clearable: true }) await wrapper.find('.country-selector__clear').trigger('click') const modelValueEvents = wrapper.emitted('update:modelValue') const changeEvents = wrapper.emitted('change') expect(modelValueEvents).toBeTruthy() expect(modelValueEvents?.[0]).toEqual(['']) expect(changeEvents).toBeTruthy() expect(changeEvents?.[0]).toEqual([null]) }) it('applies correct size class', async () => { await wrapper.setProps({ size: 'large' }) expect(wrapper.find('.country-selector--large').exists()).toBe(true) }) it('applies disabled class when disabled', async () => { await wrapper.setProps({ disabled: true }) expect(wrapper.find('.country-selector--disabled').exists()).toBe(true) }) it('does not open dropdown when disabled', async () => { await wrapper.setProps({ disabled: true }) await wrapper.find('.country-selector__input-wrapper').trigger('click') expect(wrapper.vm.isOpen).toBe(false) }) it('accepts language prop', async () => { await wrapper.setProps({ language: 'zh-CN' }) // 测试语言属性是否被正确设置 expect(wrapper.vm.language).toBe('zh-CN') }) it('displays localized UI text', async () => { await wrapper.setProps({ language: 'zh-CN' }) expect(wrapper.find('.country-selector__placeholder').text()).toBe('选择国家') }) it('displays localized search placeholder', async () => { await wrapper.setProps({ language: 'zh-CN' }) await wrapper.find('.country-selector__input-wrapper').trigger('click') const searchInput = wrapper.find('.country-selector__search-input') expect(searchInput.attributes('placeholder')).toBe('搜索国家...') }) it('emits country code when type is country (default)', async () => { await wrapper.find('.country-selector__input-wrapper').trigger('click') const firstOption = wrapper.find('.country-selector__option') await firstOption.trigger('click') const emittedEvents = wrapper.emitted('update:modelValue') expect(emittedEvents).toBeTruthy() expect(emittedEvents?.[0]).toEqual(['US']) }) it('emits dial code without + when type is phone', async () => { await wrapper.setProps({ type: 'phone' }) await wrapper.find('.country-selector__input-wrapper').trigger('click') const firstOption = wrapper.find('.country-selector__option') await firstOption.trigger('click') const emittedEvents = wrapper.emitted('update:modelValue') expect(emittedEvents).toBeTruthy() expect(emittedEvents?.[0]).toEqual(['1']) }) it('displays selected country when type is phone and modelValue is dial code without +', async () => { await wrapper.setProps({ type: 'phone', modelValue: '1' }) expect(wrapper.find('.country-selector__selected').exists()).toBe(true) expect(wrapper.find('.country-selector__name').text()).toBe('United States') }) it('shows correct selected option when type is phone', async () => { await wrapper.setProps({ type: 'phone', modelValue: '44' }) await wrapper.find('.country-selector__input-wrapper').trigger('click') const options = wrapper.findAll('.country-selector__option') const selectedOption = options.find(option => option.classes().includes('country-selector__option--selected') ) expect(selectedOption?.find('.country-selector__name').text()).toBe('United Kingdom') }) })