Download packages/cli/src/ui/hooks/useLoadingIndicator.test.ts from Jimmi42/openCLI: direct link, hf CLI and curl.
- Browser
- Download file 4.51 kB
-
https://huggingface.co/Jimmi42/openCLI/resolve/main/packages/cli/src/ui/hooks/useLoadingIndicator.test.ts
- Command line
-
hf download hf://Jimmi42/openCLI/packages/cli/src/ui/hooks/useLoadingIndicator.test.ts
-
curl -L -o useLoadingIndicator.test.ts https://huggingface.co/Jimmi42/openCLI/resolve/main/packages/cli/src/ui/hooks/useLoadingIndicator.test.ts
4.51 kB
| /** | |
| * @license | |
| * Copyright 2025 Google LLC | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; | |
| import { renderHook, act } from '@testing-library/react'; | |
| import { useLoadingIndicator } from './useLoadingIndicator.js'; | |
| import { StreamingState } from '../types.js'; | |
| import { | |
| WITTY_LOADING_PHRASES, | |
| PHRASE_CHANGE_INTERVAL_MS, | |
| } from './usePhraseCycler.js'; | |
| describe('useLoadingIndicator', () => { | |
| beforeEach(() => { | |
| vi.useFakeTimers(); | |
| }); | |
| afterEach(() => { | |
| vi.useRealTimers(); // Restore real timers after each test | |
| act(() => vi.runOnlyPendingTimers); | |
| }); | |
| it('should initialize with default values when Idle', () => { | |
| const { result } = renderHook(() => | |
| useLoadingIndicator(StreamingState.Idle), | |
| ); | |
| expect(result.current.elapsedTime).toBe(0); | |
| expect(result.current.currentLoadingPhrase).toBe(WITTY_LOADING_PHRASES[0]); | |
| }); | |
| it('should reflect values when Responding', async () => { | |
| const { result } = renderHook(() => | |
| useLoadingIndicator(StreamingState.Responding), | |
| ); | |
| // Initial state before timers advance | |
| expect(result.current.elapsedTime).toBe(0); | |
| expect(WITTY_LOADING_PHRASES).toContain( | |
| result.current.currentLoadingPhrase, | |
| ); | |
| const initialPhrase = result.current.currentLoadingPhrase; | |
| await act(async () => { | |
| await vi.advanceTimersByTimeAsync(PHRASE_CHANGE_INTERVAL_MS); | |
| }); | |
| // Phrase should cycle if PHRASE_CHANGE_INTERVAL_MS has passed | |
| expect(result.current.currentLoadingPhrase).not.toBe(initialPhrase); | |
| expect(WITTY_LOADING_PHRASES).toContain( | |
| result.current.currentLoadingPhrase, | |
| ); | |
| }); | |
| it('should show waiting phrase and retain elapsedTime when WaitingForConfirmation', async () => { | |
| const { result, rerender } = renderHook( | |
| ({ streamingState }) => useLoadingIndicator(streamingState), | |
| { initialProps: { streamingState: StreamingState.Responding } }, | |
| ); | |
| await act(async () => { | |
| await vi.advanceTimersByTimeAsync(60000); | |
| }); | |
| expect(result.current.elapsedTime).toBe(60); | |
| act(() => { | |
| rerender({ streamingState: StreamingState.WaitingForConfirmation }); | |
| }); | |
| expect(result.current.currentLoadingPhrase).toBe( | |
| 'Waiting for user confirmation...', | |
| ); | |
| expect(result.current.elapsedTime).toBe(60); // Elapsed time should be retained | |
| // Timer should not advance further | |
| await act(async () => { | |
| await vi.advanceTimersByTimeAsync(2000); | |
| }); | |
| expect(result.current.elapsedTime).toBe(60); | |
| }); | |
| it('should reset elapsedTime and use a witty phrase when transitioning from WaitingForConfirmation to Responding', async () => { | |
| const { result, rerender } = renderHook( | |
| ({ streamingState }) => useLoadingIndicator(streamingState), | |
| { initialProps: { streamingState: StreamingState.Responding } }, | |
| ); | |
| await act(async () => { | |
| await vi.advanceTimersByTimeAsync(5000); // 5s | |
| }); | |
| expect(result.current.elapsedTime).toBe(5); | |
| act(() => { | |
| rerender({ streamingState: StreamingState.WaitingForConfirmation }); | |
| }); | |
| expect(result.current.elapsedTime).toBe(5); | |
| expect(result.current.currentLoadingPhrase).toBe( | |
| 'Waiting for user confirmation...', | |
| ); | |
| act(() => { | |
| rerender({ streamingState: StreamingState.Responding }); | |
| }); | |
| expect(result.current.elapsedTime).toBe(0); // Should reset | |
| expect(WITTY_LOADING_PHRASES).toContain( | |
| result.current.currentLoadingPhrase, | |
| ); | |
| await act(async () => { | |
| await vi.advanceTimersByTimeAsync(1000); | |
| }); | |
| expect(result.current.elapsedTime).toBe(1); | |
| }); | |
| it('should reset timer and phrase when streamingState changes from Responding to Idle', async () => { | |
| const { result, rerender } = renderHook( | |
| ({ streamingState }) => useLoadingIndicator(streamingState), | |
| { initialProps: { streamingState: StreamingState.Responding } }, | |
| ); | |
| await act(async () => { | |
| await vi.advanceTimersByTimeAsync(10000); // 10s | |
| }); | |
| expect(result.current.elapsedTime).toBe(10); | |
| act(() => { | |
| rerender({ streamingState: StreamingState.Idle }); | |
| }); | |
| expect(result.current.elapsedTime).toBe(0); | |
| expect(result.current.currentLoadingPhrase).toBe(WITTY_LOADING_PHRASES[0]); | |
| // Timer should not advance | |
| await act(async () => { | |
| await vi.advanceTimersByTimeAsync(2000); | |
| }); | |
| expect(result.current.elapsedTime).toBe(0); | |
| }); | |
| }); | |