diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml
index 7823d80753..e608d55cf2 100644
--- a/.github/workflows/unit-test.yml
+++ b/.github/workflows/unit-test.yml
@@ -32,7 +32,7 @@ jobs:
- name: Lint
run: pnpm lint
- name: Test
- run: pnpm test -- --coverage
+ run: pnpm test:coverage
- name: Upload to codecov.io
uses: codecov/codecov-action@v2
with:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d292987627..1cb383100f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -40,8 +40,8 @@ pnpm install
Then you can following command to verify your installation.
```shell
-pnpm test
-pnpm run format
+pnpm t
+pnpm format
```
## Getting Started developing
diff --git a/jest.config.js b/jest.config.js
index e3a2011825..c28e25e446 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -3,6 +3,11 @@
*/
module.exports = {
setupFiles: ['./jest.setup.js'],
+ testMatch: [
+ '**/__tests__/**/*.[jt]s?(x)',
+ '**/?(*.)+(spec|test).[jt]s?(x)',
+ '!**/**vitest**',
+ ],
testPathIgnorePatterns: ['/node_modules/', 'dist'],
modulePathIgnorePatterns: ['/node_modules/', 'dist', 'cypress'],
testEnvironment: 'jsdom',
diff --git a/package.json b/package.json
index fef8e5c720..f6a6d0f442 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,10 @@
},
"scripts": {
"cz": "git-cz",
- "test": "jest",
+ "test": "pnpm test:jest && pnpm test:vitest",
+ "test:jest": "jest",
+ "test:vitest": "vitest",
+ "test:coverage": "vitest --coverage",
"prepare:e2e": "if [ ! -d \"docs/.vitepress/dist\" ]; then pnpm run docs:build; fi;",
"e2e": "cypress open",
"e2e:ci": "cypress run",
@@ -96,10 +99,12 @@
"@typescript-eslint/parser": "5.12.0",
"@vitejs/plugin-vue": "2.2.2",
"@vitejs/plugin-vue-jsx": "1.3.7",
+ "@vitest/ui": "^0.3.2",
"@vue/babel-plugin-jsx": "1.1.1",
"@vue/test-utils": "2.0.0-rc.16",
"@vue/tsconfig": "0.1.3",
"babel-jest": "26.6.3",
+ "c8": "^7.11.0",
"chalk": "4.1.2",
"components-helper": "2.0.0",
"csstype": "2.6.19",
@@ -134,6 +139,7 @@
"type-fest": "2.12.0",
"typescript": "4.5.5",
"unplugin-vue-define-options": "0.3.1",
+ "vitest": "^0.3.2",
"vue": "3.2.30",
"vue-jest": "5.0.0-alpha.10",
"vue-router": "4.0.12",
diff --git a/packages/constants/package.json b/packages/constants/package.json
index ac82cec1d2..81e4ac379c 100644
--- a/packages/constants/package.json
+++ b/packages/constants/package.json
@@ -1,5 +1,6 @@
{
"name": "@element-plus/constants",
"private": true,
- "license": "MIT"
+ "license": "MIT",
+ "main": "index.ts"
}
diff --git a/packages/hooks/__tests__/use-attrs.spec.ts b/packages/hooks/__tests__/use-attrs.vitest.tsx
similarity index 61%
rename from packages/hooks/__tests__/use-attrs.spec.ts
rename to packages/hooks/__tests__/use-attrs.vitest.tsx
index 8fc5122885..9d14d4c0a0 100644
--- a/packages/hooks/__tests__/use-attrs.spec.ts
+++ b/packages/hooks/__tests__/use-attrs.vitest.tsx
@@ -1,6 +1,7 @@
+import { defineComponent } from 'vue'
import { mount } from '@vue/test-utils'
+import { describe, it, expect, fn, afterEach, vi } from 'vitest'
import { useAttrs } from '../use-attrs'
-import type { ComponentOptions } from 'vue'
const CLASS = 'a'
const WIDTH = '50px'
@@ -8,53 +9,50 @@ const TEST_KEY = 'test'
const TEST_VALUE = 'fake'
const ANOTHER_TEST_VALUE = 'fake1'
-const handleClick = jest.fn()
+const handleClick = fn()
const genComp = (
inheritAttrs = true,
excludeListeners = false,
excludeKeys: string[] = []
) => {
- return {
- template: `
-
-
-
- `,
+ return defineComponent({
inheritAttrs,
props: {},
setup() {
const attrs = useAttrs({ excludeListeners, excludeKeys })
-
- return {
- attrs,
- }
- },
- }
-}
-
-const _mount = (Comp: ComponentOptions) => {
- return mount({
- components: { Comp },
- template: `
- `,
- methods: {
- handleClick,
+ return () => (
+
+
+
+ )
},
})
}
-afterEach(() => {
- handleClick.mockClear()
-})
+const _mount = (Comp: ReturnType) => {
+ return mount({
+ setup() {
+ return () => (
+
+ )
+ },
+ })
+}
describe('useAttrs', () => {
- test('class and style should not bind to child node', async () => {
+ afterEach(() => {
+ vi.restoreAllMocks()
+ })
+
+ it('class and style should not bind to child node', async () => {
const wrapper = _mount(genComp())
const container = wrapper.element as HTMLDivElement
const span = wrapper.find('span')
@@ -70,7 +68,7 @@ describe('useAttrs', () => {
expect(handleClick).toBeCalledTimes(2)
})
- test("child node's attributes should update when prop change", async () => {
+ it("child node's attributes should update when prop change", async () => {
const wrapper = _mount(genComp())
const span = wrapper.find('span')
@@ -78,7 +76,7 @@ describe('useAttrs', () => {
expect(span.attributes(TEST_KEY)).toBe(ANOTHER_TEST_VALUE)
})
- test('excluded listeners should not bind to child node', async () => {
+ it('excluded listeners should not bind to child node', async () => {
const wrapper = _mount(genComp(true, true))
const span = wrapper.find('span')
@@ -87,7 +85,7 @@ describe('useAttrs', () => {
expect(handleClick).toBeCalledTimes(1)
})
- test('excluded attributes should not bind to child node', async () => {
+ it('excluded attributes should not bind to child node', async () => {
const wrapper = _mount(genComp(true, false, [TEST_KEY]))
const span = wrapper.find('span')
diff --git a/packages/hooks/__tests__/use-deprecated.spec.ts b/packages/hooks/__tests__/use-deprecated.vitest.ts
similarity index 75%
rename from packages/hooks/__tests__/use-deprecated.spec.ts
rename to packages/hooks/__tests__/use-deprecated.vitest.ts
index fbb2874bc9..e6e445f00c 100644
--- a/packages/hooks/__tests__/use-deprecated.spec.ts
+++ b/packages/hooks/__tests__/use-deprecated.vitest.ts
@@ -1,11 +1,15 @@
import { computed, defineComponent, nextTick } from 'vue'
import { mount } from '@vue/test-utils'
+import { describe, it, fn, vi, expect, afterEach } from 'vitest'
import { debugWarn } from '@element-plus/utils'
import { useDeprecated } from '../use-deprecated'
-jest.mock('@element-plus/utils/error', () => {
+const AXIOM = 'Rem is the best girl'
+
+vi.mock('@element-plus/utils/error', async () => {
return {
- debugWarn: jest.fn(),
+ ...(await vi.importActual('@element-plus/utils/error')),
+ debugWarn: fn(),
}
})
@@ -24,14 +28,15 @@ const DummyComponent = defineComponent({
},
computed(() => props.shouldWarn)
)
+ return () => AXIOM
},
- template: `Rem is the best girl
`,
})
describe('useDeprecated', () => {
- beforeEach(() => {
- ;(debugWarn as jest.Mock).mockClear()
+ afterEach(() => {
+ vi.restoreAllMocks()
})
+
it('should warn when condition is true', async () => {
mount(DummyComponent, {
props: {
diff --git a/packages/hooks/__tests__/use-focus.spec.ts b/packages/hooks/__tests__/use-focus.vitest.ts
similarity index 89%
rename from packages/hooks/__tests__/use-focus.spec.ts
rename to packages/hooks/__tests__/use-focus.vitest.ts
index 9a724cea62..bca1e3289e 100644
--- a/packages/hooks/__tests__/use-focus.spec.ts
+++ b/packages/hooks/__tests__/use-focus.vitest.ts
@@ -1,4 +1,5 @@
import { ref } from 'vue'
+import { describe, it, expect } from 'vitest'
import { useFocus } from '../use-focus'
describe('useFocus', () => {
diff --git a/packages/hooks/__tests__/use-form-item.spec.ts b/packages/hooks/__tests__/use-form-item.vitest.tsx
similarity index 80%
rename from packages/hooks/__tests__/use-form-item.spec.ts
rename to packages/hooks/__tests__/use-form-item.vitest.tsx
index fd2997df3e..33bb883fb4 100644
--- a/packages/hooks/__tests__/use-form-item.spec.ts
+++ b/packages/hooks/__tests__/use-form-item.vitest.tsx
@@ -1,6 +1,7 @@
-import { h, provide } from 'vue'
+import { defineComponent, provide } from 'vue'
import { NOOP } from '@vue/shared'
import { mount } from '@vue/test-utils'
+import { describe, it, expect } from 'vitest'
import { ElButton } from '@element-plus/components'
import {
elFormKey,
@@ -16,23 +17,16 @@ import type {
const AXIOM = 'Rem is the best girl'
-const Component = {
- render() {
- return h(ElButton, this.$attrs, {
- default: () => [AXIOM],
- })
- },
-}
-
-const mountComponent = (setup = NOOP, options = {}) => {
- return mount(
- {
- ...Component,
+const mountComponent = (setup = NOOP, options = {}) =>
+ mount(
+ defineComponent({
setup,
- },
+ render() {
+ return {AXIOM}
+ },
+ }),
options
)
-}
describe('use-form-item', () => {
it('should return local value', () => {
@@ -44,14 +38,10 @@ describe('use-form-item', () => {
const propSize = 'small'
const wrapper = mountComponent(
() => {
- provide(elFormItemKey, {
- size: 'large',
- } as ElFormItemContext)
+ provide(elFormItemKey, { size: 'large' } as ElFormItemContext)
},
{
- props: {
- size: propSize,
- },
+ props: { size: propSize },
}
)
diff --git a/packages/hooks/__tests__/use-locale.spec.ts b/packages/hooks/__tests__/use-locale.vitest.tsx
similarity index 65%
rename from packages/hooks/__tests__/use-locale.spec.ts
rename to packages/hooks/__tests__/use-locale.vitest.tsx
index 26eace5831..532d2146e9 100644
--- a/packages/hooks/__tests__/use-locale.spec.ts
+++ b/packages/hooks/__tests__/use-locale.vitest.tsx
@@ -1,46 +1,43 @@
-import { h, nextTick, computed } from 'vue'
+import { nextTick, computed, defineComponent } from 'vue'
import { mount } from '@vue/test-utils'
+import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import Chinese from '@element-plus/locale/lang/zh-cn'
import English from '@element-plus/locale/lang/en'
import { useLocale, buildTranslator } from '../use-locale'
import { provideGlobalConfig } from '..'
+import type { Language } from '@element-plus/locale'
+import type { PropType, ComponentPublicInstance } from 'vue'
+import type { VueWrapper } from '@vue/test-utils'
-const TestComp = {
+const TestComp = defineComponent({
setup() {
const { t } = useLocale()
- return () => {
- return h(
- 'div',
- { class: 'locale-manifest' },
- t('el.popconfirm.confirmButtonText')
- )
- }
+ return () => (
+ {t('el.popconfirm.confirmButtonText')}
+ )
},
-}
+})
describe('use-locale', () => {
- let wrapper
+ let wrapper: VueWrapper
+
beforeEach(() => {
wrapper = mount(
{
props: {
- locale: Object,
+ locale: Object as PropType,
},
components: {
'el-test': TestComp,
},
setup(props, { slots }) {
provideGlobalConfig(computed(() => ({ locale: props.locale })))
- return () => slots.default()
+ return () => slots.default?.()
},
},
{
- props: {
- locale: Chinese,
- },
- slots: {
- default: () => h(TestComp),
- },
+ props: { locale: Chinese },
+ slots: { default: () => },
}
)
})
@@ -70,7 +67,7 @@ describe('use-locale', () => {
)
})
- test('return key name if not defined', () => {
+ it('return key name if not defined', () => {
const t = buildTranslator(English)
expect(t('el.popconfirm.someThing')).toBe('el.popconfirm.someThing')
})
diff --git a/packages/hooks/__tests__/use-lockscreen.spec.ts b/packages/hooks/__tests__/use-lockscreen.vitest.tsx
similarity index 60%
rename from packages/hooks/__tests__/use-lockscreen.spec.ts
rename to packages/hooks/__tests__/use-lockscreen.vitest.tsx
index 1d6b464bc7..b22dfd528c 100644
--- a/packages/hooks/__tests__/use-lockscreen.spec.ts
+++ b/packages/hooks/__tests__/use-lockscreen.vitest.tsx
@@ -1,5 +1,6 @@
import { ref, nextTick, defineComponent, onMounted } from 'vue'
import { mount } from '@vue/test-utils'
+import { describe, it, expect } from 'vitest'
import { hasClass } from '@element-plus/utils'
import { useLockscreen } from '../use-lockscreen'
@@ -13,19 +14,15 @@ const Comp = defineComponent({
onMounted(() => {
flag.value = true
})
+
+ return () => undefined
},
- template: ``,
})
describe('useLockscreen', () => {
- test('should lock screen when trigger is true', async () => {
+ it('should lock screen when trigger is true', async () => {
const wrapper = mount({
- template: `
-
- `,
- components: {
- 'test-comp': Comp,
- },
+ setup: () => () => ,
})
await nextTick()
expect(hasClass(document.body, kls)).toBe(true)
@@ -35,26 +32,17 @@ describe('useLockscreen', () => {
expect(hasClass(document.body, kls)).toBe(false)
})
- test('should cleanup when unmounted', async () => {
- const wrapper = mount({
- template: `
-
- `,
- data() {
- return {
- shouldRender: true,
- }
- },
- components: {
- 'test-comp': Comp,
- },
+ it('should cleanup when unmounted', async () => {
+ const shouldRender = ref(true)
+ mount({
+ setup: () => () => shouldRender.value ? : undefined,
})
await nextTick()
expect(hasClass(document.body, kls)).toBe(true)
- wrapper.vm.shouldRender = false
+ shouldRender.value = false
await nextTick()
expect(hasClass(document.body, kls)).toBe(false)
diff --git a/packages/hooks/__tests__/use-modal.spec.ts b/packages/hooks/__tests__/use-modal.vitest.ts
similarity index 83%
rename from packages/hooks/__tests__/use-modal.spec.ts
rename to packages/hooks/__tests__/use-modal.vitest.ts
index 798d67c2d4..0da7573aea 100644
--- a/packages/hooks/__tests__/use-modal.spec.ts
+++ b/packages/hooks/__tests__/use-modal.vitest.ts
@@ -1,12 +1,12 @@
import { ref, nextTick } from 'vue'
+import { describe, it, expect, fn } from 'vitest'
import { EVENT_CODE } from '@element-plus/constants'
-
import { useModal } from '../use-modal'
describe('useModal', () => {
- test('should work when ref value changed', async () => {
+ it('should work when ref value changed', async () => {
const visible = ref(false)
- const handleClose = jest.fn()
+ const handleClose = fn()
useModal(
{
diff --git a/packages/hooks/__tests__/use-model-toggle.spec.ts b/packages/hooks/__tests__/use-model-toggle.vitest.tsx
similarity index 75%
rename from packages/hooks/__tests__/use-model-toggle.spec.ts
rename to packages/hooks/__tests__/use-model-toggle.vitest.tsx
index dc328a1127..10394eb887 100644
--- a/packages/hooks/__tests__/use-model-toggle.spec.ts
+++ b/packages/hooks/__tests__/use-model-toggle.vitest.tsx
@@ -1,21 +1,24 @@
-import { nextTick, ref, h, reactive } from 'vue'
+import { nextTick, ref, reactive, defineComponent } from 'vue'
import { mount } from '@vue/test-utils'
+import { describe, it, expect, fn, beforeEach, afterEach } from 'vitest'
import { useModelToggle, useModelToggleProps } from '../use-model-toggle'
-
-import type { ExtractPropTypes } from 'vue'
+import type { VueWrapper } from '@vue/test-utils'
const AXIOM = 'Rem is the best girl'
-const onShow = jest.fn()
-const onHide = jest.fn()
+const onShow = fn()
+const onHide = fn()
let flag = true
const shouldProceed = () => flag
-const Comp = {
- name: 'comp',
- props: { ...useModelToggleProps, disabled: Boolean },
- setup(props: ExtractPropTypes) {
+const Comp = defineComponent({
+ props: {
+ ...useModelToggleProps,
+ disabled: Boolean,
+ },
+
+ setup(props) {
const indicator = ref(false)
const { show, hide, toggle } = useModelToggle({
indicator,
@@ -26,36 +29,26 @@ const Comp = {
})
return () => {
- return [
- h(
- 'button',
- {
- class: 'show',
- onClick: show,
- },
- 'show'
- ),
- h(
- 'button',
- {
- class: 'hide',
- onClick: hide,
- },
- 'hide'
- ),
- h('button', {
- class: 'toggle',
- onClick: toggle,
- }),
-
- indicator.value || props.modelValue ? h('div', AXIOM) : null,
- ]
+ return (
+ <>
+
+
+
+ {indicator.value || props.modelValue ? {AXIOM}
: undefined}
+ >
+ )
}
},
-}
+})
describe('use-model-toggle', () => {
- let wrapper: ReturnType
+ let wrapper: VueWrapper
beforeEach(() => {
flag = true
wrapper = mount(Comp)
@@ -129,33 +122,28 @@ describe('use-model-toggle', () => {
it('should bind with modelValue', async () => {
wrapper.unmount()
+
+ const model = ref(false)
+ const disabled = ref(false)
wrapper = mount({
- components: {
- Comp,
- },
- template: ``,
- data() {
- return {
- model: false,
- disabled: false,
- }
- },
+ setup: () => () =>
+ ,
})
expect(wrapper.findComponent(Comp).text()).not.toContain(AXIOM)
await wrapper.find('.show').trigger('click')
- expect(wrapper.vm.model).toBe(true)
+ expect(model.value).toBe(true)
expect(wrapper.findComponent(Comp).text()).toContain(AXIOM)
await wrapper.find('.hide').trigger('click')
expect(onHide).toHaveBeenCalledTimes(1)
- expect(wrapper.vm.model).toBe(false)
+ expect(model.value).toBe(false)
expect(wrapper.findComponent(Comp).text()).not.toContain(AXIOM)
- ;(wrapper.vm.model as any) = true
- ;(wrapper.vm.disabled as any) = true
+ model.value = true
+ disabled.value = true
await nextTick()
// when disabled emits false that modifies the model
- expect(wrapper.vm.model).toBe(false)
+ expect(model.value).toBe(false)
// should not hide when disabled
await wrapper.find('.hide').trigger('click')
diff --git a/packages/hooks/__tests__/use-namespace.spec.ts b/packages/hooks/__tests__/use-namespace.spec.ts
deleted file mode 100644
index 63c72abf3f..0000000000
--- a/packages/hooks/__tests__/use-namespace.spec.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-import { h, nextTick } from 'vue'
-import { mount } from '@vue/test-utils'
-import { useNamespace, provideGlobalConfig } from '..'
-
-const TestComp = {
- setup() {
- const ns = useNamespace('table')
- return () => {
- return h(
- 'div',
- {
- id: 'testId',
- class: [
- ns.b(), // return ns + block
- ns.b('body'),
- ns.e('content'),
- ns.m('active'),
- ns.be('content', 'active'),
- ns.em('content', 'active'),
- ns.bem('body', 'content', 'active'),
- ns.is('focus'),
- ns.e(), // return empty string
- ns.m(), // return empty string
- ns.be(), // return empty string
- ns.em(), // return empty string
- ns.bem(), // return empty string
- ns.is('hover', undefined), // return empty string
- ns.is('clicked', false), // return empty string
- ],
- },
- 'text'
- )
- }
- },
-}
-
-describe('use-locale', () => {
- let wrapper
- beforeEach(() => {
- wrapper = mount(
- {
- components: {
- 'el-test': TestComp,
- },
- setup(props, { slots }) {
- provideGlobalConfig({ namespace: 'ep' })
- return () => slots.default()
- },
- },
- {
- slots: {
- default: () => h(TestComp),
- },
- }
- )
- })
-
- afterEach(() => {
- wrapper.unmount()
- })
-
- it('should provide bem correctly', async () => {
- await nextTick()
- expect(wrapper.find('#testId').classes().join('~')).toBe(
- [
- 'ep-table', // b()
- 'ep-table-body', // b('body')
- 'ep-table__content', // e('content')
- 'ep-table--active', // m('active')
- 'ep-table-content__active', // be('content', 'active')
- 'ep-table__content--active', // em('content', 'active')
- 'ep-table-body__content--active', // bem('body', 'content', 'active')
- 'is-focus', // is('focus')
- ].join('~')
- )
- })
-})
diff --git a/packages/hooks/__tests__/use-namespace.vitest.tsx b/packages/hooks/__tests__/use-namespace.vitest.tsx
new file mode 100644
index 0000000000..df7f0697ff
--- /dev/null
+++ b/packages/hooks/__tests__/use-namespace.vitest.tsx
@@ -0,0 +1,68 @@
+import { defineComponent, nextTick } from 'vue'
+import { mount } from '@vue/test-utils'
+import { describe, it, expect, beforeEach, afterEach } from 'vitest'
+import { useNamespace, provideGlobalConfig } from '..'
+import type { VueWrapper } from '@vue/test-utils'
+
+const TestComp = defineComponent({
+ setup() {
+ const ns = useNamespace('table')
+ return () => (
+
+ text
+
+ )
+ },
+})
+
+describe('use-locale', () => {
+ const Comp = defineComponent({
+ setup(_props, { slots }) {
+ provideGlobalConfig({ namespace: 'ep' })
+ return () => slots.default?.()
+ },
+ })
+ let wrapper: VueWrapper>
+ beforeEach(() => {
+ wrapper = mount(Comp, {
+ slots: { default: () => },
+ })
+ })
+
+ afterEach(() => {
+ wrapper.unmount()
+ })
+
+ it('should provide bem correctly', async () => {
+ await nextTick()
+ expect(wrapper.find('#testId').classes()).toEqual([
+ 'ep-table', // b()
+ 'ep-table-body', // b('body')
+ 'ep-table__content', // e('content')
+ 'ep-table--active', // m('active')
+ 'ep-table-content__active', // be('content', 'active')
+ 'ep-table__content--active', // em('content', 'active')
+ 'ep-table-body__content--active', // bem('body', 'content', 'active')
+ 'is-focus', // is('focus')
+ ])
+ })
+})
diff --git a/packages/hooks/__tests__/use-prevent-global.ts b/packages/hooks/__tests__/use-prevent-global.vitest.ts
similarity index 64%
rename from packages/hooks/__tests__/use-prevent-global.ts
rename to packages/hooks/__tests__/use-prevent-global.vitest.ts
index 83d338a56c..fb907a44b2 100644
--- a/packages/hooks/__tests__/use-prevent-global.ts
+++ b/packages/hooks/__tests__/use-prevent-global.vitest.ts
@@ -1,44 +1,51 @@
import { ref } from 'vue'
-import { on, off } from '@element-plus/utils'
+import {
+ describe,
+ it,
+ expect,
+ beforeAll,
+ beforeEach,
+ afterAll,
+ fn,
+} from 'vitest'
import triggerEvent from '@element-plus/test-utils/trigger-event'
import { usePreventGlobal } from '../use-prevent-global'
describe('usePreventGlobal', () => {
const evtName = 'keydown'
- const evt = jest.fn()
+ const evtHandler = fn()
beforeAll(() => {
- on(document.body, evtName, evt)
+ document.body.addEventListener(evtName, evtHandler)
})
beforeEach(() => {
- evt.mockClear()
+ evtHandler.mockClear()
})
afterAll(() => {
- off(document.body, evtName, evt)
+ document.body.removeEventListener(evtName, evtHandler)
})
it('should prevent global event from happening', () => {
const visible = ref(true)
- const evt2Trigger = jest.fn().mockReturnValue(true)
+ const evt2Trigger = fn().mockReturnValue(true)
usePreventGlobal(visible, evtName, evt2Trigger)
triggerEvent(document.body, evtName)
- expect(evt).not.toBeCalled()
+ expect(evtHandler).not.toBeCalled()
expect(evt2Trigger).toHaveBeenCalled()
visible.value = false
- // clean up
})
it('should not prevent global event from happening', () => {
const visible = ref(true)
- const evt2Trigger = jest.fn().mockReturnValue(false)
+ const evt2Trigger = fn().mockReturnValue(false)
usePreventGlobal(visible, evtName, evt2Trigger)
triggerEvent(document.body, evtName)
- expect(evt).toHaveBeenCalled()
+ expect(evtHandler).toHaveBeenCalled()
expect(evt2Trigger).toHaveBeenCalled()
visible.value = false
diff --git a/packages/hooks/__tests__/use-restore-active.spec.ts b/packages/hooks/__tests__/use-restore-active.vitest.ts
similarity index 93%
rename from packages/hooks/__tests__/use-restore-active.spec.ts
rename to packages/hooks/__tests__/use-restore-active.vitest.ts
index f55263590f..1c7c57222d 100644
--- a/packages/hooks/__tests__/use-restore-active.spec.ts
+++ b/packages/hooks/__tests__/use-restore-active.vitest.ts
@@ -1,4 +1,5 @@
import { ref, nextTick } from 'vue'
+import { describe, it, expect } from 'vitest'
import { useRestoreActive } from '../use-restore-active'
describe('useRestoreActive', () => {
diff --git a/packages/hooks/__tests__/use-teleport.spec.ts b/packages/hooks/__tests__/use-teleport.vitest.tsx
similarity index 63%
rename from packages/hooks/__tests__/use-teleport.spec.ts
rename to packages/hooks/__tests__/use-teleport.vitest.tsx
index 44b8def875..5f37e62b03 100644
--- a/packages/hooks/__tests__/use-teleport.spec.ts
+++ b/packages/hooks/__tests__/use-teleport.vitest.tsx
@@ -1,11 +1,12 @@
-import { ref, nextTick, h } from 'vue'
+import { ref, nextTick, h, defineComponent } from 'vue'
import { mount } from '@vue/test-utils'
-
+import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { useTeleport } from '../use-teleport'
+import type { VueWrapper } from '@vue/test-utils'
const AXIOM = 'Rem is the best girl'
-const Comp = {
+const Comp = defineComponent({
setup() {
const appendToBody = ref(true)
const { showTeleport, hideTeleport, renderTeleport } = useTeleport(
@@ -13,39 +14,28 @@ const Comp = {
appendToBody
)
- return () => {
- return [
- h(
- 'button',
- {
- class: 'show',
- onClick: showTeleport,
- },
- 'show'
- ),
- h(
- 'button',
- {
- class: 'hide',
- onClick: hideTeleport,
- },
- 'hide'
- ),
- h('button', {
- class: 'toggle',
- onClick: () => {
- // toggle append to body.
- appendToBody.value = !appendToBody.value
- },
- }),
- renderTeleport(),
- ]
- }
+ return () => (
+ <>
+
+
+
+ {renderTeleport()}
+ >
+ )
},
-}
+})
describe('useModal', () => {
- let wrapper: ReturnType
+ let wrapper: VueWrapper>
beforeEach(() => {
wrapper = mount(Comp)
diff --git a/packages/hooks/__tests__/use-timeout.spec.ts b/packages/hooks/__tests__/use-timeout.vitest.ts
similarity index 69%
rename from packages/hooks/__tests__/use-timeout.spec.ts
rename to packages/hooks/__tests__/use-timeout.vitest.ts
index 34ccc68a24..633c08a467 100644
--- a/packages/hooks/__tests__/use-timeout.spec.ts
+++ b/packages/hooks/__tests__/use-timeout.vitest.ts
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils'
+import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
import { useTimeout } from '../use-timeout'
const _mount = (cb: () => void) => {
@@ -7,29 +8,27 @@ const _mount = (cb: () => void) => {
const { cancelTimeout, registerTimeout } = useTimeout()
registerTimeout(cb, 0)
- return {
- cancelTimeout,
- }
- },
- render() {
- return null
+ return { cancelTimeout }
},
+ render: () => undefined,
})
}
-jest.useFakeTimers()
-
describe('use-timeout', () => {
- let wrapper
- const cb = jest.fn()
beforeEach(() => {
- cb.mockClear()
+ vi.useFakeTimers()
wrapper = _mount(cb)
})
+ afterEach(() => {
+ vi.restoreAllMocks()
+ })
+
+ let wrapper: ReturnType
+ const cb = vi.fn()
it('should register timeout correctly', async () => {
expect(cb).not.toHaveBeenCalled()
- jest.runOnlyPendingTimers()
+ vi.runOnlyPendingTimers()
expect(cb).toHaveBeenCalled()
wrapper.unmount()
})
@@ -37,7 +36,7 @@ describe('use-timeout', () => {
it('should cancel the timeout correctly', async () => {
wrapper.vm.cancelTimeout()
- jest.runOnlyPendingTimers()
+ vi.runOnlyPendingTimers()
expect(cb).not.toHaveBeenCalled()
wrapper.unmount()
@@ -47,7 +46,7 @@ describe('use-timeout', () => {
expect(cb).not.toHaveBeenCalled()
wrapper.unmount()
- jest.runOnlyPendingTimers()
+ vi.runOnlyPendingTimers()
expect(cb).not.toHaveBeenCalled()
})
diff --git a/packages/hooks/use-model-toggle/index.ts b/packages/hooks/use-model-toggle/index.ts
index 8791f244e5..37efa28110 100644
--- a/packages/hooks/use-model-toggle/index.ts
+++ b/packages/hooks/use-model-toggle/index.ts
@@ -1,21 +1,30 @@
import { computed, getCurrentInstance, watch, onMounted } from 'vue'
import { isFunction } from '@vue/shared'
import { isClient } from '@vueuse/core'
-import { isBoolean, buildProp, definePropType } from '@element-plus/utils'
+import { isBoolean, definePropType, buildProp } from '@element-plus/utils'
import type { RouteLocationNormalizedLoaded } from 'vue-router'
import type { Ref, ComponentPublicInstance, ExtractPropTypes } from 'vue'
-export const createModelToggleComposable = (name: string) => {
+const _prop = buildProp({
+ type: definePropType(Boolean),
+ default: null,
+} as const)
+const _event = buildProp({
+ type: definePropType<(val: boolean) => void>(Function),
+} as const)
+
+type _UseModelToggleProps = {
+ [K in T]: typeof _prop
+} & {
+ [K in `onUpdate:${T}`]: typeof _event
+}
+
+export const createModelToggleComposable = (name: T) => {
const useModelToggleProps = {
- [name]: buildProp({
- type: definePropType(Boolean),
- default: null,
- } as const),
- [`onUpdate:${name}`]: buildProp({
- type: definePropType<(val: boolean) => void>(Function),
- } as const),
- }
+ [name]: _prop,
+ [`onUpdate:${name}`]: _event,
+ } as _UseModelToggleProps
const useModelToggleEmits = [`update:${name}`]
@@ -27,7 +36,9 @@ export const createModelToggleComposable = (name: string) => {
onHide,
}: ModelToggleParams) => {
const instance = getCurrentInstance()!
- const props = instance.props as UseModelToggleProps & { disabled: boolean }
+ const props = instance.props as _UseModelToggleProps & {
+ disabled: boolean
+ }
const { emit } = instance
const updateEventKey = `update:${name}`
diff --git a/packages/utils/tests/dom/aria.test.ts b/packages/utils/__tests__/dom/aria.vitest.ts
similarity index 96%
rename from packages/utils/tests/dom/aria.test.ts
rename to packages/utils/__tests__/dom/aria.vitest.ts
index d1c99f87c3..3dec9110a7 100644
--- a/packages/utils/tests/dom/aria.test.ts
+++ b/packages/utils/__tests__/dom/aria.vitest.ts
@@ -1,3 +1,4 @@
+import { describe, it, expect, spyOn } from 'vitest'
import { triggerEvent, isFocusable } from '../..'
const CE = (tag: string) => document.createElement(tag)
@@ -6,7 +7,7 @@ describe('Aria Utils', () => {
describe('Trigger Event', () => {
it('Util trigger event to trigger event correctly', () => {
const div = document.createElement('div')
- jest.spyOn(div, 'dispatchEvent')
+ spyOn(div, 'dispatchEvent')
const eventName = 'click'
triggerEvent(div, eventName)
expect(div.dispatchEvent).toHaveBeenCalled()
diff --git a/packages/utils/tests/dom/dom.spec.ts b/packages/utils/__tests__/dom/style.vitest.ts
similarity index 98%
rename from packages/utils/tests/dom/dom.spec.ts
rename to packages/utils/__tests__/dom/style.vitest.ts
index 8513438be7..25351909bb 100644
--- a/packages/utils/tests/dom/dom.spec.ts
+++ b/packages/utils/__tests__/dom/style.vitest.ts
@@ -1,13 +1,12 @@
+import { describe, it, expect } from 'vitest'
import { hasClass, addClass, removeClass } from '../..'
const getClass = (el: Element) => {
- if (!el) {
- return ''
- }
+ if (!el) return ''
return el.getAttribute('class')
}
-describe('Dom Utils', () => {
+describe('dom style', () => {
describe('hasClass', () => {
it('Judge whether a Element has a class', () => {
const div = document.createElement('div')
diff --git a/packages/utils/tests/vue/global-nodes.spec.ts b/packages/utils/__tests__/vue/global-node.vitest.ts
similarity index 94%
rename from packages/utils/tests/vue/global-nodes.spec.ts
rename to packages/utils/__tests__/vue/global-node.vitest.ts
index 6aafc24bac..e16816056a 100644
--- a/packages/utils/tests/vue/global-nodes.spec.ts
+++ b/packages/utils/__tests__/vue/global-node.vitest.ts
@@ -1,3 +1,4 @@
+import { describe, it, expect, afterEach } from 'vitest'
import {
createGlobalNode,
removeGlobalNode,
diff --git a/packages/utils/tests/vue/prop.spec.ts b/packages/utils/__tests__/vue/props.vitest.ts
similarity index 99%
rename from packages/utils/tests/vue/prop.spec.ts
rename to packages/utils/__tests__/vue/props.vitest.ts
index 4dee9a74b1..1161256908 100644
--- a/packages/utils/tests/vue/prop.spec.ts
+++ b/packages/utils/__tests__/vue/props.vitest.ts
@@ -2,6 +2,7 @@
import { defineComponent } from 'vue'
import { mount } from '@vue/test-utils'
+import { describe, it, expect, vi } from 'vitest'
import { expectTypeOf } from 'expect-type'
import { buildProp, definePropType, mutable, keysOf, buildProps } from '../..'
import type { propKey } from '../..'
@@ -449,7 +450,7 @@ describe('buildProps', () => {
describe('runtime', () => {
it('default value', () => {
- const warnHandler = jest.fn()
+ const warnHandler = vi.fn()
const Foo = defineComponent({
props: buildProps({
diff --git a/packages/utils/package.json b/packages/utils/package.json
index 0f3801b0b3..0ed948ce6a 100644
--- a/packages/utils/package.json
+++ b/packages/utils/package.json
@@ -2,6 +2,7 @@
"name": "@element-plus/utils",
"private": true,
"license": "MIT",
+ "main": "index.ts",
"peerDependencies": {
"vue": "^3.2.0"
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 50fdd6d945..d5a8184e29 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -38,12 +38,14 @@ importers:
'@typescript-eslint/parser': 5.12.0
'@vitejs/plugin-vue': 2.2.2
'@vitejs/plugin-vue-jsx': 1.3.7
+ '@vitest/ui': ^0.3.2
'@vue/babel-plugin-jsx': 1.1.1
'@vue/test-utils': 2.0.0-rc.16
'@vue/tsconfig': 0.1.3
'@vueuse/core': ^7.6.0
async-validator: ^4.0.7
babel-jest: 26.6.3
+ c8: ^7.11.0
chalk: 4.1.2
components-helper: 2.0.0
csstype: 2.6.19
@@ -84,6 +86,7 @@ importers:
type-fest: 2.12.0
typescript: 4.5.5
unplugin-vue-define-options: 0.3.1
+ vitest: ^0.3.2
vue: 3.2.30
vue-jest: 5.0.0-alpha.10
vue-router: 4.0.12
@@ -132,10 +135,12 @@ importers:
'@typescript-eslint/parser': 5.12.0_eslint@8.9.0+typescript@4.5.5
'@vitejs/plugin-vue': 2.2.2_vue@3.2.30
'@vitejs/plugin-vue-jsx': 1.3.7
+ '@vitest/ui': 0.3.2
'@vue/babel-plugin-jsx': 1.1.1_@babel+core@7.17.5
'@vue/test-utils': 2.0.0-rc.16_vue@3.2.30
'@vue/tsconfig': 0.1.3_@types+node@17.0.16
babel-jest: 26.6.3_@babel+core@7.17.5
+ c8: 7.11.0
chalk: 4.1.2
components-helper: 2.0.0
csstype: 2.6.19
@@ -170,6 +175,7 @@ importers:
type-fest: 2.12.0
typescript: 4.5.5
unplugin-vue-define-options: 0.3.1_a2d0c1fa84d0bf84d5748cef41c57115
+ vitest: 0.3.2_7eedc1c4db875d438e18b4f15a9092b1
vue: 3.2.30
vue-jest: 5.0.0-alpha.10_9f18a56dc640bc0fc3dd15c5d03f3517
vue-router: 4.0.12_vue@3.2.30
@@ -480,15 +486,6 @@ packages:
- supports-color
dev: true
- /@babel/generator/7.17.0:
- resolution: {integrity: sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.17.0
- jsesc: 2.5.2
- source-map: 0.5.7
- dev: true
-
/@babel/generator/7.17.3:
resolution: {integrity: sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==}
engines: {node: '>=6.9.0'}
@@ -670,7 +667,7 @@ packages:
'@babel/helper-environment-visitor': 7.16.7
'@babel/helper-member-expression-to-functions': 7.16.7
'@babel/helper-optimise-call-expression': 7.16.7
- '@babel/traverse': 7.17.0
+ '@babel/traverse': 7.17.3
'@babel/types': 7.17.0
transitivePeerDependencies:
- supports-color
@@ -1640,24 +1637,6 @@ packages:
'@babel/types': 7.17.0
dev: true
- /@babel/traverse/7.17.0:
- resolution: {integrity: sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/code-frame': 7.16.7
- '@babel/generator': 7.17.0
- '@babel/helper-environment-visitor': 7.16.7
- '@babel/helper-function-name': 7.16.7
- '@babel/helper-hoist-variables': 7.16.7
- '@babel/helper-split-export-declaration': 7.16.7
- '@babel/parser': 7.17.0
- '@babel/types': 7.17.0
- debug: 4.3.3
- globals: 11.12.0
- transitivePeerDependencies:
- - supports-color
- dev: true
-
/@babel/traverse/7.17.3:
resolution: {integrity: sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==}
engines: {node: '>=6.9.0'}
@@ -2798,6 +2777,16 @@ packages:
'@babel/types': 7.17.0
dev: true
+ /@types/chai-subset/1.3.3:
+ resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==}
+ dependencies:
+ '@types/chai': 4.3.0
+ dev: true
+
+ /@types/chai/4.3.0:
+ resolution: {integrity: sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==}
+ dev: true
+
/@types/clean-css/4.2.5:
resolution: {integrity: sha512-NEzjkGGpbs9S9fgC4abuBvTpVwE3i+Acu9BBod3PUyjDVZcNsGx61b8r2PphR61QGPnn0JHVs5ey6/I4eTrkxw==}
dependencies:
@@ -3232,6 +3221,12 @@ packages:
vue: 3.2.30
dev: true
+ /@vitest/ui/0.3.2:
+ resolution: {integrity: sha512-bW2AWmfBxUlz4Xc0lpY1tfMf1MzK3ZnkzN9ACtDTrrWOQ4yEALgKxJm8qDW71x8qllWlrJTbO0R4xUVI96oc/A==}
+ dependencies:
+ sirv: 2.0.2
+ dev: true
+
/@volar/code-gen/0.31.4:
resolution: {integrity: sha512-ngivMEbBNd19v+EHdLyCJoIGRaoD9J4P20ZgdCEGf2voztja59u3Tilpf9r9ENy/731nG7XncToYm4+c1t/LhA==}
dependencies:
@@ -3304,7 +3299,7 @@ packages:
'@babel/helper-module-imports': 7.16.7
'@babel/plugin-syntax-jsx': 7.16.7_@babel+core@7.17.5
'@babel/template': 7.16.7
- '@babel/traverse': 7.17.0
+ '@babel/traverse': 7.17.3
'@babel/types': 7.17.0
'@vue/babel-helper-vue-transform-on': 1.0.2
camelcase: 6.2.0
@@ -4007,6 +4002,10 @@ packages:
engines: {node: '>=0.8'}
dev: true
+ /assertion-error/1.1.0:
+ resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
+ dev: true
+
/assign-symbols/1.0.0:
resolution: {integrity: sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=}
engines: {node: '>=0.10.0'}
@@ -4419,6 +4418,25 @@ packages:
resolution: {integrity: sha1-y5T662HIaWRR2zZTThQi+U8K7og=}
dev: true
+ /c8/7.11.0:
+ resolution: {integrity: sha512-XqPyj1uvlHMr+Y1IeRndC2X5P7iJzJlEJwBpCdBbq2JocXOgJfr+JVfJkyNMGROke5LfKrhSFXGFXnwnRJAUJw==}
+ engines: {node: '>=10.12.0'}
+ hasBin: true
+ dependencies:
+ '@bcoe/v8-coverage': 0.2.3
+ '@istanbuljs/schema': 0.1.2
+ find-up: 5.0.0
+ foreground-child: 2.0.0
+ istanbul-lib-coverage: 3.2.0
+ istanbul-lib-report: 3.0.0
+ istanbul-reports: 3.0.2
+ rimraf: 3.0.2
+ test-exclude: 6.0.0
+ v8-to-istanbul: 8.1.1
+ yargs: 16.2.0
+ yargs-parser: 20.2.9
+ dev: true
+
/cacache/15.2.0:
resolution: {integrity: sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==}
engines: {node: '>= 10'}
@@ -4529,6 +4547,19 @@ packages:
resolution: {integrity: sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=}
dev: true
+ /chai/4.3.6:
+ resolution: {integrity: sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==}
+ engines: {node: '>=4'}
+ dependencies:
+ assertion-error: 1.1.0
+ check-error: 1.0.2
+ deep-eql: 3.0.1
+ get-func-name: 2.0.0
+ loupe: 2.3.4
+ pathval: 1.1.1
+ type-detect: 4.0.8
+ dev: true
+
/chalk/2.4.2:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
engines: {node: '>=4'}
@@ -4569,6 +4600,10 @@ packages:
resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
dev: true
+ /check-error/1.0.2:
+ resolution: {integrity: sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=}
+ dev: true
+
/check-more-types/2.24.0:
resolution: {integrity: sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=}
engines: {node: '>= 0.8.0'}
@@ -5297,6 +5332,13 @@ packages:
resolution: {integrity: sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=}
dev: true
+ /deep-eql/3.0.1:
+ resolution: {integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==}
+ engines: {node: '>=0.12'}
+ dependencies:
+ type-detect: 4.0.8
+ dev: true
+
/deep-is/0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: true
@@ -6773,6 +6815,14 @@ packages:
for-in: 1.0.2
dev: true
+ /foreground-child/2.0.0:
+ resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==}
+ engines: {node: '>=8.0.0'}
+ dependencies:
+ cross-spawn: 7.0.3
+ signal-exit: 3.0.5
+ dev: true
+
/forever-agent/0.6.1:
resolution: {integrity: sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=}
dev: true
@@ -6905,6 +6955,10 @@ packages:
engines: {node: 6.* || 8.* || >= 10.*}
dev: true
+ /get-func-name/2.0.0:
+ resolution: {integrity: sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=}
+ dev: true
+
/get-intrinsic/1.1.1:
resolution: {integrity: sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==}
dependencies:
@@ -7999,6 +8053,11 @@ packages:
engines: {node: '>=8'}
dev: true
+ /istanbul-lib-coverage/3.2.0:
+ resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==}
+ engines: {node: '>=8'}
+ dev: true
+
/istanbul-lib-instrument/4.0.3:
resolution: {integrity: sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==}
engines: {node: '>=8'}
@@ -8015,7 +8074,7 @@ packages:
resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==}
engines: {node: '>=8'}
dependencies:
- istanbul-lib-coverage: 3.0.0
+ istanbul-lib-coverage: 3.2.0
make-dir: 3.1.0
supports-color: 7.2.0
dev: true
@@ -8025,7 +8084,7 @@ packages:
engines: {node: '>=8'}
dependencies:
debug: 4.3.3
- istanbul-lib-coverage: 3.0.0
+ istanbul-lib-coverage: 3.2.0
source-map: 0.6.1
transitivePeerDependencies:
- supports-color
@@ -8943,6 +9002,12 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /loupe/2.3.4:
+ resolution: {integrity: sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==}
+ dependencies:
+ get-func-name: 2.0.0
+ dev: true
+
/lru-cache/6.0.0:
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
engines: {node: '>=10'}
@@ -10034,6 +10099,10 @@ packages:
engines: {node: '>=8'}
dev: true
+ /pathval/1.1.1:
+ resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
+ dev: true
+
/pend/1.2.0:
resolution: {integrity: sha1-elfrVQpng/kRUzH89GY9XI4AelA=}
dev: true
@@ -11052,6 +11121,15 @@ packages:
totalist: 2.0.0
dev: true
+ /sirv/2.0.2:
+ resolution: {integrity: sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==}
+ engines: {node: '>= 10'}
+ dependencies:
+ '@polka/url': 1.0.0-next.20
+ mrmime: 1.0.0
+ totalist: 3.0.0
+ dev: true
+
/sisteransi/1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
dev: true
@@ -11651,6 +11729,16 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /tinypool/0.1.2:
+ resolution: {integrity: sha512-fvtYGXoui2RpeMILfkvGIgOVkzJEGediv8UJt7TxdAOY8pnvUkFg/fkvqTfXG9Acc9S17Cnn1S4osDc2164guA==}
+ engines: {node: '>=14.0.0'}
+ dev: true
+
+ /tinyspy/0.2.10:
+ resolution: {integrity: sha512-Qij6rGWCDjWIejxCXXVi6bNgvrYBp3PbqC4cBP/0fD6WHDOHCw09Zd13CsxrDqSR5PFq01WeqDws8t5lz5sH0A==}
+ engines: {node: '>=14.0.0'}
+ dev: true
+
/tmp/0.0.33:
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
engines: {node: '>=0.6.0'}
@@ -11730,6 +11818,11 @@ packages:
engines: {node: '>=6'}
dev: true
+ /totalist/3.0.0:
+ resolution: {integrity: sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==}
+ engines: {node: '>=6'}
+ dev: true
+
/tough-cookie/2.5.0:
resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==}
engines: {node: '>=0.8'}
@@ -12288,6 +12381,15 @@ packages:
source-map: 0.7.3
dev: true
+ /v8-to-istanbul/8.1.1:
+ resolution: {integrity: sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==}
+ engines: {node: '>=10.12.0'}
+ dependencies:
+ '@types/istanbul-lib-coverage': 2.0.3
+ convert-source-map: 1.8.0
+ source-map: 0.7.3
+ dev: true
+
/v8flags/3.2.0:
resolution: {integrity: sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==}
engines: {node: '>= 0.10'}
@@ -12464,6 +12566,40 @@ packages:
- stylus
dev: true
+ /vitest/0.3.2_7eedc1c4db875d438e18b4f15a9092b1:
+ resolution: {integrity: sha512-Xc0u8BVPBdD029uDcLSYDvy1MFenC6V8WvTJOGdld6NNWgz/swgsMvwZNzftsDohmHLgDyck8A+TaQdDd1tNwA==}
+ engines: {node: '>=14.14.0'}
+ hasBin: true
+ peerDependencies:
+ '@vitest/ui': '*'
+ c8: '*'
+ happy-dom: '*'
+ jsdom: '*'
+ peerDependenciesMeta:
+ '@vitest/ui':
+ optional: true
+ c8:
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+ dependencies:
+ '@types/chai': 4.3.0
+ '@types/chai-subset': 1.3.3
+ '@vitest/ui': 0.3.2
+ c8: 7.11.0
+ chai: 4.3.6
+ local-pkg: 0.4.1
+ tinypool: 0.1.2
+ tinyspy: 0.2.10
+ vite: 2.8.3_sass@1.49.7
+ transitivePeerDependencies:
+ - less
+ - sass
+ - stylus
+ dev: true
+
/void-elements/3.1.0:
resolution: {integrity: sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=}
engines: {node: '>=0.10.0'}
@@ -12949,6 +13085,19 @@ packages:
yargs-parser: 18.1.3
dev: true
+ /yargs/16.2.0:
+ resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==}
+ engines: {node: '>=10'}
+ dependencies:
+ cliui: 7.0.4
+ escalade: 3.1.1
+ get-caller-file: 2.0.5
+ require-directory: 2.1.1
+ string-width: 4.2.3
+ y18n: 5.0.8
+ yargs-parser: 20.2.9
+ dev: true
+
/yargs/17.2.1:
resolution: {integrity: sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==}
engines: {node: '>=12'}
diff --git a/tsconfig.json b/tsconfig.json
index 39669f74e5..9ef7663e23 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -11,13 +11,11 @@
"allowSyntheticDefaultImports": true,
"types": ["unplugin-vue-define-options"]
},
- "references": [{ "path": "./tsconfig.jest.json" }],
+ "references": [
+ { "path": "./tsconfig.vite-config.json" },
+ { "path": "./tsconfig.jest.json" },
+ { "path": "./tsconfig.vitest.json" }
+ ],
"include": ["packages", "typings"],
- "exclude": [
- "node_modules",
- "**/dist",
- "**/__tests__",
- "**/*.test.*",
- "**/*.spec.*"
- ]
+ "exclude": ["node_modules", "**/dist", "**/__tests__/**/*"]
}
diff --git a/tsconfig.vite-config.json b/tsconfig.vite-config.json
new file mode 100644
index 0000000000..688f689a68
--- /dev/null
+++ b/tsconfig.vite-config.json
@@ -0,0 +1,8 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.node.json",
+ "include": ["vite.config.*", "vitest.config.*"],
+ "compilerOptions": {
+ "composite": true,
+ "types": ["node", "vitest"]
+ }
+}
diff --git a/tsconfig.vitest.json b/tsconfig.vitest.json
new file mode 100644
index 0000000000..389104bb10
--- /dev/null
+++ b/tsconfig.vitest.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.node.json",
+ "include": ["packages/**/*.vitest.*"],
+ "compilerOptions": {
+ "composite": true,
+ "lib": ["DOM"],
+ "types": ["node"],
+ "jsx": "preserve"
+ }
+}
diff --git a/vitest.config.ts b/vitest.config.ts
new file mode 100644
index 0000000000..abd606015d
--- /dev/null
+++ b/vitest.config.ts
@@ -0,0 +1,13 @@
+import { defineConfig } from 'vite'
+import Vue from '@vitejs/plugin-vue'
+import VueJsx from '@vitejs/plugin-vue-jsx'
+import DefineOptions from 'unplugin-vue-define-options/vite'
+
+export default defineConfig({
+ plugins: [Vue(), VueJsx(), DefineOptions()],
+ test: {
+ include: ['**/*.vitest.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
+ exclude: ['**/*.test.*', '**/*.spec.*'],
+ environment: 'jsdom',
+ },
+})