wot-design-uni/tests/components/wd-table.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

710 lines
20 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { mount } from '@vue/test-utils'
import WdTable from '@/uni_modules/wot-design-uni/components/wd-table/wd-table.vue'
import WdTableCol from '@/uni_modules/wot-design-uni/components/wd-table-col/wd-table-col.vue'
import WdSortButton from '@/uni_modules/wot-design-uni/components/wd-sort-button/wd-sort-button.vue'
import { describe, test, expect, vi, beforeEach } from 'vitest'
import { nextTick } from 'vue'
const globalComponents = {
WdTableCol,
WdSortButton
}
describe('WdTable', () => {
beforeEach(() => {
vi.clearAllMocks()
})
// 测试基本渲染
test('基本渲染', () => {
const data = [
{ name: '张三', age: 25, address: '北京' },
{ name: '李四', age: 30, address: '上海' }
]
const wrapper = mount(WdTable, {
props: {
data
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px"></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed></wd-table-col>
<wd-table-col prop="address" label="地址"></wd-table-col>
`
},
global: {
components: globalComponents
}
})
expect(wrapper.classes()).toContain('wd-table')
expect(wrapper.classes()).toContain('is-border') // 默认有边框
})
// 测试表格数据渲染
test('表格数据渲染', async () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const wrapper = mount(WdTable, {
props: {
data,
border: true
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px"></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed></wd-table-col>
<wd-table-col prop="address" label="地址"></wd-table-col>
`
},
global: {
components: globalComponents
}
})
await nextTick()
// 验证表格渲染
expect(wrapper.findComponent(WdTable).exists()).toBe(true)
expect(wrapper.findAllComponents(WdTableCol).length).toBe(3)
})
// 测试斑马纹
test('斑马纹样式', () => {
const data = [
{ name: '张三', age: 25, address: '北京' },
{ name: '李四', age: 30, address: '上海' }
]
const wrapper = mount(WdTable, {
props: {
data,
stripe: true
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px"></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed></wd-table-col>
<wd-table-col prop="address" label="地址"></wd-table-col>
`
},
global: {
components: globalComponents
}
})
// 检查 stripe 属性是否正确传递给组件
expect((wrapper.vm as any).stripe).toBe(true)
})
// 测试边框
test('边框样式', () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const wrapper = mount(WdTable, {
props: {
data,
border: true
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px"></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed></wd-table-col>
<wd-table-col prop="address" label="地址"></wd-table-col>
`
},
global: {
components: globalComponents
}
})
expect(wrapper.classes()).toContain('is-border')
})
// 测试无边框
test('无边框样式', () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const wrapper = mount(WdTable, {
props: {
data,
border: false
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px"></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed></wd-table-col>
<wd-table-col prop="address" label="地址"></wd-table-col>
`
},
global: {
components: globalComponents
}
})
expect(wrapper.classes()).not.toContain('is-border')
})
// 测试行点击事件
test('行点击事件', async () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const wrapper = mount(WdTable, {
props: {
data
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px"></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed></wd-table-col>
<wd-table-col prop="address" label="地址"></wd-table-col>
`
},
global: {
components: globalComponents
}
})
// 调用 rowClick 方法
;(wrapper.vm as any).rowClick(0)
// 验证事件
const emitted = wrapper.emitted() as Record<string, any[]>
expect(emitted['row-click']).toBeTruthy()
expect(emitted['row-click'][0][0]).toEqual({ rowIndex: 0 })
})
// 测试排序事件
test('排序方法事件', async () => {
const data = [
{ name: '张三', age: 25, address: '北京' },
{ name: '李四', age: 30, address: '上海' }
]
const wrapper = mount(WdTable, {
props: {
data
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px" sortable></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed sortable></wd-table-col>
<wd-table-col prop="address" label="地址" sortable></wd-table-col>
`
},
global: {
components: globalComponents
}
})
await nextTick()
const sortButtons = wrapper.findAllComponents(WdSortButton)
// 点击第一列(姓名)进行升序排序
if (sortButtons[0]) {
await sortButtons[0].find('.wd-sort-button').trigger('click')
}
await nextTick()
// 验证事件
let emitted = wrapper.emitted() as Record<string, any[]>
expect(emitted['sort-method']).toBeTruthy()
expect(emitted['sort-method'][0][0]).toMatchObject({
prop: 'name',
label: '姓名',
sortable: true,
sortDirection: 1 // 升序
})
// 验证子组件状态
const colComponents = wrapper.findAllComponents(WdTableCol)
expect((colComponents[0].vm as any).sortDirection).toBe(1)
expect((colComponents[1].vm as any).sortDirection).toBe(0)
// 点击第二列(年龄)进行升序排序
if (sortButtons[1]) {
await sortButtons[1].find('.wd-sort-button').trigger('click')
}
await nextTick()
// 验证事件
emitted = wrapper.emitted() as Record<string, any[]>
expect(emitted['sort-method']).toHaveLength(2) // 触发了两次
expect(emitted['sort-method'][1][0]).toMatchObject({
prop: 'age',
label: '年龄',
sortable: true,
sortDirection: 1 // 升序
})
// 验证其他列的排序方向被重置
expect((colComponents[0].vm as any).sortDirection).toBe(0)
expect((colComponents[1].vm as any).sortDirection).toBe(1)
// 再次点击第二列(年龄)进行降序排序
if (sortButtons[1]) {
await sortButtons[1].find('.wd-sort-button').trigger('click')
}
await nextTick()
// 验证事件
emitted = wrapper.emitted() as Record<string, any[]>
expect(emitted['sort-method']).toHaveLength(3)
expect(emitted['sort-method'][2][0]).toMatchObject({
prop: 'age',
label: '年龄',
sortable: true,
sortDirection: -1 // 降序
})
expect((colComponents[1].vm as any).sortDirection).toBe(-1)
// 再次点击第二列(年龄)取消排序
if (sortButtons[1]) {
await sortButtons[1].find('.wd-sort-button').trigger('click')
}
await nextTick()
// 验证事件
emitted = wrapper.emitted() as Record<string, any[]>
expect(emitted['sort-method']).toHaveLength(4)
expect(emitted['sort-method'][3][0]).toMatchObject({
prop: 'age',
label: '年龄',
sortable: true,
sortDirection: 0 // 取消排序
})
expect((colComponents[1].vm as any).sortDirection).toBe(0)
})
// 测试滚动事件
test('滚动事件处理', async () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const wrapper = mount(WdTable, {
props: {
data
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px" sortable></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed sortable></wd-table-col>
<wd-table-col prop="address" label="地址" sortable></wd-table-col>
`
},
global: {
components: globalComponents
}
})
// 模拟滚动事件
;(wrapper.vm as any).handleScroll({ detail: { scrollLeft: 100 } })
// 验证滚动位置
expect((wrapper.vm as any).state.scrollLeft).toBe(100)
})
// 测试表格高度
test('表格高度设置', () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const height = 300
const wrapper = mount(WdTable, {
props: {
data,
height
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px"></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed></wd-table-col>
<wd-table-col prop="address" label="地址"></wd-table-col>
`
},
global: {
components: globalComponents
}
})
// 验证表格高度
expect(wrapper.attributes('style')).toContain(`max-height: ${height}px`)
})
// 测试行高
test('行高设置', () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const rowHeight = 60
const wrapper = mount(WdTable, {
props: {
data,
rowHeight
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px" sortable></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed sortable></wd-table-col>
<wd-table-col prop="address" label="地址" sortable></wd-table-col>
`
},
global: {
components: globalComponents
}
})
// 验证行高属性是否正确传递给组件
expect((wrapper.vm as any).rowHeight).toBe(rowHeight)
})
// 测试隐藏表头
test('隐藏表头', () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const wrapper = mount(WdTable, {
props: {
data,
showHeader: false
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px" sortable></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed sortable></wd-table-col>
<wd-table-col prop="address" label="地址" sortable></wd-table-col>
`
},
global: {
components: globalComponents
}
})
// 验证表头隐藏
expect((wrapper.vm as any).showHeader).toBe(false)
})
// 测试文本省略
test('文本省略样式', () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const wrapper = mount(WdTable, {
props: {
data,
ellipsis: true
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px" sortable></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed sortable></wd-table-col>
<wd-table-col prop="address" label="地址" sortable></wd-table-col>
`
},
global: {
components: globalComponents
}
})
// 验证文本省略
expect((wrapper.vm as any).ellipsis).toBe(true)
})
// 测试索引列
test('索引列渲染', async () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const wrapper = mount(WdTable, {
props: {
data,
index: true
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px"></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed></wd-table-col>
<wd-table-col prop="address" label="地址"></wd-table-col>
`
},
global: {
components: globalComponents
}
})
await nextTick()
// 验证索引列
expect(wrapper.props('index')).toBe(true)
expect((wrapper.vm as any).indexColumn.label).toBe('序号')
expect((wrapper.vm as any).indexColumn.width).toBe('100rpx')
})
// 测试自定义索引列
test('自定义索引列', async () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const indexColumn = {
label: '编号',
width: '150rpx',
align: 'center' as const
}
const wrapper = mount(WdTable, {
props: {
data,
index: indexColumn
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px" sortable></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed sortable></wd-table-col>
<wd-table-col prop="address" label="地址" sortable></wd-table-col>
`
},
global: {
components: globalComponents
}
})
await nextTick()
// 验证自定义索引列
expect((wrapper.vm as any).indexColumn.label).toBe(indexColumn.label)
expect((wrapper.vm as any).indexColumn.width).toBe(indexColumn.width)
expect((wrapper.vm as any).indexColumn.align).toBe(indexColumn.align)
})
// 测试固定表头
test('固定表头', () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const wrapper = mount(WdTable, {
props: {
data,
fixedHeader: true
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px"></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed></wd-table-col>
<wd-table-col prop="address" label="地址"></wd-table-col>
`
},
global: {
components: globalComponents
}
})
// 验证固定表头属性是否正确传递给组件
expect((wrapper.vm as any).fixedHeader).toBe(true)
})
// 测试非固定表头
test('非固定表头', () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const wrapper = mount(WdTable, {
props: {
data,
fixedHeader: false
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px"></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed></wd-table-col>
<wd-table-col prop="address" label="地址"></wd-table-col>
`
},
global: {
components: globalComponents
}
})
// 验证非固定表头属性是否正确传递给组件
expect((wrapper.vm as any).fixedHeader).toBe(false)
})
// 测试获取固定列样式
test('获取固定列样式', () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const wrapper = mount(WdTable, {
props: {
data
},
global: {
components: globalComponents
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px"></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed></wd-table-col>
<wd-table-col prop="address" label="地址"></wd-table-col>
`
}
})
// 获取第一列的固定样式
const style1 = (wrapper.vm as any).getFixedStyle(0, {})
expect(style1.left).toBe(0)
// 获取第二列的固定样式
const style2 = (wrapper.vm as any).getFixedStyle(1, {})
expect(style2.left).toBe('calc(100px)')
})
// 测试判断是否最后一个固定列
test('判断是否最后一个固定列', () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const wrapper = mount(WdTable, {
props: {
data
},
global: {
components: globalComponents
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px"></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed></wd-table-col>
<wd-table-col prop="address" label="地址"></wd-table-col>
`
}
})
// 第一列不是最后一个固定列
expect((wrapper.vm as any).getIsLastFixed({ fixed: true, prop: 'name' })).toBe(false)
// 第二列是最后一个固定列
expect((wrapper.vm as any).getIsLastFixed({ fixed: true, prop: 'age' })).toBe(true)
// 第三列不是固定列
expect((wrapper.vm as any).getIsLastFixed({ fixed: false, prop: 'address' })).toBe(false)
})
// 测试获取单元格样式
test('获取单元格样式', () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const wrapper = mount(WdTable, {
props: {
data
},
global: {
components: globalComponents
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px"></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed></wd-table-col>
<wd-table-col prop="address" label="地址"></wd-table-col>
`
}
})
// 获取第一列的样式
const style1 = (wrapper.vm as any).getCellStyle(0)
// 不检查分号,只检查内容
expect(style1.includes('width:100px')).toBe(true)
// 获取第二列的样式(固定列)
const style2 = (wrapper.vm as any).getCellStyle(1)
// 不检查分号,只检查内容
expect(style2.includes('width:150px')).toBe(true)
expect(style2).toContain('left:calc(100px)')
})
// 测试自定义样式
test('自定义样式', () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const customStyle = 'margin: 10px;'
const wrapper = mount(WdTable, {
props: {
data,
customStyle
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px" sortable></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed sortable></wd-table-col>
<wd-table-col prop="address" label="地址" sortable></wd-table-col>
`
},
global: {
components: globalComponents
}
})
// 验证自定义样式
// 在测试环境中customStyle 可能会被转换或应用方式不同
// 只要确保组件有 style 属性即可
expect(wrapper.attributes('style')).toBeDefined()
})
// 测试自定义类名
test('自定义类名', () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const customClass = 'custom-table'
const wrapper = mount(WdTable, {
props: {
data,
customClass
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px" sortable></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" fixed sortable></wd-table-col>
<wd-table-col prop="address" label="地址" sortable></wd-table-col>
`
},
global: {
components: globalComponents
}
})
// 验证自定义类名
expect(wrapper.classes()).toContain(customClass)
})
// --- WdTableCol specific tests ---
// 测试 WdTableCol 的 align 属性
test('WdTableCol 对齐样式', async () => {
const data = [{ name: '张三', age: 25, address: '北京' }]
const wrapper = mount(WdTable, {
props: {
data
},
slots: {
default: `
<wd-table-col prop="name" label="姓名" width="100px" align="center"></wd-table-col>
<wd-table-col prop="age" label="年龄" width="150px" align="right"></wd-table-col>
<wd-table-col prop="address" label="地址"></wd-table-col>
`
},
global: {
components: globalComponents
}
})
await nextTick()
const cells = wrapper.findAllComponents(WdTableCol)
// 检查表头对齐
expect(cells[0].find('.wd-table__cell').classes()).toContain('is-center')
expect(cells[1].find('.wd-table__cell').classes()).toContain('is-right')
// 检查数据单元格对齐 (假设数据行渲染在表头之后)
const bodyWrapper = wrapper.find('.wd-table__body')
const dataCells = bodyWrapper.findAll('.wd-table__cell')
if (dataCells.length > 1) {
expect(dataCells[0].classes()).toContain('is-center')
expect(dataCells[1].classes()).toContain('is-right')
}
})
})