import { mount } from '@vue/test-utils'
import WdForm from '@/uni_modules/wot-design-uni/components/wd-form/wd-form.vue'
import WdFormItem from '@/uni_modules/wot-design-uni/components/wd-form-item/wd-form-item.vue'
import WdInput from '@/uni_modules/wot-design-uni/components/wd-input/wd-input.vue'
import WdCalendar from '@/uni_modules/wot-design-uni/components/wd-calendar/wd-calendar.vue'
import WdCell from '@/uni_modules/wot-design-uni/components/wd-cell/wd-cell.vue'
import WdColPicker from '@/uni_modules/wot-design-uni/components/wd-col-picker/wd-col-picker.vue'
import WdDatetimePicker from '@/uni_modules/wot-design-uni/components/wd-datetime-picker/wd-datetime-picker.vue'
import WdPicker from '@/uni_modules/wot-design-uni/components/wd-picker/wd-picker.vue'
import WdSelectPicker from '@/uni_modules/wot-design-uni/components/wd-select-picker/wd-select-picker.vue'
import WdTextarea from '@/uni_modules/wot-design-uni/components/wd-textarea/wd-textarea.vue'
import WdCheckbox from '@/uni_modules/wot-design-uni/components/wd-checkbox/wd-checkbox.vue'
import WdCheckboxGroup from '@/uni_modules/wot-design-uni/components/wd-checkbox-group/wd-checkbox-group.vue'
import WdSearch from '@/uni_modules/wot-design-uni/components/wd-search/wd-search.vue'
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'
import WdTag from '@/uni_modules/wot-design-uni/components/wd-tag/wd-tag.vue'
import WdIcon from '@/uni_modules/wot-design-uni/components/wd-icon/wd-icon.vue'
import { describe, test, expect, vi } from 'vitest'
import { nextTick } from 'vue'
import type { FormRules } from '@/uni_modules/wot-design-uni/components/wd-form/types'
import { isArray } from '@/uni_modules/wot-design-uni/components/common/util'
// 全局组件
const globalComponents = {
WdFormItem,
WdInput,
WdCalendar,
WdCell,
WdColPicker,
WdDatetimePicker,
WdPicker,
WdSelectPicker,
WdTextarea,
WdCheckbox,
WdCheckboxGroup,
WdForm,
WdIcon,
WdSearch,
WdTabs,
WdTab,
WdTag
}
describe('WdForm 和 WdFormItem', () => {
// 测试基本渲染
test('测试基本渲染 - 默认属性', () => {
const wrapper = mount(WdForm, {
props: {
model: {}
}
})
expect(wrapper.classes()).toContain('wd-form')
})
// 测试表单验证
test('测试表单字段验证', async () => {
const rules: FormRules = {
name: [{ required: true, message: '请输入姓名' }],
age: [{ required: true, message: '请输入年龄' }]
}
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
name: '',
age: ''
},
rules
}
}
},
{
global: { components: globalComponents }
}
)
const form = wrapper.findComponent({ ref: 'form' })
const result = await form.vm.validate()
expect(result.valid).toBe(false)
expect(result.errors.length).toBeGreaterThan(0)
await nextTick()
expect(wrapper.findAll('.wd-input__error-message').length).toBeGreaterThan(0)
})
// 测试表单重置
test('测试表单字段重置', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
name: 'test'
}
}
}
},
{
global: { components: globalComponents }
}
)
// 使用类型断言访问组件实例的数据
const vm = wrapper.vm as any
expect(vm.formData.name).toBe('test')
// Call reset and check if error messages are cleared
vm.formData.name = ''
const form = wrapper.findComponent(WdForm)
const result = await form.vm.validate()
expect(result.valid).toBe(false)
expect(result.errors.length).toBeGreaterThan(0)
await nextTick()
expect(wrapper.find('.wd-input__error-message').exists()).toBe(true)
form.vm.reset()
await nextTick()
expect(wrapper.find('.wd-input__error-message').exists()).toBe(false)
})
// 测试表单项标签宽度
test('测试自定义标签宽度渲染', () => {
const labelWidth = '120px'
const wrapper = mount(
{
template: `
内容
`
},
{
global: { components: globalComponents }
}
)
const formItem = wrapper.findComponent(WdFormItem)
expect(formItem.props('labelWidth')).toBe(labelWidth)
})
// 测试表单错误提示类型
test('测试支持不同的错误提示类型', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
name: ''
},
rules: {
name: [{ required: true, message: '请输入姓名' }]
}
}
}
},
{
global: { components: globalComponents }
}
)
wrapper.findComponent(WdForm).vm.validate()
await wrapper.vm.$nextTick()
expect(wrapper.find('.wd-input__error-message').exists()).toBe(false)
})
// 测试自定义校验规则
test('测试处理自定义校验规则', async () => {
const validator = (value: any) => {
if (value < 18) {
return Promise.reject('年龄必须大于18岁')
} else {
return Promise.resolve()
}
}
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: { age: '17' },
rules: {
age: [
{
required: true,
message: '年龄必须大于18岁',
validator
}
]
}
}
}
},
{
global: { components: globalComponents }
}
)
const form = wrapper.findComponent({ ref: 'form' })
const result = await form.vm.validate()
expect(result.valid).toBe(false)
await nextTick()
expect(wrapper.find('.wd-input__error-message').exists()).toBe(true)
})
// 测试指定字段校验
test('测试校验指定字段', async () => {
const rules: FormRules = {
name: [{ required: true, message: '请输入姓名' }],
age: [{ required: true, message: '请输入年龄' }]
}
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
name: '',
age: '20'
},
rules
}
}
},
{
global: { components: globalComponents }
}
)
const form = wrapper.findComponent(WdForm)
const result = await form.vm.validate('name')
expect(result.valid).toBe(false)
expect(result.errors.length).toBeGreaterThan(0)
await nextTick()
const errorMessages = wrapper.findAll('.wd-input__error-message')
expect(errorMessages.length).toBeGreaterThan(0)
})
// 测试resetOnChange属性
test('当 resetOnChange 为 true 时,在模型更改时重置验证', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
name: ''
},
rules: {
name: [{ required: true, message: '请输入姓名' }]
}
}
}
},
{
global: { components: globalComponents }
}
)
const form = wrapper.findComponent(WdForm)
await form.vm.validate()
await nextTick()
expect(wrapper.find('.wd-input__error-message').exists()).toBe(true)
})
// 测试自定义类名
test('测试应用自定义类名', () => {
const customClass = 'custom-form'
const wrapper = mount(WdForm, {
props: {
model: {},
customClass
}
})
expect(wrapper.classes()).toContain(customClass)
})
// 测试自定义样式
test('测试应用自定义样式', () => {
const customStyle = 'margin: 20px;'
const wrapper = mount(WdForm, {
props: {
model: {},
customStyle
}
})
expect(wrapper.attributes('style')).toContain(customStyle)
})
// 测试与 WdSelectPicker 集成
test('测试与 WdSelectPicker 集成', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
fruit: ''
},
rules: {
fruit: [{ required: true, message: '请选择水果' }]
},
columns: [
{ label: '苹果', value: 'apple' },
{ label: '香蕉', value: 'banana' }
]
}
}
},
{
global: { components: globalComponents }
}
)
const form = wrapper.findComponent({ ref: 'form' })
const result = await form.vm.validate()
expect(result.valid).toBe(false)
expect(result.errors[0].message).toBe('请选择水果')
await nextTick()
expect(wrapper.find('.wd-cell__error-message').exists()).toBe(true)
// Set value and validate again
const vm = wrapper.vm as any
vm.formData.fruit = 'apple'
await nextTick()
const result2 = await form.vm.validate()
expect(result2.valid).toBe(true)
await nextTick()
expect(wrapper.find('.wd-cell__error-message').exists()).toBe(false)
})
// 测试与 WdPicker 集成
test('测试与 WdPicker 集成', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
city: ''
},
rules: {
city: [{ required: true, message: '请选择城市' }]
},
columns: [
{ label: '北京', value: 'beijing' },
{ label: '上海', value: 'shanghai' }
]
}
}
},
{
global: { components: globalComponents }
}
)
const form = wrapper.findComponent({ ref: 'form' })
const result = await form.vm.validate()
expect(result.valid).toBe(false)
expect(result.errors[0].message).toBe('请选择城市')
await nextTick()
expect(wrapper.find('.wd-cell__error-message').exists()).toBe(true)
// Set value and validate again
const vm = wrapper.vm as any
vm.formData.city = 'beijing'
await nextTick()
const result2 = await form.vm.validate()
expect(result2.valid).toBe(true)
await nextTick()
expect(wrapper.find('.wd-cell__error-message').exists()).toBe(false)
})
// 测试与 WdTextarea 集成
test('测试与 WdTextarea 集成', async () => {
const wrapper = mount(
{
global: { components: globalComponents },
template: `
`,
data() {
return {
formData: {
intro: ''
},
rules: {
intro: [{ required: true, message: '请输入介绍' }]
}
}
}
},
{
global: { components: globalComponents }
}
)
const form = wrapper.findComponent({ ref: 'form' })
const result = await form.vm.validate()
expect(result.valid).toBe(false)
expect(result.errors[0].message).toBe('请输入介绍')
await nextTick()
expect(wrapper.find('.wd-textarea__error-message').exists()).toBe(true)
// Set value and validate again
const vm = wrapper.vm as any
vm.formData.intro = 'some introduction'
await nextTick()
const result2 = await form.vm.validate()
expect(result2.valid).toBe(true)
await nextTick()
expect(wrapper.find('.wd-textarea__error-message').exists()).toBe(false)
})
// 测试与 WdCalendar 集成
test('测试与 WdCalendar 集成', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
date: null
},
rules: {
date: [{ required: true, message: '请选择日期' }]
}
}
}
},
{
global: { components: globalComponents }
}
)
const form = wrapper.findComponent({ ref: 'form' })
const result = await form.vm.validate()
expect(result.valid).toBe(false)
expect(result.errors[0].message).toBe('请选择日期')
await nextTick()
expect(wrapper.find('.wd-cell__error-message').exists()).toBe(true)
// Set value and validate again
const vm = wrapper.vm as any
vm.formData.date = new Date().getTime()
await nextTick()
const result2 = await form.vm.validate()
expect(result2.valid).toBe(true)
await nextTick()
expect(wrapper.find('.wd-cell__error-message').exists()).toBe(false)
})
// 测试与 WdDatetimePicker 集成
test('测试与 WdDatetimePicker 集成', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
datetime: ''
},
rules: {
datetime: [{ required: true, message: '请选择日期时间' }]
}
}
}
},
{
global: { components: globalComponents }
}
)
const form = wrapper.findComponent({ ref: 'form' })
const result = await form.vm.validate()
expect(result.valid).toBe(false)
expect(result.errors[0].message).toBe('请选择日期时间')
await nextTick()
expect(wrapper.find('.wd-cell__error-message').exists()).toBe(true)
// Set value and validate again
const vm = wrapper.vm as any
vm.formData.datetime = '2024-01-01 10:00'
await nextTick()
const result2 = await form.vm.validate()
expect(result2.valid).toBe(true)
await nextTick()
expect(wrapper.find('.wd-cell__error-message').exists()).toBe(false)
})
// 测试与 WdColPicker 集成
test('测试与 WdColPicker 集成', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
area: []
},
rules: {
area: [
{
required: true,
message: '请选择地区',
validator: (value: any) => {
return isArray(value) && value.length > 0
}
}
]
},
columns: [[{ label: '北京', value: 'beijing' }], [{ label: '朝阳区', value: 'chaoyang' }]]
}
}
},
{
global: { components: globalComponents }
}
)
const form = wrapper.findComponent({ ref: 'form' })
const result = await form.vm.validate()
expect(result.valid).toBe(false)
expect(result.errors[0].message).toBe('请选择地区')
await nextTick()
expect(wrapper.find('.wd-cell__error-message').exists()).toBe(true)
// Set value and validate again
const vm = wrapper.vm as any
vm.formData.area = ['beijing', 'chaoyang']
await nextTick()
const result2 = await form.vm.validate()
expect(result2.valid).toBe(true)
await nextTick()
expect(wrapper.find('.wd-cell__error-message').exists()).toBe(false)
})
// 测试与 WdCheckboxGroup 集成
test('测试与 WdCheckboxGroup 集成', async () => {
const wrapper = mount(
{
template: `
阅读
音乐
`,
data() {
return {
formData: {
hobbies: []
},
rules: {
hobbies: [
{
required: true,
message: '请选择爱好',
validator: (value: any) => {
return isArray(value) && value.length > 0
}
}
]
}
}
}
},
{
global: { components: globalComponents }
}
)
const form = wrapper.findComponent(WdForm)
const result = await form.vm.validate()
expect(result.valid).toBe(false)
expect(result.errors[0].message).toBe('请选择爱好')
await nextTick()
expect(wrapper.find('.wd-form-item__error-message').exists()).toBe(true)
// Set value and validate again
const vm = wrapper.vm as any
vm.formData.hobbies = ['reading']
await nextTick()
const result2 = await form.vm.validate()
expect(result2.valid).toBe(true)
await nextTick()
expect(wrapper.find('.wd-form-item__error-message').exists()).toBe(false)
})
// ===== WdFormItem 测试用例 =====
// 测试 WdFormItem 基本渲染
test('WdFormItem 基本渲染', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
username: ''
}
}
}
},
{
global: {
components: globalComponents
}
}
)
// 检查 form-item 是否正确渲染
expect(wrapper.find('.wd-form-item').exists()).toBe(true)
// 检查标签是否正确显示
expect(wrapper.text()).toContain('用户名')
})
// 测试 WdFormItem 必填标记
test('WdFormItem 显示必填标记', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
username: ''
}
}
}
},
{
global: {
components: globalComponents
}
}
)
// 检查必填标记是否存在
expect(wrapper.html()).toContain('required')
})
// 测试 WdFormItem 垂直居中
test('WdFormItem 垂直居中', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
username: ''
}
}
}
},
{
global: {
components: globalComponents
}
}
)
// 检查是否有居中样式
expect(wrapper.html()).toContain('is-center')
})
// 测试 WdFormItem 自定义标签宽度
test('WdFormItem 自定义标签宽度', async () => {
const labelWidth = '150px'
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
username: ''
}
}
}
},
{
global: {
components: globalComponents
}
}
)
// 检查标签宽度是否正确设置
const formItem = wrapper.findComponent(WdFormItem)
expect(formItem.props('labelWidth')).toBe(labelWidth)
})
// 测试 WdFormItem 链接样式
test('WdFormItem 链接样式', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
username: ''
}
}
}
},
{
global: {
components: globalComponents
}
}
)
// 检查是否有链接样式
const formItem = wrapper.findComponent(WdFormItem)
expect(formItem.props('isLink')).toBe(true)
})
// 测试 WdFormItem 错误消息显示
test('WdFormItem 错误消息显示', async () => {
const errorMessage = '用户名不能为空'
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
username: ''
},
rules: {
username: [{ required: true, message: errorMessage }]
}
}
}
},
{
global: {
components: globalComponents
}
}
)
// 触发表单验证
const form = wrapper.findComponent({ ref: 'form' })
await form.vm.validate()
await nextTick()
// 检查错误消息是否显示
expect(wrapper.find('.wd-form-item__error-message').exists()).toBe(true)
expect(wrapper.find('.wd-form-item__error-message').text()).toBe(errorMessage)
})
// 测试 WdFormItem 与 WdForm 的集成 - 表单验证
test('WdFormItem 与 WdForm 的集成 - 表单验证', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
username: '',
password: ''
},
rules: {
username: [{ required: true, message: '请输入用户名' }],
password: [{ required: true, message: '请输入密码' }]
}
}
}
},
{
global: {
components: globalComponents
}
}
)
// 触发表单验证
const form = wrapper.findComponent({ ref: 'form' })
const result = await form.vm.validate()
// 检查验证结果
expect(result.valid).toBe(false)
expect(result.errors.length).toBe(2)
await nextTick()
// 检查错误消息是否显示
const errorMessages = wrapper.findAll('.wd-form-item__error-message')
expect(errorMessages.length).toBe(2)
expect(errorMessages[0].text()).toBe('请输入用户名')
expect(errorMessages[1].text()).toBe('请输入密码')
// 更新表单数据
await wrapper.setData({
formData: {
username: 'test',
password: 'password'
}
})
// 再次验证
const result2 = await form.vm.validate()
expect(result2.valid).toBe(true)
expect(result2.errors.length).toBe(0)
await nextTick()
// 检查错误消息是否清除
expect(wrapper.find('.wd-form-item__error-message').exists()).toBe(false)
})
// 测试 WdFormItem 与 WdForm 的集成 - 重置表单
test('WdFormItem 与 WdForm 的集成 - 重置表单', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
username: ''
},
rules: {
username: [{ required: true, message: '请输入用户名' }]
}
}
}
},
{
global: {
components: globalComponents
}
}
)
// 触发表单验证
const form = wrapper.findComponent({ ref: 'form' })
await form.vm.validate()
await nextTick()
// 检查错误消息是否显示
expect(wrapper.find('.wd-form-item__error-message').exists()).toBe(true)
// 重置表单
form.vm.reset()
await nextTick()
// 检查错误消息是否清除
expect(wrapper.find('.wd-form-item__error-message').exists()).toBe(false)
})
// 测试 WdFormItem 与 WdForm 的集成 - 自定义校验规则
test('WdFormItem 与 WdForm 的集成 - 自定义校验规则', async () => {
const wrapper = mount(
{
template: `
`,
data() {
return {
formData: {
email: 'invalid-email'
}
}
},
methods: {
validateEmail(value: string): boolean {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return emailRegex.test(value)
}
}
},
{
global: {
components: globalComponents
}
}
)
// 触发表单验证
const form = wrapper.findComponent({ ref: 'form' })
const result = await form.vm.validate()
// 检查验证结果
expect(result.valid).toBe(false)
await nextTick()
// 检查错误消息是否显示
expect(wrapper.find('.wd-form-item__error-message').exists()).toBe(true)
expect(wrapper.find('.wd-form-item__error-message').text()).toBe('请输入正确的邮箱格式')
// 更新为有效的邮箱
await wrapper.setData({
formData: {
email: 'test@example.com'
}
})
// 再次验证
const result2 = await form.vm.validate()
expect(result2.valid).toBe(true)
await nextTick()
// 检查错误消息是否清除
expect(wrapper.find('.wd-form-item__error-message').exists()).toBe(false)
})
})