Files
tolaria/src/components/ResizeHandle.test.tsx
lucaronin e1cdd86ab2 test: add component tests — StatusBar, CommitDialog, DiffView, QuickOpenPalette, ResizeHandle, CreateNoteDialog, EditableValue, TypeCustomizePopover, DynamicPropertiesPanel, InspectorPanels
251 tests covering:
- StatusBar: note count, vault menu interactions
- CommitDialog: file count badge, submit via click/Cmd+Enter, validation
- DiffView: line rendering, color coding, line numbers
- QuickOpenPalette: search, sorting, fuzzy filtering, keyboard navigation
- ResizeHandle: drag with rAF batching, delta accumulation, cursor reset
- CreateNoteDialog: title input, submit, validation, defaultType
- EditableValue: view/edit modes, Enter/Escape/blur, TagPillList CRUD
- TypeCustomizePopover: resolveIcon, color/icon selection
- DynamicPropertiesPanel: properties, status pills, boolean toggle, tags,
  add property form, value coercion, delete
- InspectorPanels: relationships, backlinks, git history, navigation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 12:02:44 +01:00

101 lines
3.2 KiB
TypeScript

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import { render, fireEvent } from '@testing-library/react'
import { ResizeHandle } from './ResizeHandle'
describe('ResizeHandle', () => {
let rafCallback: FrameRequestCallback | null = null
const originalRAF = globalThis.requestAnimationFrame
const originalCAF = globalThis.cancelAnimationFrame
beforeEach(() => {
rafCallback = null
globalThis.requestAnimationFrame = vi.fn((cb: FrameRequestCallback) => {
rafCallback = cb
return 1
})
globalThis.cancelAnimationFrame = vi.fn()
})
afterEach(() => {
globalThis.requestAnimationFrame = originalRAF
globalThis.cancelAnimationFrame = originalCAF
})
it('renders a draggable handle element', () => {
const { container } = render(<ResizeHandle onResize={vi.fn()} />)
const handle = container.firstChild as HTMLElement
expect(handle).toBeInTheDocument()
expect(handle.style.cursor || handle.className).toBeTruthy()
})
it('calls onResize with delta during drag', () => {
const onResize = vi.fn()
const { container } = render(<ResizeHandle onResize={onResize} />)
const handle = container.firstChild as HTMLElement
// Start drag
fireEvent.mouseDown(handle, { clientX: 100 })
// Move mouse
fireEvent.mouseMove(document, { clientX: 120 })
// Flush rAF
if (rafCallback) rafCallback(0)
expect(onResize).toHaveBeenCalledWith(20)
})
it('accumulates delta across multiple moves before rAF', () => {
const onResize = vi.fn()
const { container } = render(<ResizeHandle onResize={onResize} />)
const handle = container.firstChild as HTMLElement
fireEvent.mouseDown(handle, { clientX: 100 })
fireEvent.mouseMove(document, { clientX: 110 })
fireEvent.mouseMove(document, { clientX: 120 })
// Only one rAF should have been scheduled
if (rafCallback) rafCallback(0)
expect(onResize).toHaveBeenCalledWith(20)
})
it('flushes pending delta on mouseUp', () => {
const onResize = vi.fn()
const { container } = render(<ResizeHandle onResize={onResize} />)
const handle = container.firstChild as HTMLElement
fireEvent.mouseDown(handle, { clientX: 100 })
fireEvent.mouseMove(document, { clientX: 115 })
// Mouse up before rAF fires
fireEvent.mouseUp(document)
expect(globalThis.cancelAnimationFrame).toHaveBeenCalled()
expect(onResize).toHaveBeenCalledWith(15)
})
it('does not call onResize when mouseMove without mouseDown', () => {
const onResize = vi.fn()
render(<ResizeHandle onResize={onResize} />)
fireEvent.mouseMove(document, { clientX: 200 })
expect(onResize).not.toHaveBeenCalled()
})
it('resets cursor and user-select on mouseUp', () => {
const onResize = vi.fn()
const { container } = render(<ResizeHandle onResize={onResize} />)
const handle = container.firstChild as HTMLElement
fireEvent.mouseDown(handle, { clientX: 100 })
expect(document.body.style.cursor).toBe('col-resize')
expect(document.body.style.userSelect).toBe('none')
fireEvent.mouseUp(document)
expect(document.body.style.cursor).toBe('')
expect(document.body.style.userSelect).toBe('')
})
})