fix(hooks): [use-delayed-toggle] clear timer when call onClose (#12056)

* fix(hooks): [use-delayed-toggle] clear timer when call onClose

* test(hooks): [use-delayed-toggle] coverage 100%
This commit is contained in:
Dave 2023-03-16 22:29:24 +08:00 committed by GitHub
parent 8b3250217e
commit 8306138159
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 192 additions and 1 deletions

View File

@ -0,0 +1,183 @@
import { ref } from 'vue'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { useDelayedToggle } from '../use-delayed-toggle'
describe('use-delayed-toggle', () => {
beforeEach(() => {
vi.useFakeTimers()
})
afterEach(() => {
vi.restoreAllMocks()
})
it('should can call open/close', () => {
const cbOpen = vi.fn()
const cbClose = vi.fn()
const { onOpen, onClose } = useDelayedToggle({
open: cbOpen,
close: cbClose,
showAfter: ref(0),
hideAfter: ref(0),
autoClose: ref(0),
})
expect(cbOpen).not.toHaveBeenCalled()
expect(cbClose).not.toHaveBeenCalled()
onOpen()
vi.runAllTimers()
expect(cbOpen).toHaveBeenCalled()
expect(cbClose).not.toHaveBeenCalled()
onClose()
vi.runAllTimers()
expect(cbOpen).toHaveBeenCalledTimes(1)
expect(cbClose).toHaveBeenCalledTimes(1)
})
it('should delay of appearance', () => {
const cbOpen = vi.fn()
const cbClose = vi.fn()
const { onOpen, onClose } = useDelayedToggle({
open: cbOpen,
close: cbClose,
showAfter: ref(100),
hideAfter: ref(0),
autoClose: ref(0),
})
expect(cbOpen).not.toHaveBeenCalled()
expect(cbClose).not.toHaveBeenCalled()
onOpen()
vi.advanceTimersByTime(50)
expect(cbOpen).not.toHaveBeenCalled()
vi.advanceTimersByTime(50)
expect(cbOpen).toHaveBeenCalled()
expect(cbClose).not.toHaveBeenCalled()
onClose()
vi.runAllTimers()
expect(cbOpen).toHaveBeenCalledTimes(1)
expect(cbClose).toHaveBeenCalledTimes(1)
})
it('should delay of disappear', () => {
const cbOpen = vi.fn()
const cbClose = vi.fn()
const { onClose } = useDelayedToggle({
open: cbOpen,
close: cbClose,
showAfter: ref(0),
hideAfter: ref(100),
autoClose: ref(0),
})
expect(cbOpen).not.toHaveBeenCalled()
expect(cbClose).not.toHaveBeenCalled()
onClose()
vi.advanceTimersByTime(50)
expect(cbClose).not.toHaveBeenCalled()
vi.advanceTimersByTime(50)
expect(cbClose).toHaveBeenCalled()
vi.runAllTimers()
expect(cbOpen).not.toHaveBeenCalled()
expect(cbClose).toHaveBeenCalledTimes(1)
})
it('should disappear automatically', () => {
const cbOpen = vi.fn()
const cbClose = vi.fn()
const { onOpen } = useDelayedToggle({
open: cbOpen,
close: cbClose,
showAfter: ref(0),
hideAfter: ref(0),
autoClose: ref(100),
})
expect(cbOpen).not.toHaveBeenCalled()
expect(cbClose).not.toHaveBeenCalled()
onOpen()
vi.advanceTimersByTime(0)
expect(cbOpen).toHaveBeenCalled()
vi.advanceTimersByTime(50)
expect(cbClose).not.toHaveBeenCalled()
vi.advanceTimersByTime(50)
expect(cbClose).toHaveBeenCalled()
vi.runAllTimers()
expect(cbOpen).toHaveBeenCalledTimes(1)
expect(cbClose).toHaveBeenCalledTimes(1)
})
it('apply all time', () => {
const cbOpen = vi.fn()
const cbClose = vi.fn()
const { onOpen, onClose } = useDelayedToggle({
open: cbOpen,
close: cbClose,
showAfter: ref(100),
hideAfter: ref(100),
autoClose: ref(100),
})
expect(cbOpen).not.toHaveBeenCalled()
expect(cbClose).not.toHaveBeenCalled()
onOpen()
vi.advanceTimersByTime(0)
expect(cbOpen).not.toHaveBeenCalled()
vi.advanceTimersByTime(50)
expect(cbOpen).not.toHaveBeenCalled()
onClose()
vi.advanceTimersByTime(50)
expect(cbOpen).not.toHaveBeenCalled()
expect(cbClose).not.toHaveBeenCalled()
vi.runAllTimers()
expect(cbOpen).not.toHaveBeenCalled()
expect(cbClose).toHaveBeenCalledTimes(1)
})
it('the close function call once', () => {
const cbOpen = vi.fn()
const cbClose = vi.fn()
const { onOpen, onClose } = useDelayedToggle({
open: cbOpen,
close: cbClose,
showAfter: ref(0),
hideAfter: ref(100),
autoClose: ref(50),
})
expect(cbOpen).not.toHaveBeenCalled()
expect(cbClose).not.toHaveBeenCalled()
onOpen()
vi.advanceTimersByTime(0)
expect(cbOpen).toHaveBeenCalled()
expect(cbClose).not.toHaveBeenCalled()
onClose()
vi.advanceTimersByTime(50)
expect(cbClose).not.toHaveBeenCalled()
vi.advanceTimersByTime(50)
expect(cbOpen).toHaveBeenCalledTimes(1)
expect(cbClose).toHaveBeenCalledTimes(1)
vi.runAllTimers()
expect(cbOpen).toHaveBeenCalledTimes(1)
expect(cbClose).toHaveBeenCalledTimes(1)
})
})

View File

@ -19,6 +19,9 @@ export const useDelayedToggleProps = buildProps({
type: Number,
default: 200,
},
/**
* @description disappear automatically, in millisecond
*/
autoClose: {
type: Number,
default: 0,
@ -38,7 +41,10 @@ export const useDelayedToggle = ({
close,
}: UseDelayedToggleProps) => {
const { registerTimeout } = useTimeout()
const { registerTimeout: registerTimeoutForAutoClose } = useTimeout()
const {
registerTimeout: registerTimeoutForAutoClose,
cancelTimeout: cancelTimeoutForAutoClose,
} = useTimeout()
const onOpen = (event?: Event) => {
registerTimeout(() => {
@ -54,6 +60,8 @@ export const useDelayedToggle = ({
}
const onClose = (event?: Event) => {
cancelTimeoutForAutoClose()
registerTimeout(() => {
close(event)
}, unref(hideAfter))