vuetify
Version:
Vue Material Component Framework
324 lines (245 loc) • 8.02 kB
text/typescript
// Components
import VCombobox from '../VCombobox'
// Utilities
import {
mount,
Wrapper,
} from '@vue/test-utils'
describe('VCombobox.ts', () => {
type Instance = InstanceType<typeof VCombobox>
let mountFunction: (options?: object) => Wrapper<Instance>
beforeEach(() => {
document.body.setAttribute('data-app', 'true')
mountFunction = (options = {}) => {
return mount(VCombobox, {
// https://github.com/vuejs/vue-test-utils/issues/1130
sync: false,
mocks: {
$vuetify: {
lang: {
t: (val: string) => val,
},
theme: {
dark: false,
},
},
},
...options,
})
}
})
// TODO: this fails without sync, nextTick doesn't help
// https://github.com/vuejs/vue-test-utils/issues/1130
it.skip('should evaluate the range of an integer', async () => {
const wrapper = mountFunction({
propsData: {
value: 11,
},
})
await wrapper.vm.$nextTick()
expect(wrapper.vm.currentRange).toBe(2)
wrapper.setProps({ value: 0 })
await wrapper.vm.$nextTick()
expect(wrapper.vm.currentRange).toBe(1)
})
it('should not use search input when blurring', async () => {
const wrapper = mountFunction({
attachToDocument: true,
propsData: {
eager: true,
items: [1, 12],
},
})
const event = jest.fn()
wrapper.vm.$on('input', event)
const input = wrapper.find('input')
input.trigger('focus')
await wrapper.vm.$nextTick()
wrapper.setProps({ searchInput: '1' })
await wrapper.vm.$nextTick()
expect(wrapper.vm.internalSearch).toBe('1')
const list = wrapper.findAll('.v-list-item').at(1)
list.trigger('click')
await wrapper.vm.$nextTick()
expect(event).toHaveBeenCalledWith(12)
})
it('should not use search input if an option is selected from the menu', async () => {
const item = { value: 123, text: 'Foo' }
const wrapper = mountFunction({
propsData: {
items: [item],
},
})
const event = jest.fn()
wrapper.vm.$on('input', event)
wrapper.setData({ isMenuActive: true })
await wrapper.vm.$nextTick()
wrapper.vm.selectItem(item)
await wrapper.vm.$nextTick()
wrapper.setData({ isMenuActive: false })
await wrapper.vm.$nextTick()
expect(event).toHaveBeenCalledWith(item)
})
it('should not populate search field if value is falsey', async () => {
const wrapper = mountFunction()
const event = jest.fn()
wrapper.vm.$on('input', event)
wrapper.setData({ isMenuActive: true })
await wrapper.vm.$nextTick()
wrapper.setProps({ searchInput: '' })
await wrapper.vm.$nextTick()
wrapper.setData({ isMenuActive: false })
await wrapper.vm.$nextTick()
expect(event).not.toHaveBeenCalled()
})
// TODO: fails with TS 3.9
it.skip('should clear value', async () => {
const wrapper = mountFunction({
attachToDocument: true,
})
await wrapper.vm.$nextTick()
const change = jest.fn()
const input = wrapper.find('input')
const element = input.element as HTMLInputElement
wrapper.vm.$on('change', change)
wrapper.vm.$on('input', change)
input.trigger('focus')
element.value = 'foo'
input.trigger('input')
input.trigger('keydown.enter')
await wrapper.vm.$nextTick()
expect(change).toHaveBeenCalledWith('foo')
expect(change).toHaveBeenCalledTimes(2)
expect(wrapper.vm.internalValue).toBe('foo')
element.value = ''
input.trigger('input')
input.trigger('keydown.enter')
await wrapper.vm.$nextTick()
expect(wrapper.vm.internalValue).toBe('')
expect(change).toHaveBeenCalledTimes(4)
})
it('should call methods on blur', async () => {
const updateCombobox = jest.fn()
const wrapper = mountFunction({
attachToDocument: true,
methods: {
updateCombobox,
},
})
const e = { preventDefault: jest.fn() }
wrapper.vm.onEnterDown(e)
await wrapper.vm.$nextTick()
// https://github.com/vuetifyjs/vuetify/issues/4974
expect(e.preventDefault).toHaveBeenCalled()
expect(updateCombobox).toHaveBeenCalledTimes(1)
})
it('should emit custom value on blur', async () => {
const wrapper = mountFunction()
const input = wrapper.find('input')
const element = input.element as HTMLInputElement
const change = jest.fn()
wrapper.vm.$on('change', change)
input.trigger('focus')
await wrapper.vm.$nextTick()
element.value = 'foo'
input.trigger('input')
input.trigger('keydown.enter')
await wrapper.vm.$nextTick()
expect(change).toHaveBeenCalledWith('foo')
input.trigger('keydown.esc')
expect(wrapper.vm.isMenuActive).toBe(false)
element.value = ''
input.trigger('input')
await wrapper.vm.$nextTick()
expect(wrapper.vm.isMenuActive).toBe(false)
})
it('should conditionally show the menu', async () => {
const wrapper = mountFunction({
attachToDocument: true,
propsData: {
items: ['foo', 'bar', 'fizz'],
searchInput: 'foobar',
},
})
const slot = wrapper.find('.v-input__slot')
const input = wrapper.find('input')
// Focus input should only focus
input.trigger('focus')
expect(wrapper.vm.isFocused).toBe(true)
expect(wrapper.vm.$_menuProps.value).toBe(false)
slot.trigger('click')
expect(wrapper.vm.$_menuProps.value).toBe(false)
// TODO: Add expects for tags when impl
})
it('should return an object', () => {
const items = [
{ text: 'Programming', value: 0 },
{ text: 'Design', value: 1 },
{ text: 'Vue', value: 2 },
{ text: 'Vuetify', value: 3 },
]
const wrapper = mountFunction({
propsData: {
items,
},
})
const input = wrapper.find('input')
const element = input.element as HTMLInputElement
const event = jest.fn()
wrapper.vm.$on('input', event)
input.trigger('focus')
element.value = 'Programming'
input.trigger('input')
wrapper.vm.selectItem(items[0])
expect(wrapper.vm.isFocused).toBe(true)
expect(event).toHaveBeenCalledWith(items[0])
input.trigger('keydown.tab')
expect(wrapper.vm.isFocused).toBe(false)
expect(wrapper.vm.internalValue).toEqual(items[0])
})
// https://github.com/vuetifyjs/vuetify/issues/5008
// TODO: this fails without sync, nextTick doesn't help
// https://github.com/vuejs/vue-test-utils/issues/1130
it.skip('should select item if menu index is greater than -1', async () => {
const selectItem = jest.fn()
const wrapper = mountFunction({
propsData: {
items: ['foo'],
},
methods: { selectItem },
})
const input = wrapper.find('input')
input.trigger('focus')
input.trigger('keydown.enter')
input.trigger('keydown.down')
await wrapper.vm.$nextTick()
expect(wrapper.vm.getMenuIndex()).toBe(0)
input.trigger('keydown.enter')
expect(selectItem).toHaveBeenCalledWith('foo')
})
// https://github.com/vuetifyjs/vuetify/issues/8476
it('should properly compare falsey values when setting', async () => {
const wrapper = mountFunction()
wrapper.vm.setValue(0)
expect(wrapper.vm.internalValue).toBe(0)
wrapper.vm.setValue('')
expect(wrapper.vm.internalValue).toBe('')
wrapper.vm.setValue(null)
expect(wrapper.vm.internalValue).toBeUndefined()
wrapper.vm.setValue(undefined)
expect(wrapper.vm.internalValue).toBeUndefined()
wrapper.setData({ lazySearch: 'foo' })
wrapper.vm.setValue(null)
expect(wrapper.vm.internalValue).toBe('foo')
wrapper.vm.setValue(undefined)
expect(wrapper.vm.internalValue).toBe('foo')
})
it('should change autocomplete attribute', () => {
const wrapper = mountFunction({
attrs: {
autocomplete: 'on',
},
})
expect(wrapper.vm.$attrs.autocomplete).toBe('on')
})
})