2
0
mirror of https://github.com/tenrok/vue-select.git synced 2026-06-16 09:10:33 +03:00

bump test coverage up to 95%, deprecate getOptionValue, small optimizations

This commit is contained in:
Jeff Sagal
2016-05-28 11:58:18 -07:00
parent bd7dabc639
commit 03ba6376e3
2 changed files with 339 additions and 118 deletions
+305 -82
View File
@@ -18,13 +18,29 @@ function trigger(target, event, process) {
return e
}
function triggerMouse(target, event, process) {
var e = document.createEvent('MouseEvent')
e.initEvent('event', true, true)
if (process) process(e)
target.dispatchEvent(e)
return e
}
function triggerFocusEvent(target, event, process) {
var e = document.createEvent('FocusEvent')
e.initEvent('event', true, true)
if (process) process(e)
target.dispatchEvent(e)
return e
}
/**
* Optionally set the search term, then simulate a return keypress.
* @param vm
* @param search
*/
function searchSubmit(vm, search = false) {
if( search ) {
if (search) {
vm.$children[0].search = search
}
@@ -45,7 +61,7 @@ describe('Select.vue', () => {
options: ['one', 'two', 'three']
}
}).$mount()
expect(vm.$children[0].value).toEqual(['one'])
expect(vm.$children[0].value).toEqual(vm.value)
})
it('can accept an array of objects and pre-selected value (single)', () => {
@@ -57,8 +73,7 @@ describe('Select.vue', () => {
options: [{label: 'This is Foo', value: 'foo'}, {label: 'This is Bar', value: 'bar'}]
}
}).$mount()
expect(vm.$children[0].$get('value').value).toEqual('foo')
expect(vm.$children[0].$get('value').label).toEqual('This is Foo')
expect(vm.$children[0].value).toEqual(vm.value)
})
it('can accept an array of objects and pre-selected values (multiple)', () => {
@@ -70,12 +85,7 @@ describe('Select.vue', () => {
options: [{label: 'This is Foo', value: 'foo'}, {label: 'This is Bar', value: 'bar'}]
}
}).$mount()
var values = vm.$children[0].$get('value')
var labels = []
labels = values.map(value => value.label)
values = values.map(value => value.value)
expect(values).toEqual(['foo', 'bar'])
expect(labels).toEqual(['This is Foo', 'This is Bar'])
expect(vm.$children[0].value).toEqual(vm.value)
})
it('can determine if the value prop is empty', () => {
@@ -120,11 +130,34 @@ describe('Select.vue', () => {
}).$mount()
vm.$children[0].options = ['four', 'five', 'six']
Vue.nextTick(() => {
expect(vm.$children[0].$get('value')).toEqual([])
expect(vm.$children[0].value).toEqual([])
done()
})
})
it('resets the selected values when the multiple property changes', (done) => {
const vm = new Vue({
template: '<div><v-select :options="options" :value.sync="value" :multiple="multiple"></v-select></div>',
components: {vSelect},
data: {
value: ['one'],
multiple: true,
options: ['one', 'two', 'three']
}
}).$mount()
vm.multiple = false
Vue.nextTick(() => {
expect(vm.$children[0].value).toEqual(null)
vm.multiple = true
Vue.nextTick(() => {
expect(vm.$children[0].value).toEqual([])
done()
})
})
})
it('can retain values present in a new array of options', () => {
const vm = new Vue({
template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
@@ -137,80 +170,18 @@ describe('Select.vue', () => {
vm.$children[0].$set('options', ['one', 'five', 'six'])
expect(vm.$children[0].value).toEqual(['one'])
})
})
describe('Removing values', () => {
it('removes the given tag when its close icon is clicked', (done) => {
it('can determine if an object is already selected', () => {
const vm = new Vue({
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
template: '<div><v-select :options="options" multiple :value.sync="value"></v-select></div>',
components: {vSelect},
data: {
value: ['one'],
options: ['one', 'two', 'three']
value: [{label: 'one'}],
options: [{label: 'one'}]
}
}).$mount()
vm.$children[0].$els.toggle.querySelector('.close').click()
Vue.nextTick(() => {
expect(vm.$children[0].$get('value')).toEqual([])
done()
})
})
it('removes the last item in the value array on delete keypress when multiple is true', () => {
const vm = new Vue({
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
components: {vSelect},
data: {
value: ['one', 'two'],
options: ['one', 'two', 'three']
}
}).$mount()
vm.$children[0].maybeDeleteValue()
Vue.nextTick(() => {
expect(vm.$children[0].$get('value')).toEqual(['one'])
})
})
it('sets the value to null on delete keypress when multiple is false', () => {
const vm = new Vue({
template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
components: {vSelect},
data: {
value: 'one',
options: ['one', 'two', 'three']
}
}).$mount()
vm.$children[0].maybeDeleteValue()
Vue.nextTick(() => {
expect(vm.$children[0].$get('value')).toEqual(null)
})
})
})
describe('Labels', () => {
it('can generate labels using the default label key', () => {
const vm = new Vue({
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
components: {vSelect},
data: {
value: [{label: 'Baz'}],
options: [{label: 'Foo'}, {label: 'Baz'}]
}
}).$mount()
expect(vm.$children[0].$els.toggle.querySelector('.selected-tag').textContent).toContain('Baz')
})
it('can generate labels using a custom label key', () => {
const vm = new Vue({
template: '<div><v-select label="name" :options="options" :value.sync="value" :multiple="true"></v-select></div>',
components: {vSelect},
data: {
value: [{name: 'Baz'}],
options: [{name: 'Foo'}, {name: 'Baz'}]
}
}).$mount()
expect(vm.$children[0].$els.toggle.querySelector('.selected-tag').textContent).toContain('Baz')
expect(vm.$children[0].isOptionSelected('one')).toEqual(true)
})
it('can run a callback when the selection changes', (done) => {
@@ -241,6 +212,242 @@ describe('Select.vue', () => {
})
})
describe('Toggling Dropdown', () => {
it('can open the dropdown when the el is clicked', (done) => {
const vm = new Vue({
template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
components: {vSelect},
data: {
value: [{label: 'one'}],
options: [{label: 'one'}]
}
}).$mount()
vm.$children[0].toggleDropdown({target: vm.$children[0].$els.search})
Vue.nextTick(() => {
Vue.nextTick(() => {
expect(vm.$children[0].open).toEqual(true)
done()
})
})
})
// it('can close the dropdown when the el is clicked', (done) => {
// const vm = new Vue({
// template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
// components: {vSelect},
// data: {
// value: [{label: 'one'}],
// options: [{label: 'one'}]
// }
// }).$mount()
// vm.$children[0].open = true
// Vue.nextTick(() => {
// vm.$children[0].toggleDropdown({ target: vm.$children[0].$el })
// Vue.nextTick( () => {
// expect(vm.$children[0].open).toEqual(false)
// done()
// })
// })
// })
it('will close the dropdown on search blur', () => {
const vm = new Vue({
template: '<div><v-select :options="options" multiple :value.sync="value"></v-select></div>',
components: {vSelect},
data: {
value: [{label: 'one'}],
options: [{label: 'one'}]
}
}).$mount()
vm.$children[0].open = true
triggerFocusEvent(vm.$children[0].$els.toggle, 'blur')
expect(vm.$children[0].open).toEqual(true)
})
// it('will close the dropdown on escape, if search is empty', (done) => {
// const vm = new Vue({
// template: '<div><v-select :options="options" multiple :value.sync="value"></v-select></div>',
// components: {vSelect},
// data: {
// value: [{label: 'one'}],
// options: [{label: 'one'}]
// }
// }).$mount()
// vm.$children[0].open = true
// vm.$children[0].onEscape()
// Vue.nextTick(() => {
// Vue.nextTick(() => {
// expect(vm.$children[0].open).toEqual(false)
// done()
// })
// })
// })
it('will remove existing search text on escape keyup', () => {
const vm = new Vue({
template: '<div><v-select :options="options" multiple :value.sync="value"></v-select></div>',
components: {vSelect},
data: {
value: [{label: 'one'}],
options: [{label: 'one'}]
}
}).$mount()
vm.$children[0].search = 'foo'
vm.$children[0].onEscape()
expect(vm.$children[0].search).toEqual('')
})
})
describe('Moving the Typeahead Pointer', () => {
it('will set the pointer to zero when the filteredOptions change', (done) => {
const vm = new Vue({
template: '<div><v-select :options="options"></v-select></div>',
components: {vSelect},
data: {
options: ['one', 'two', 'three']
}
}).$mount()
vm.$children[0].search = 'two'
Vue.nextTick(() => {
expect(vm.$children[0].typeAheadPointer).toEqual(0)
done()
})
})
it('will move the pointer visually up the list on up arrow keyup', () => {
const vm = new Vue({
template: '<div><v-select :options="options"></v-select></div>',
components: {vSelect},
data: {
options: ['one', 'two', 'three']
}
}).$mount()
vm.$children[0].typeAheadPointer = 1
trigger(vm.$children[0].$els.search, 'keyup', (e) => e.keyCode = 38)
expect(vm.$children[0].typeAheadPointer).toEqual(0)
})
it('will move the pointer visually down the list on down arrow keyup', () => {
const vm = new Vue({
template: '<div><v-select :options="options"></v-select></div>',
components: {vSelect},
data: {
options: ['one', 'two', 'three']
}
}).$mount()
vm.$children[0].typeAheadPointer = 1
trigger(vm.$children[0].$els.search, 'keyup', (e) => e.keyCode = 40)
expect(vm.$children[0].typeAheadPointer).toEqual(2)
})
it('will not move the pointer past the end of the list', () => {
const vm = new Vue({
template: '<div><v-select :options="options"></v-select></div>',
components: {vSelect},
data: {
options: ['one', 'two', 'three']
}
}).$mount()
vm.$children[0].typeAheadPointer = 2
vm.$children[0].typeAheadDown()
expect(vm.$children[0].typeAheadPointer).toEqual(2)
})
})
describe('Removing values', () => {
it('removes the given tag when its close icon is clicked', (done) => {
const vm = new Vue({
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
components: {vSelect},
data: {
value: ['one'],
options: ['one', 'two', 'three']
}
}).$mount()
vm.$children[0].$els.toggle.querySelector('.close').click()
Vue.nextTick(() => {
expect(vm.$children[0].value).toEqual([])
done()
})
})
it('removes the last item in the value array on delete keypress when multiple is true', () => {
const vm = new Vue({
template: '<div><v-select :options="options" :value.sync="value" :multiple="true"></v-select></div>',
components: {vSelect},
data: {
value: ['one', 'two'],
options: ['one', 'two', 'three']
}
}).$mount()
vm.$children[0].maybeDeleteValue()
Vue.nextTick(() => {
expect(vm.$children[0].value).toEqual(['one'])
})
})
it('sets the value to null on delete keypress when multiple is false', () => {
const vm = new Vue({
template: '<div><v-select :options="options" :value.sync="value"></v-select></div>',
components: {vSelect},
data: {
value: 'one',
options: ['one', 'two', 'three']
}
}).$mount()
vm.$children[0].maybeDeleteValue()
Vue.nextTick(() => {
expect(vm.$children[0].value).toEqual(null)
})
})
})
describe('Labels', () => {
it('can generate labels using a custom label key', () => {
const vm = new Vue({
template: '<div><v-select label="name" :options="options" :value.sync="value" :multiple="true"></v-select></div>',
components: {vSelect},
data: {
value: [{name: 'Baz'}],
options: [{name: 'Foo'}, {name: 'Baz'}]
}
}).$mount()
expect(vm.$children[0].$els.toggle.querySelector('.selected-tag').textContent).toContain('Baz')
})
it('will display a placeholder if the value is empty', (done) => {
const vm = new Vue({
template: '<div><v-select :options="options" placeholder="foo"></v-select></div>',
components: {vSelect},
data: {
options: [{label: 'one'}]
}
}).$mount()
expect(vm.$children[0].searchPlaceholder).toEqual('foo')
vm.$children[0].value = {label: 'one'}
Vue.nextTick(() => {
expect(vm.$children[0].searchPlaceholder).not.toBeDefined()
done()
})
// expect(vm.$children[0].searchPlaceholder()).toEqual('foo')
})
})
describe('When Tagging Is Enabled', () => {
it('can determine if a given option string already exists', () => {
const vm = new Vue({
@@ -295,7 +502,7 @@ describe('Select.vue', () => {
expect(vm.$children[0].filteredOptions).toEqual(['three'])
})
it('can select the current search text', (done) => {
it('can select the current search text as a string', (done) => {
const vm = new Vue({
template: '<div><v-select :options="options" :value.sync="value" :multiple="true" taggable></v-select></div>',
components: {vSelect},
@@ -307,7 +514,24 @@ describe('Select.vue', () => {
searchSubmit(vm, 'three')
Vue.nextTick(() => {
expect(vm.$children[0].$get('value')).toEqual(['one', 'three'])
expect(vm.$children[0].value).toEqual(['one', 'three'])
done()
})
})
it('can select the current search text as an object', (done) => {
const vm = new Vue({
template: '<div><v-select :options="options" :value.sync="value" :multiple="true" taggable></v-select></div>',
components: {vSelect},
data: {
value: [{label: 'one'}],
options: [{label: 'one'}]
}
}).$mount()
searchSubmit(vm, 'two')
Vue.nextTick(() => {
expect(vm.$children[0].value).toEqual([{label: 'one'}, {label: 'two'}])
done()
})
})
@@ -355,7 +579,7 @@ describe('Select.vue', () => {
searchSubmit(vm)
Vue.nextTick(() => {
expect(vm.$children[0].$get('value')[0]).toBe(two)
expect(vm.$children[0].value[0]).toBe(two)
done()
})
})
@@ -374,7 +598,6 @@ describe('Select.vue', () => {
Vue.nextTick(() => {
searchSubmit(vm)
// This needs to be wrapped in nextTick() twice so that filteredOptions can
// calculate after setting the search text, and move the typeAheadPointer index to 0.
Vue.nextTick(() => {