/
vshmidt
/
streamlit
Обзор
Документация
Войти
/
vshmidt
/
streamlit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
frontend/lib/src/hooks/useTimeout.test.ts
204 строки
6 KB
Ken McGrady
Update copyright header to 2026 (#13491)
02 янв 2026, 16:21
Не верифицирован
02 янв 2026, 16:21
374540a
Код
Авторство
О чём код?
/** * Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2026) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { renderHook } from "@testing-library/react" import useTimeout from "./useTimeout" describe("timeout function", () => { beforeEach(() => { vi.useFakeTimers() }) afterEach(() => { vi.useRealTimers() }) it("should call the callback function after timeout", () => { const callback = vi.fn() const timeoutDelayMs = 50 renderHook(() => useTimeout(callback, timeoutDelayMs)) expect(callback).toHaveBeenCalledTimes(0) vi.advanceTimersByTime(timeoutDelayMs) expect(callback).toHaveBeenCalledTimes(1) }) it("should not call the callback function when cancel timeout", () => { const callback = vi.fn() const timeoutDelayMs = 100 const { result } = renderHook(() => useTimeout(callback, timeoutDelayMs)) const { clear } = result.current clear() vi.advanceTimersByTime(2 * timeoutDelayMs) expect(callback).toHaveBeenCalledTimes(0) }) it("should not call the callback when timeoutMs is null", () => { const callback = vi.fn() renderHook(() => useTimeout(callback, null)) // Wait longer than a typical timeout to ensure callback isn't called vi.advanceTimersByTime(200) expect(callback).toHaveBeenCalledTimes(0) }) it("should start timeout when timeoutMs changes from null to a number", () => { const callback = vi.fn() const timeoutDelayMs = 50 let timeoutMs: number | null = null const { rerender } = renderHook(() => useTimeout(callback, timeoutMs)) // Initially no timeout should be set vi.advanceTimersByTime(100) expect(callback).toHaveBeenCalledTimes(0) // Change timeoutMs to a number timeoutMs = timeoutDelayMs rerender() // Now callback should be called after the timeout vi.advanceTimersByTime(timeoutDelayMs) expect(callback).toHaveBeenCalledTimes(1) }) it("should clear timeout when timeoutMs changes from a number to null", () => { const callback = vi.fn() const timeoutDelayMs = 100 let timeoutMs: number | null = timeoutDelayMs const { rerender } = renderHook(() => useTimeout(callback, timeoutMs)) // Change timeoutMs to null before the timeout fires timeoutMs = null rerender() // Wait longer than the original timeout to ensure callback isn't called vi.advanceTimersByTime(2 * timeoutDelayMs) expect(callback).toHaveBeenCalledTimes(0) }) it("should handle multiple transitions between null and number values", () => { const callback = vi.fn() const timeoutDelayMs = 50 let timeoutMs: number | null = null const { rerender } = renderHook(() => useTimeout(callback, timeoutMs)) // Start with null - no callback vi.advanceTimersByTime(100) expect(callback).toHaveBeenCalledTimes(0) // Change to number - should trigger callback timeoutMs = timeoutDelayMs rerender() vi.advanceTimersByTime(timeoutDelayMs) expect(callback).toHaveBeenCalledTimes(1) // Change back to null - no more callbacks timeoutMs = null rerender() vi.advanceTimersByTime(100) expect(callback).toHaveBeenCalledTimes(1) // Change to number again - should trigger callback again timeoutMs = timeoutDelayMs rerender() vi.advanceTimersByTime(timeoutDelayMs) expect(callback).toHaveBeenCalledTimes(2) }) it("should clear timeout using the clear function when timeoutMs is null", () => { const callback = vi.fn() const { result } = renderHook(() => useTimeout(callback, null)) // Should be able to call clear function without errors even when no timeout is set const { clear } = result.current expect(() => clear()).not.toThrow() }) it("should handle changing from one number to another", () => { const callback = vi.fn() let timeoutMs = 200 // Long initial timeout const { rerender } = renderHook(() => useTimeout(callback, timeoutMs)) // Change to a shorter timeout before the first one fires timeoutMs = 50 rerender() // Should only call callback once with the new shorter timeout vi.advanceTimersByTime(50) expect(callback).toHaveBeenCalledTimes(1) // Ensure it doesn't call again after the original longer timeout vi.advanceTimersByTime(200) expect(callback).toHaveBeenCalledTimes(1) }) it("should restart timeout when restart function is called", () => { const callback = vi.fn() const timeoutDelayMs = 100 const { result } = renderHook(() => useTimeout(callback, timeoutDelayMs)) // Wait for half the timeout duration, then restart vi.advanceTimersByTime(timeoutDelayMs / 2) const { restart } = result.current restart() // Should not have called callback yet expect(callback).toHaveBeenCalledTimes(0) // Wait for the full timeout duration from restart vi.advanceTimersByTime(timeoutDelayMs) expect(callback).toHaveBeenCalledTimes(1) }) it("should handle multiple restarts before timeout fires", () => { const callback = vi.fn() const timeoutDelayMs = 80 const { result } = renderHook(() => useTimeout(callback, timeoutDelayMs)) const { restart } = result.current // Restart multiple times rapidly vi.advanceTimersByTime(20) restart() vi.advanceTimersByTime(20) restart() vi.advanceTimersByTime(20) restart() // Should not have called callback yet expect(callback).toHaveBeenCalledTimes(0) // Wait for the timeout from the last restart vi.advanceTimersByTime(timeoutDelayMs) expect(callback).toHaveBeenCalledTimes(1) }) it("should not restart timeout when timeoutMs is null", () => { const callback = vi.fn() const { result } = renderHook(() => useTimeout(callback, null)) const { restart } = result.current // Should be able to call restart without errors even when timeoutMs is null expect(() => restart()).not.toThrow() // Wait a bit and ensure callback was never called vi.advanceTimersByTime(100) expect(callback).toHaveBeenCalledTimes(0) }) })