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

build(vite): replace webpack with Vite, add Typescript (#1594)

BREAKING: mixins are no longer exported from the index (and will likely be converted to hooks)
This commit is contained in:
Jeff Sagal
2022-07-18 09:33:46 -07:00
committed by GitHub
parent 92abcbf1f8
commit 98c278b2bb
51 changed files with 3470 additions and 10062 deletions
+1 -20
View File
@@ -1,6 +1,5 @@
import { shallowMount } from '@vue/test-utils'
import VueSelect from '../src/components/Select.vue'
import Vue from 'vue'
import VueSelect from '@/components/Select.vue'
/**
* Trigger a submit event on the search
@@ -69,21 +68,3 @@ export const mountDefault = (props = {}, options = {}) => {
...options,
})
}
/**
* Returns a v-select component directly.
* @param props
* @param options
* @return {Vue | Element | Vue[] | Element[]}
*/
export const mountWithoutTestUtils = (props = {}, options = {}) => {
return createApp({
render: (createEl) =>
createEl('vue-select', {
ref: 'select',
props: { options: ['one', 'two', 'three'], ...props },
...options,
}),
components: { VueSelect },
}).mount().$refs.select
}
+3 -2
View File
@@ -1,10 +1,11 @@
import { mountDefault } from '../helpers'
import { it, describe, expect } from 'vitest'
import { mountDefault } from '@tests/helpers.js'
describe('Search Slot Scope', () => {
/**
* @see https://www.w3.org/WAI/PF/aria/states_and_properties#aria-activedescendant
*/
fdescribe('aria-activedescendant', () => {
describe('aria-activedescendant', () => {
it('adds the active descendant attribute only when the dropdown is open and there is a typeAheadPointer value', async () => {
const Select = mountDefault()
+3 -2
View File
@@ -1,6 +1,7 @@
import { selectWithProps } from '../helpers'
import { it, describe, expect } from 'vitest'
import { selectWithProps } from '@tests/helpers.js'
import { shallowMount } from '@vue/test-utils'
import vSelect from '../../src/components/Select'
import vSelect from '@/components/Select.vue'
describe('Asynchronous Loading', () => {
it('can toggle the loading class', () => {
+8 -6
View File
@@ -1,15 +1,17 @@
import pointerScroll from '../../src/mixins/pointerScroll'
import { mountDefault } from '../helpers'
import { it, describe, expect, vi, afterEach } from 'vitest'
import pointerScroll from '@/mixins/pointerScroll.js'
import { mountDefault } from '@tests/helpers.js'
describe('Automatic Scrolling', () => {
let spy
afterEach(() => {
if (spy) spy.mockClear()
})
it('should check if the scroll position needs to be adjusted on up arrow keyUp', async () => {
// Given
spy = jest.spyOn(pointerScroll.methods, 'maybeAdjustScroll')
spy = vi.spyOn(pointerScroll.methods, 'maybeAdjustScroll')
const Select = mountDefault()
Select.vm.typeAheadPointer = 1
@@ -22,7 +24,7 @@ describe('Automatic Scrolling', () => {
it('should check if the scroll position needs to be adjusted on down arrow keyUp', async () => {
// Given
spy = jest.spyOn(pointerScroll.methods, 'maybeAdjustScroll')
spy = vi.spyOn(pointerScroll.methods, 'maybeAdjustScroll')
const Select = mountDefault()
Select.vm.typeAheadPointer = 1
@@ -35,7 +37,7 @@ describe('Automatic Scrolling', () => {
it('should check if the scroll position needs to be adjusted when filtered options changes', async () => {
// Given
spy = jest.spyOn(pointerScroll.methods, 'maybeAdjustScroll')
spy = vi.spyOn(pointerScroll.methods, 'maybeAdjustScroll')
const Select = mountDefault()
Select.vm.typeAheadPointer = 1
@@ -49,7 +51,7 @@ describe('Automatic Scrolling', () => {
it('should not adjust scroll position when autoscroll is false', async () => {
// Given
spy = jest.spyOn(pointerScroll.methods, 'maybeAdjustScroll')
spy = vi.spyOn(pointerScroll.methods, 'maybeAdjustScroll')
const Select = mountDefault({
autoscroll: false,
})
+2 -1
View File
@@ -1,5 +1,6 @@
import { it, describe, expect } from 'vitest'
import { defineComponent } from 'vue'
import { selectWithProps } from '../helpers'
import { selectWithProps } from '@tests/helpers.js'
describe('Components API', () => {
it('swap the Deselect component', () => {
+2 -1
View File
@@ -1,4 +1,5 @@
import { selectTag, selectWithProps } from '../helpers'
import { it, describe, expect } from 'vitest'
import { selectTag, selectWithProps } from '@tests/helpers.js'
describe('CreateOption When Tagging Is Enabled', () => {
it('can select the current search text as a string', async () => {
+5 -4
View File
@@ -1,4 +1,5 @@
import { mountDefault, selectWithProps } from '../helpers'
import { it, describe, expect, vi } from 'vitest'
import { mountDefault, selectWithProps } from '@tests/helpers.js'
describe('Removing values', () => {
it('can remove the given tag when its close icon is clicked', async () => {
@@ -65,7 +66,7 @@ describe('Removing values', () => {
options: ['one', 'two', 'three'],
deselectFromDropdown: true,
})
const deselect = spyOn(Select.vm, 'deselect')
const deselect = vi.spyOn(Select.vm, 'deselect')
Select.vm.open = true
await Select.vm.$nextTick()
@@ -83,7 +84,7 @@ describe('Removing values', () => {
clearable: false,
deselectFromDropdown: true,
})
const deselect = spyOn(Select.vm, 'deselect')
const deselect = vi.spyOn(Select.vm, 'deselect')
Select.vm.open = true
await Select.vm.$nextTick()
@@ -100,7 +101,7 @@ describe('Removing values', () => {
options: ['one', 'two', 'three'],
deselectFromDropdown: false,
})
const deselect = spyOn(Select.vm, 'deselect')
const deselect = vi.spyOn(Select.vm, 'deselect')
Select.vm.open = true
await Select.vm.$nextTick()
+9 -21
View File
@@ -1,8 +1,9 @@
import { selectWithProps } from '../helpers'
import OpenIndicator from '../../src/components/OpenIndicator'
import VueSelect from '../../src/components/Select'
import { it, describe, expect, vi, afterEach } from 'vitest'
import { selectWithProps } from '@tests/helpers.js'
import OpenIndicator from '@/components/OpenIndicator.vue'
import VueSelect from '@/components/Select.vue'
const preventDefault = jest.fn()
const preventDefault = vi.fn()
function clickEvent(currentTarget) {
return { currentTarget, preventDefault }
@@ -30,19 +31,6 @@ describe('Toggling Dropdown', () => {
expect(Select.vm.open).toEqual(true)
})
it('should not close the dropdown when the el is clicked and enableMouseInputSearch is set to true', () => {
const Select = selectWithProps({
modelValue: [{ label: 'one' }],
options: [{ label: 'one' }],
enableMouseSearchInput: true,
})
Select.vm.toggleDropdown(clickEvent(Select.vm.$refs.search))
expect(Select.vm.open).toEqual(true)
Select.vm.toggleDropdown(clickEvent(Select.vm.$el))
expect(Select.vm.open).toEqual(false)
})
it('should open the dropdown when the selected tag is clicked', () => {
const Select = selectWithProps({
modelValue: [{ label: 'one' }],
@@ -57,7 +45,7 @@ describe('Toggling Dropdown', () => {
it('can close the dropdown when the el is clicked', () => {
const Select = selectWithProps()
const spy = jest.spyOn(Select.vm.$refs.search, 'blur')
const spy = vi.spyOn(Select.vm.$refs.search, 'blur')
Select.vm.open = true
Select.vm.toggleDropdown(clickEvent(Select.vm.$el))
@@ -104,7 +92,7 @@ describe('Toggling Dropdown', () => {
})
it('will close the dropdown and emit the search:blur event from onSearchBlur', () => {
spy = jest.spyOn(VueSelect.methods, 'onSearchBlur')
spy = vi.spyOn(VueSelect.methods, 'onSearchBlur')
const Select = selectWithProps()
Select.vm.open = true
@@ -115,7 +103,7 @@ describe('Toggling Dropdown', () => {
})
it('will open the dropdown and emit the search:focus event from onSearchFocus', () => {
spy = jest.spyOn(VueSelect.methods, 'onSearchFocus')
spy = vi.spyOn(VueSelect.methods, 'onSearchFocus')
const Select = selectWithProps()
Select.vm.onSearchFocus()
@@ -126,7 +114,7 @@ describe('Toggling Dropdown', () => {
it('will close the dropdown on escape, if search is empty', () => {
const Select = selectWithProps()
const spy = jest.spyOn(Select.vm.$refs.search, 'blur')
const spy = vi.spyOn(Select.vm.$refs.search, 'blur')
Select.vm.open = true
Select.vm.onEscape()
+2 -1
View File
@@ -1,5 +1,6 @@
import { it, describe, expect } from 'vitest'
import { shallowMount } from '@vue/test-utils'
import VueSelect from '../../src/components/Select'
import VueSelect from '@/components/Select.vue'
describe('Filtering Options', () => {
it("should update the search value when the input element receives the 'input' event", () => {
+9 -9
View File
@@ -1,6 +1,6 @@
import { DOMWrapper } from '@vue/test-utils'
import typeAheadPointer from '../../src/mixins/typeAheadPointer'
import { mountDefault } from '../helpers'
import { it, describe, expect, vi, afterEach } from 'vitest'
import typeAheadPointer from '@/mixins/typeAheadPointer.js'
import { mountDefault } from '@tests/helpers.js'
describe('Custom Keydown Handlers', () => {
let spy
@@ -9,7 +9,7 @@ describe('Custom Keydown Handlers', () => {
})
it('can use the map-keydown prop to trigger custom behaviour', async () => {
const onKeyDown = jest.fn()
const onKeyDown = vi.fn()
const Select = mountDefault({
mapKeydown: (defaults, vm) => ({ ...defaults, 32: onKeyDown }),
})
@@ -20,7 +20,7 @@ describe('Custom Keydown Handlers', () => {
})
it('selectOnKeyCodes should trigger a selection for custom keycodes', () => {
spy = jest.spyOn(typeAheadPointer.methods, 'typeAheadSelect')
spy = vi.spyOn(typeAheadPointer.methods, 'typeAheadSelect')
const Select = mountDefault({
selectOnKeyCodes: [32],
@@ -32,9 +32,9 @@ describe('Custom Keydown Handlers', () => {
})
it('even works when combining selectOnKeyCodes with map-keydown', () => {
spy = jest.spyOn(typeAheadPointer.methods, 'typeAheadSelect')
spy = vi.spyOn(typeAheadPointer.methods, 'typeAheadSelect')
const onKeyDown = jest.fn()
const onKeyDown = vi.fn()
const Select = mountDefault({
mapKeydown: (defaults, vm) => ({ ...defaults, 32: onKeyDown }),
selectOnKeyCodes: [9],
@@ -49,7 +49,7 @@ describe('Custom Keydown Handlers', () => {
describe('CompositionEvent support', () => {
it('will not select a value with enter if the user is composing', () => {
spy = jest.spyOn(typeAheadPointer.methods, 'typeAheadSelect')
spy = vi.spyOn(typeAheadPointer.methods, 'typeAheadSelect')
const Select = mountDefault()
@@ -63,7 +63,7 @@ describe('Custom Keydown Handlers', () => {
})
it('will not select a value with tab if the user is composing', () => {
spy = jest.spyOn(typeAheadPointer.methods, 'typeAheadSelect')
spy = vi.spyOn(typeAheadPointer.methods, 'typeAheadSelect')
const Select = mountDefault({ selectOnTab: true })
+22 -21
View File
@@ -1,6 +1,7 @@
import VueSelect from '../../src/components/Select'
import { it, describe, expect, vi } from 'vitest'
import { shallowMount } from '@vue/test-utils'
import { selectWithProps } from '../helpers'
import VueSelect from '@/components/Select.vue'
import { selectWithProps } from '@tests/helpers.js'
describe('Labels', () => {
it('can generate labels using a custom label key', () => {
@@ -13,7 +14,7 @@ describe('Labels', () => {
})
it('will console.warn when options contain objects without a valid label key', async () => {
const spy = jest.spyOn(console, 'warn').mockImplementation(() => {})
const spy = vi.spyOn(console, 'warn').mockImplementation(() => {})
const Select = selectWithProps({
options: [{}],
})
@@ -63,23 +64,23 @@ describe('Labels', () => {
* @see https://github.com/vuejs/vue/issues/10224
* @see https://github.com/vuejs/vue/pull/10229
*/
xit('will not call getOptionLabel if both scoped option slots are used and a filter is provided', () => {
const spy = spyOn(VueSelect.props.getOptionLabel, 'default')
const Select = shallowMount(VueSelect, {
props: {
options: [{ name: 'one' }],
filter: () => {},
},
scopedSlots: {
option: '<span class="option">{{ props.name }}</span>',
'selected-option': '<span class="selected">{{ props.name }}</span>',
},
})
Select.vm.select({ name: 'one' })
expect(spy).toHaveBeenCalledTimes(0)
expect(Select.find('.selected').exists()).toBeTruthy()
})
// it('will not call getOptionLabel if both scoped option slots are used and a filter is provided', () => {
// const spy = spyOn(VueSelect.props.getOptionLabel, 'default')
// const Select = shallowMount(VueSelect, {
// props: {
// options: [{ name: 'one' }],
// filter: () => {},
// },
// scopedSlots: {
// option: '<span class="option">{{ props.name }}</span>',
// 'selected-option': '<span class="selected">{{ props.name }}</span>',
// },
// })
//
// Select.vm.select({ name: 'one' })
//
// expect(spy).toHaveBeenCalledTimes(0)
// expect(Select.find('.selected').exists()).toBeTruthy()
// })
})
})
+2 -1
View File
@@ -1,5 +1,6 @@
import { it, describe, expect } from 'vitest'
import { shallowMount } from '@vue/test-utils'
import VueSelect from '../../src/components/Select'
import VueSelect from '@/components/Select.vue'
describe('Single value options', () => {
it('should reset the search input on focus lost', () => {
+2 -1
View File
@@ -1,4 +1,5 @@
import Select from '../../src/components/Select'
import { it, describe, expect } from 'vitest'
import Select from '@/components/Select.vue'
describe('Comparing Options', () => {
const comparator = Select.methods.optionComparator.bind({
+2 -1
View File
@@ -1,4 +1,5 @@
import Select from '../../src/components/Select.vue'
import { it, describe, expect } from 'vitest'
import Select from '@/components/Select.vue'
describe('Serializing Option Keys', () => {
const getOptionKey = Select.props.getOptionKey.default
+14 -13
View File
@@ -1,6 +1,7 @@
import { mount, shallowMount } from '@vue/test-utils'
import VueSelect from '../../src/components/Select'
import { mountDefault } from '../helpers'
import { it, describe, expect, vi, afterEach } from 'vitest'
import { shallowMount } from '@vue/test-utils'
import VueSelect from '@/components/Select.vue'
import { mountDefault } from '@tests/helpers.js'
describe('Reset on options change', () => {
it('should not reset the selected value by default when the options property changes', async () => {
@@ -21,7 +22,7 @@ describe('Reset on options change', () => {
})
it('will yell at you if resetOnOptionsChange is not a function or boolean', () => {
spy = jest.spyOn(console, 'warn').mockImplementation(() => {})
spy = vi.spyOn(console, 'warn').mockImplementation(() => {})
mountDefault({ resetOnOptionsChange: 1 })
expect(spy.mock.calls[0][0]).toContain(
@@ -45,7 +46,7 @@ describe('Reset on options change', () => {
})
it('should receive the new options, old options, and current value', async () => {
let resetOnOptionsChange = jest.fn((option) => option)
const resetOnOptionsChange = vi.fn((option) => option)
const Select = mountDefault({
resetOnOptionsChange,
options: ['bear'],
@@ -63,8 +64,8 @@ describe('Reset on options change', () => {
})
it('should allow resetOnOptionsChange to be a function that returns true', async () => {
let resetOnOptionsChange = () => true
spy = jest.spyOn(VueSelect.methods, 'clearSelection')
const resetOnOptionsChange = () => true
spy = vi.spyOn(VueSelect.methods, 'clearSelection')
const Select = shallowMount(VueSelect, {
props: { resetOnOptionsChange, options: ['one'], modelValue: 'one' },
})
@@ -75,8 +76,8 @@ describe('Reset on options change', () => {
})
it('should allow resetOnOptionsChange to be a function that returns false', () => {
let resetOnOptionsChange = () => false
spy = jest.spyOn(VueSelect.methods, 'clearSelection')
const resetOnOptionsChange = () => false
spy = vi.spyOn(VueSelect.methods, 'clearSelection')
const Select = shallowMount(VueSelect, {
props: { resetOnOptionsChange, options: ['one'], modelValue: 'one' },
})
@@ -86,9 +87,9 @@ describe('Reset on options change', () => {
})
it('should reset the options if the selectedValue does not exist in the new options', async () => {
let resetOnOptionsChange = (options, old, val) =>
const resetOnOptionsChange = (options, old, val) =>
val.some((val) => options.includes(val))
spy = jest.spyOn(VueSelect.methods, 'clearSelection')
spy = vi.spyOn(VueSelect.methods, 'clearSelection')
const Select = shallowMount(VueSelect, {
props: { resetOnOptionsChange, options: ['one'], modelValue: 'one' },
})
@@ -135,7 +136,7 @@ describe('Reset on options change', () => {
it('clearSearchOnBlur returns false when multiple is true', async () => {
const Select = mountDefault({})
let clearSearchOnBlur = jest.spyOn(Select.vm.$.props, 'clearSearchOnBlur')
const clearSearchOnBlur = vi.spyOn(Select.vm.$.props, 'clearSearchOnBlur')
await Select.get('input').trigger('click')
Select.vm.search = 'one'
await Select.get('input').trigger('blur')
@@ -149,7 +150,7 @@ describe('Reset on options change', () => {
})
it('clearSearchOnBlur accepts a function', async () => {
let clearSearchOnBlur = jest.fn(() => false)
const clearSearchOnBlur = vi.fn(() => false)
const Select = mountDefault({ clearSearchOnBlur })
await Select.get('input').trigger('click')
+4 -3
View File
@@ -1,10 +1,11 @@
import { it, describe, expect } from 'vitest'
import { mount, shallowMount } from '@vue/test-utils'
import VueSelect from '../../src/components/Select'
import { mountDefault } from '../helpers.js'
import VueSelect from '@/components/Select.vue'
import { mountDefault } from '@tests/helpers.js'
describe('When reduce prop is defined', () => {
it('determines when a reducer has been supplied', async () => {
let Select = mountDefault()
const Select = mountDefault()
expect(Select.vm.isReducingValues).toBeFalsy()
await Select.setProps({ reduce: () => {} })
+2 -1
View File
@@ -1,4 +1,5 @@
import { searchSubmit, selectWithProps } from '../helpers'
import { it, describe, expect } from 'vitest'
import { searchSubmit, selectWithProps } from '@tests/helpers.js'
describe('Selectable prop', () => {
it('should select selectable option if clicked', async () => {
+6 -5
View File
@@ -1,7 +1,8 @@
import { it, describe, expect, vi, beforeEach, afterEach } from 'vitest'
import { mount, shallowMount } from '@vue/test-utils'
import VueSelect from '../../src/components/Select.vue'
import typeAheadPointer from '../../src/mixins/typeAheadPointer'
import { mountDefault } from '../helpers'
import VueSelect from '@/components/Select.vue'
import typeAheadPointer from '@/mixins/typeAheadPointer.js'
import { mountDefault } from '@tests/helpers.js'
describe('VS - Selecting Values', () => {
let defaultProps
@@ -57,7 +58,7 @@ describe('VS - Selecting Values', () => {
})
it('can select an option on tab', () => {
spy = jest.spyOn(typeAheadPointer.methods, 'typeAheadSelect')
spy = vi.spyOn(typeAheadPointer.methods, 'typeAheadSelect')
const Select = shallowMount(VueSelect, {
props: {
selectOnTab: true,
@@ -218,7 +219,7 @@ describe('VS - Selecting Values', () => {
expect(Select.vm.selectedValue).toEqual(options)
})
fit('can select a false boolean option', async () => {
it('can select a false boolean option', async () => {
const Select = mountDefault({
options: [false],
})
+7 -6
View File
@@ -1,5 +1,6 @@
import { it, test, describe, expect, vi } from 'vitest'
import { h } from 'vue'
import { mountDefault } from '../helpers'
import { mountDefault } from '@tests/helpers.js'
describe('Scoped Slots', () => {
it('receives an option object to the selected-option-container slot', () => {
@@ -68,7 +69,7 @@ describe('Scoped Slots', () => {
})
it('noOptions slot receives the current search text', async () => {
const noOptions = jest.fn()
const noOptions = vi.fn()
const Select = mountDefault(
{},
{
@@ -88,7 +89,7 @@ describe('Scoped Slots', () => {
})
test('header slot props', async () => {
const header = jest.fn()
const header = vi.fn()
const Select = mountDefault(
{},
{
@@ -106,7 +107,7 @@ describe('Scoped Slots', () => {
})
test('footer slot props', async () => {
const footer = jest.fn()
const footer = vi.fn()
const Select = mountDefault(
{},
{
@@ -124,7 +125,7 @@ describe('Scoped Slots', () => {
})
test('list-header slot props', async () => {
const header = jest.fn()
const header = vi.fn()
const Select = mountDefault(
{},
{
@@ -142,7 +143,7 @@ describe('Scoped Slots', () => {
})
test('list-footer slot props', async () => {
const footer = jest.fn()
const footer = vi.fn()
const Select = mountDefault(
{},
{
+7 -6
View File
@@ -1,10 +1,11 @@
import { it, describe, expect, vi } from 'vitest'
import {
mountDefault,
searchSubmit,
selectTag,
selectWithProps,
} from '../helpers'
import VueSelect from '../../src/components/Select'
} from '@tests/helpers.js'
import VueSelect from '@/components/Select.vue'
describe('When Tagging Is Enabled', () => {
it('can determine if a given option string already exists', () => {
@@ -146,7 +147,7 @@ describe('When Tagging Is Enabled', () => {
})
it('should select an existing option if the search string matches a string from options', async () => {
let two = 'two'
const two = 'two'
const Select = selectWithProps({
taggable: true,
multiple: true,
@@ -159,7 +160,7 @@ describe('When Tagging Is Enabled', () => {
})
it('should select an existing option if the search string matches an objects label from options', async () => {
let two = { label: 'two' }
const two = { label: 'two' }
const Select = selectWithProps({
taggable: true,
options: [{ label: 'one' }, two],
@@ -170,7 +171,7 @@ describe('When Tagging Is Enabled', () => {
})
it('should select an existing option if the search string matches an objects label from options when filter-options is false', async () => {
let two = { label: 'two' }
const two = { label: 'two' }
const Select = selectWithProps({
taggable: true,
filterable: false,
@@ -222,7 +223,7 @@ describe('When Tagging Is Enabled', () => {
})
it('should not allow duplicate tags when using object options', async () => {
const spy = jest.spyOn(VueSelect.methods, 'select')
const spy = vi.spyOn(VueSelect.methods, 'select')
const Select = selectWithProps({
taggable: true,
multiple: true,
+3 -4
View File
@@ -1,8 +1,7 @@
import { it, describe, expect } from 'vitest'
import { shallowMount } from '@vue/test-utils'
import VueSelect from '../../src/components/Select'
import { mountDefault, mountWithoutTestUtils } from '../helpers'
import typeAheadMixin from '../../src/mixins/typeAheadPointer'
import Vue from 'vue'
import VueSelect from '@/components/Select.vue'
import { mountDefault } from '@tests/helpers.js'
describe('Moving the Typeahead Pointer', () => {
it('should set the pointer to zero when the filteredOptions watcher is called', async () => {
+2 -1
View File
@@ -1,4 +1,5 @@
import sortAndStringify from '../../../src/utility/sortAndStringify'
import { test, expect } from 'vitest'
import sortAndStringify from '@/utility/sortAndStringify'
test('it will stringify an object', () => {
expect(sortAndStringify({ hello: 'world' })).toEqual('{"hello":"world"}')
+2 -1
View File
@@ -1,4 +1,5 @@
import uniqueId from '../../../src/utility/uniqueId'
import { test, expect } from 'vitest'
import uniqueId from '@/utility/uniqueId'
test('it generates a unique number', () => {
expect(uniqueId()).not.toEqual(uniqueId())