wot-design-uni/tests/components/wd-calendar.test.ts
不如摸鱼去 7e84c5c91f
feat: 引入vitest做组件测试
* chore: 🚀 引入vitest做组件测试

* chore: 🚀 引入vitest做组件测试

* chore: 🚀 update workflow

* chore: 🚀 update workflow

* chore: 🚀 update workflow

* chore: 🚀 update workflow

* chore: 🚀 update nodejs version

* chore: 🚀 update nodejs version
2025-05-06 13:38:08 +08:00

553 lines
12 KiB
TypeScript

import { mount } from '@vue/test-utils'
import '../mocks/wd-transition.mock'
import WdCalendar from '@/uni_modules/wot-design-uni/components/wd-calendar/wd-calendar.vue'
import WdActionSheet from '@/uni_modules/wot-design-uni/components/wd-action-sheet/wd-action-sheet.vue'
import WdCalendarView from '@/uni_modules/wot-design-uni/components/wd-calendar-view/wd-calendar-view.vue'
import WdButton from '@/uni_modules/wot-design-uni/components/wd-button/wd-button.vue'
import WdIcon from '@/uni_modules/wot-design-uni/components/wd-icon/wd-icon.vue'
import WdTag from '@/uni_modules/wot-design-uni/components/wd-tag/wd-tag.vue'
import { describe, expect, test, vi } from 'vitest'
import { nextTick } from 'vue'
import { CalendarFormatter } from '@/uni_modules/wot-design-uni/components/wd-calendar-view/types'
import { pause } from '@/uni_modules/wot-design-uni/components/common/util'
import WdTabs from '@/uni_modules/wot-design-uni/components/wd-tabs/wd-tabs.vue'
import WdTab from '@/uni_modules/wot-design-uni/components/wd-tab/wd-tab.vue'
describe('WdCalendar', () => {
test('基本渲染', async () => {
const wrapper = mount(WdCalendar, {
props: {
modelValue: Date.now(),
label: '日期选择'
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
expect(wrapper.classes()).toContain('wd-calendar')
expect(wrapper.find('.wd-calendar__label').text()).toBe('日期选择')
})
test('禁用状态', async () => {
const wrapper = mount(WdCalendar, {
props: {
modelValue: Date.now(),
disabled: true
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
expect(wrapper.find('.wd-calendar__cell').classes()).toContain('is-disabled')
})
test('只读状态', async () => {
const wrapper = mount(WdCalendar, {
props: {
modelValue: Date.now(),
readonly: true
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
expect(wrapper.find('.wd-calendar__cell').classes()).toContain('is-readonly')
})
test('日期范围选择', async () => {
const wrapper = mount(WdCalendar, {
props: {
modelValue: [],
type: 'daterange'
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
expect(wrapper.props('type')).toBe('daterange')
})
test('周选择', async () => {
const wrapper = mount(WdCalendar, {
props: {
modelValue: Date.now(),
type: 'week',
firstDayOfWeek: 1
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
expect(wrapper.props('type')).toBe('week')
expect(wrapper.props('firstDayOfWeek')).toBe(1)
})
test('月选择', async () => {
const wrapper = mount(WdCalendar, {
props: {
modelValue: Date.now(),
type: 'month'
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
expect(wrapper.props('type')).toBe('month')
})
test('日期时间选择', async () => {
const wrapper = mount(WdCalendar, {
props: {
modelValue: Date.now(),
type: 'datetime'
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
expect(wrapper.props('type')).toBe('datetime')
})
test('快捷选项', async () => {
const shortcuts = [
{
text: '最近7天',
id: 7
},
{
text: '最近15天',
id: 15
}
]
const wrapper = mount(WdCalendar, {
props: {
modelValue: [],
type: 'daterange',
shortcuts
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
// 打开日历
wrapper.vm.open()
await nextTick()
expect(wrapper.findAll('.wd-calendar__tag').length).toBe(2)
expect(wrapper.findAll('.wd-calendar__tag')[0].text()).toBe('最近7天')
expect(wrapper.findAll('.wd-calendar__tag')[1].text()).toBe('最近15天')
})
test('自定义格式化', async () => {
const formatter: CalendarFormatter = (day) => {
if (day.type === 'start') {
day.bottomInfo = '开始'
}
if (day.type === 'end') {
day.bottomInfo = '结束'
}
return day
}
const wrapper = mount(WdCalendar, {
props: {
modelValue: [],
type: 'daterange',
formatter
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
expect(wrapper.props('formatter')).toBeTruthy()
})
test('不使用内置单元格', async () => {
const wrapper = mount(WdCalendar, {
props: {
modelValue: Date.now(),
withCell: false
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
expect(wrapper.find('.wd-calendar__cell').exists()).toBe(false)
})
test('open 和 close 方法', async () => {
const wrapper = mount(WdCalendar, {
props: {
modelValue: Date.now()
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
// 初始状态下 ActionSheet 不显示
expect(wrapper.findComponent(WdActionSheet).props('modelValue')).toBe(false)
// 调用 open 方法
wrapper.vm.open()
await pause()
// ActionSheet 显示
expect(wrapper.findComponent(WdActionSheet).props('modelValue')).toBe(true)
expect(wrapper.emitted('open')).toBeTruthy()
// 调用 close 方法
wrapper.vm.close()
await nextTick()
// ActionSheet 隐藏
expect(wrapper.findComponent(WdActionSheet).props('modelValue')).toBe(false)
expect(wrapper.emitted('cancel')).toBeTruthy()
})
test('快捷选项点击回调', async () => {
const shortcuts = [
{
text: '最近7天',
id: 7
}
]
const onShortcutsClick = vi.fn().mockImplementation((_params: { item: any; index: number }) => {
const now = Date.now()
const sevenDaysAgo = now - 7 * 24 * 60 * 60 * 1000
return [sevenDaysAgo, now]
})
const wrapper = mount(WdCalendar, {
props: {
modelValue: [],
type: 'daterange',
shortcuts,
onShortcutsClick,
showConfirm: false
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
// 打开日历
wrapper.vm.open()
await nextTick()
// 点击快捷选项
await wrapper.find('.wd-calendar__tag').trigger('click')
// 验证回调被调用
expect(onShortcutsClick).toHaveBeenCalledWith({
item: shortcuts[0],
index: 0
})
// 验证 update:modelValue 事件被触发
expect(wrapper.emitted('update:modelValue')).toBeTruthy()
expect(wrapper.emitted('confirm')).toBeTruthy()
})
test('beforeConfirm 回调', async () => {
const beforeConfirm = vi.fn().mockImplementation((params: { value: any; resolve: (result: boolean) => void }) => {
// 模拟异步验证
setTimeout(() => {
params.resolve(true)
}, 0)
})
const wrapper = mount(WdCalendar, {
props: {
modelValue: Date.now(),
beforeConfirm
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
// 打开日历
wrapper.vm.open()
await nextTick()
// 点击确认按钮
await wrapper.findComponent(WdButton).trigger('click')
// 验证 beforeConfirm 被调用
expect(beforeConfirm).toHaveBeenCalled()
expect(beforeConfirm.mock.calls[0][0]).toHaveProperty('value')
expect(beforeConfirm.mock.calls[0][0]).toHaveProperty('resolve')
// 等待异步操作完成
await new Promise((resolve) => setTimeout(resolve, 10))
// 验证事件被触发
expect(wrapper.emitted('update:modelValue')).toBeTruthy()
expect(wrapper.emitted('confirm')).toBeTruthy()
})
test('日历视图变化事件', async () => {
const wrapper = mount(WdCalendar, {
props: {
modelValue: Date.now(),
showConfirm: false
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
// 打开日历
wrapper.vm.open()
await nextTick()
// 模拟日历视图变化
wrapper.findComponent(WdCalendarView).vm.$emit('change', { value: Date.now() + 86400000 })
await nextTick()
// 验证事件被触发
expect(wrapper.emitted('change')).toBeTruthy()
expect(wrapper.emitted('update:modelValue')).toBeTruthy()
expect(wrapper.emitted('confirm')).toBeTruthy()
})
test('自定义显示格式', async () => {
const displayFormat = vi.fn().mockImplementation((_value: any, _type: string) => {
return '自定义日期格式'
})
const wrapper = mount(WdCalendar, {
props: {
modelValue: Date.now(),
displayFormat
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
expect(wrapper.find('.wd-calendar__value').text()).toBe('自定义日期格式')
expect(displayFormat).toHaveBeenCalled()
})
test('自定义内部显示格式', async () => {
const innerDisplayFormat = vi.fn().mockImplementation((_value: any, rangeType: string, _type: string) => {
return rangeType === 'start' ? '开始日期' : '结束日期'
})
const wrapper = mount(WdCalendar, {
props: {
modelValue: [Date.now(), Date.now() + 86400000],
type: 'daterange',
innerDisplayFormat
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
// 打开日历
wrapper.vm.open()
await nextTick()
expect(innerDisplayFormat).toHaveBeenCalled()
})
test('表单验证相关属性', async () => {
const wrapper = mount(WdCalendar, {
props: {
modelValue: Date.now(),
prop: 'date',
label: '日期选择',
required: true,
rules: [{ required: true, message: '请选择日期' }]
},
global: {
components: {
WdActionSheet,
WdCalendarView,
WdButton,
WdIcon,
WdTag,
WdTabs,
WdTab
}
}
})
await nextTick()
expect(wrapper.find('.wd-calendar__label').classes()).toContain('is-required')
})
})