101 lines
2.5 KiB
TypeScript
101 lines
2.5 KiB
TypeScript
import { beforeEach, afterEach, describe, expect, it, vi } from 'vitest'
|
|
import { useKeyedDebouncedSearch } from '@/composables/useKeyedDebouncedSearch'
|
|
|
|
const flushPromises = () => Promise.resolve()
|
|
|
|
describe('useKeyedDebouncedSearch', () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers()
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers()
|
|
})
|
|
|
|
it('为不同 key 独立防抖触发搜索', async () => {
|
|
const search = vi.fn().mockResolvedValue([])
|
|
const onSuccess = vi.fn()
|
|
|
|
const searcher = useKeyedDebouncedSearch<string[]>({
|
|
delay: 100,
|
|
search,
|
|
onSuccess
|
|
})
|
|
|
|
searcher.trigger('a', 'foo')
|
|
searcher.trigger('b', 'bar')
|
|
|
|
expect(search).not.toHaveBeenCalled()
|
|
|
|
vi.advanceTimersByTime(100)
|
|
await flushPromises()
|
|
|
|
expect(search).toHaveBeenCalledTimes(2)
|
|
expect(search).toHaveBeenNthCalledWith(
|
|
1,
|
|
'foo',
|
|
expect.objectContaining({ key: 'a', signal: expect.any(AbortSignal) })
|
|
)
|
|
expect(search).toHaveBeenNthCalledWith(
|
|
2,
|
|
'bar',
|
|
expect.objectContaining({ key: 'b', signal: expect.any(AbortSignal) })
|
|
)
|
|
expect(onSuccess).toHaveBeenCalledTimes(2)
|
|
})
|
|
|
|
it('同 key 新请求会取消旧请求并忽略过期响应', async () => {
|
|
const resolves: Array<(value: string[]) => void> = []
|
|
const search = vi.fn().mockImplementation(
|
|
() => new Promise<string[]>((resolve) => {
|
|
resolves.push(resolve)
|
|
})
|
|
)
|
|
const onSuccess = vi.fn()
|
|
|
|
const searcher = useKeyedDebouncedSearch<string[]>({
|
|
delay: 50,
|
|
search,
|
|
onSuccess
|
|
})
|
|
|
|
searcher.trigger('rule-1', 'first')
|
|
vi.advanceTimersByTime(50)
|
|
await flushPromises()
|
|
|
|
searcher.trigger('rule-1', 'second')
|
|
vi.advanceTimersByTime(50)
|
|
await flushPromises()
|
|
|
|
expect(search).toHaveBeenCalledTimes(2)
|
|
|
|
resolves[1](['second'])
|
|
await flushPromises()
|
|
expect(onSuccess).toHaveBeenCalledTimes(1)
|
|
expect(onSuccess).toHaveBeenLastCalledWith('rule-1', ['second'])
|
|
|
|
resolves[0](['first'])
|
|
await flushPromises()
|
|
expect(onSuccess).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('clearKey 会取消未执行任务', () => {
|
|
const search = vi.fn().mockResolvedValue([])
|
|
const onSuccess = vi.fn()
|
|
|
|
const searcher = useKeyedDebouncedSearch<string[]>({
|
|
delay: 100,
|
|
search,
|
|
onSuccess
|
|
})
|
|
|
|
searcher.trigger('a', 'foo')
|
|
searcher.clearKey('a')
|
|
|
|
vi.advanceTimersByTime(100)
|
|
|
|
expect(search).not.toHaveBeenCalled()
|
|
expect(onSuccess).not.toHaveBeenCalled()
|
|
})
|
|
})
|