Files
jordium-gantt-vue3/tests/unit/composables/taskRow/useTaskRowEventHandlers.spec.ts
2025-12-17 18:09:55 +08:00

378 lines
8.8 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 { describe, it, expect, vi, beforeEach } from 'vitest'
import { ref } from 'vue'
import { useTaskRowEventHandlers } from '@/components/TaskList/composables/taskRow/useTaskRowEventHandlers'
import { createTask, createParentTask } from '../../../fixtures/tasks'
describe('useTaskRowEventHandlers', () => {
let task: any
let isStoryTask: any
let hasChildren: any
let isMilestoneGroup: any
let isSplitterDragging: any
let taskRowRef: any
let enableDrag: any
let onHover: any
let emit: any
let dragStart: any
let dragOver: any
beforeEach(() => {
task = ref(createTask())
isStoryTask = ref(false)
hasChildren = ref(false)
isMilestoneGroup = ref(false)
isSplitterDragging = ref(false)
taskRowRef = ref(null)
enableDrag = ref(true)
onHover = vi.fn()
emit = vi.fn()
dragStart = vi.fn()
dragOver = vi.fn()
})
describe('handleToggle', () => {
it('应该触发 toggle 事件', () => {
const { handleToggle } = useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit
)
handleToggle()
expect(emit).toHaveBeenCalledWith('toggle', task.value)
})
it('未传入 emit 时不应报错', () => {
const { handleToggle } = useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover
)
expect(() => handleToggle()).not.toThrow()
})
})
describe('handleRowClick', () => {
it('点击有子任务的行应触发 toggle', () => {
hasChildren.value = true
const { handleRowClick } = useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit
)
handleRowClick()
expect(emit).toHaveBeenCalledWith('toggle', task.value)
})
it('点击 story 类型任务应触发 toggle', () => {
isStoryTask.value = true
const { handleRowClick } = useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit
)
handleRowClick()
expect(emit).toHaveBeenCalledWith('toggle', task.value)
})
it('点击里程碑分组不应触发 toggle', () => {
isMilestoneGroup.value = true
hasChildren.value = true
const { handleRowClick } = useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit
)
handleRowClick()
expect(emit).not.toHaveBeenCalled()
})
it('点击普通任务不应触发 toggle', () => {
const { handleRowClick } = useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit
)
handleRowClick()
expect(emit).not.toHaveBeenCalled()
})
})
describe('handleTaskRowDoubleClick', () => {
it('应该触发 dblclick 事件', () => {
const { handleTaskRowDoubleClick } = useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit
)
const event = new MouseEvent('dblclick', { bubbles: true })
const stopPropagation = vi.spyOn(event, 'stopPropagation')
handleTaskRowDoubleClick(event)
expect(stopPropagation).toHaveBeenCalled()
expect(emit).toHaveBeenCalledWith('dblclick', task.value)
})
})
describe('handleMouseEnter / handleMouseLeave', () => {
it('鼠标进入应调用 onHover 并传入任务ID', () => {
task.value.id = 123
const { handleMouseEnter } = useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit
)
handleMouseEnter()
expect(onHover).toHaveBeenCalledWith(123)
})
it('鼠标离开应调用 onHover 并传入 null', () => {
const { handleMouseLeave } = useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit
)
handleMouseLeave()
expect(onHover).toHaveBeenCalledWith(null)
})
it('Splitter 拖拽时应忽略鼠标进入事件', () => {
isSplitterDragging.value = true
const { handleMouseEnter } = useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit
)
handleMouseEnter()
expect(onHover).not.toHaveBeenCalled()
})
it('Splitter 拖拽时应忽略鼠标离开事件', () => {
isSplitterDragging.value = true
const { handleMouseLeave } = useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit
)
handleMouseLeave()
expect(onHover).not.toHaveBeenCalled()
})
})
describe('handleMouseDown - 拖拽', () => {
it('enableDrag 为 false 时不应启动拖拽', () => {
enableDrag.value = false
taskRowRef.value = document.createElement('div')
const { handleMouseDown } = useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit,
dragStart,
dragOver
)
const event = new MouseEvent('mousedown')
handleMouseDown(event)
expect(dragStart).not.toHaveBeenCalled()
})
it('enableDrag 为 true 时应启动拖拽', () => {
enableDrag.value = true
const mockElement = document.createElement('div')
taskRowRef.value = mockElement
const { handleMouseDown } = useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit,
dragStart,
dragOver
)
const mockDiv = document.createElement('div')
const event = new MouseEvent('mousedown', { bubbles: true })
Object.defineProperty(event, 'target', { value: mockDiv, enumerable: true })
handleMouseDown(event)
expect(dragStart).toHaveBeenCalledWith(task.value, mockElement, event)
})
it('taskRowRef 为 null 时不应启动拖拽', () => {
enableDrag.value = true
taskRowRef.value = null
const { handleMouseDown } = useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit,
dragStart,
dragOver
)
const mockDiv = document.createElement('div')
const event = new MouseEvent('mousedown', { bubbles: true })
Object.defineProperty(event, 'target', { value: mockDiv, enumerable: true })
handleMouseDown(event)
expect(dragStart).not.toHaveBeenCalled()
})
})
describe('Splitter 拖拽状态', () => {
// 注意Splitter 拖拽事件是通过 window 事件监听器注册的onMounted 中)
// 在单元测试中无法直接测试,需要通过组件集成测试来验证
it.skip('handleSplitterDragStart 通过 window 事件触发', () => {
useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit
)
// 触发 window 事件
window.dispatchEvent(new Event('splitter-drag-start'))
expect(isSplitterDragging.value).toBe(true)
})
it.skip('handleSplitterDragEnd 通过 window 事件触发', () => {
isSplitterDragging.value = true
useTaskRowEventHandlers(
task,
isStoryTask,
hasChildren,
isMilestoneGroup,
isSplitterDragging,
taskRowRef,
enableDrag,
onHover,
emit
)
// 触发 window 事件
window.dispatchEvent(new Event('splitter-drag-end'))
expect(isSplitterDragging.value).toBe(false)
})
})
})