Download packages/cli/src/ui/hooks/useAnimatedScrollbar.test.tsx from SaylorTwift/gemini-cli: direct link, hf CLI and curl.
- Browser
- Download file 3.7 kB
-
https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/cli/src/ui/hooks/useAnimatedScrollbar.test.tsx
- Command line
-
hf download hf://SaylorTwift/gemini-cli/packages/cli/src/ui/hooks/useAnimatedScrollbar.test.tsx
-
curl -L -o useAnimatedScrollbar.test.tsx https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/cli/src/ui/hooks/useAnimatedScrollbar.test.tsx
3.7 kB
| /** | |
| * @license | |
| * Copyright 2025 Google LLC | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| import { act } from 'react'; | |
| import { render } from '../../test-utils/render.js'; | |
| import { useAnimatedScrollbar } from './useAnimatedScrollbar.js'; | |
| import { debugState } from '../debug.js'; | |
| import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; | |
| const TestComponent = ({ isFocused = false }: { isFocused?: boolean }) => { | |
| useAnimatedScrollbar(isFocused, () => {}); | |
| return null; | |
| }; | |
| describe('useAnimatedScrollbar', () => { | |
| beforeEach(() => { | |
| debugState.debugNumAnimatedComponents = 0; | |
| vi.useFakeTimers(); | |
| }); | |
| afterEach(() => { | |
| vi.useRealTimers(); | |
| }); | |
| it('should not increment debugNumAnimatedComponents when not focused', async () => { | |
| await render(<TestComponent isFocused={false} />); | |
| expect(debugState.debugNumAnimatedComponents).toBe(0); | |
| }); | |
| it('should not increment debugNumAnimatedComponents on initial mount even if focused', async () => { | |
| await render(<TestComponent isFocused={true} />); | |
| expect(debugState.debugNumAnimatedComponents).toBe(0); | |
| }); | |
| it('should increment debugNumAnimatedComponents when becoming focused', async () => { | |
| const { rerender } = await render(<TestComponent isFocused={false} />); | |
| expect(debugState.debugNumAnimatedComponents).toBe(0); | |
| rerender(<TestComponent isFocused={true} />); | |
| expect(debugState.debugNumAnimatedComponents).toBe(1); | |
| }); | |
| it('should decrement debugNumAnimatedComponents when becoming unfocused', async () => { | |
| const { rerender } = await render(<TestComponent isFocused={false} />); | |
| rerender(<TestComponent isFocused={true} />); | |
| expect(debugState.debugNumAnimatedComponents).toBe(1); | |
| rerender(<TestComponent isFocused={false} />); | |
| expect(debugState.debugNumAnimatedComponents).toBe(0); | |
| }); | |
| it('should decrement debugNumAnimatedComponents on unmount', async () => { | |
| const { rerender, unmount } = await render( | |
| <TestComponent isFocused={false} />, | |
| ); | |
| rerender(<TestComponent isFocused={true} />); | |
| expect(debugState.debugNumAnimatedComponents).toBe(1); | |
| unmount(); | |
| expect(debugState.debugNumAnimatedComponents).toBe(0); | |
| }); | |
| it('should decrement debugNumAnimatedComponents after animation finishes', async () => { | |
| const { rerender } = await render(<TestComponent isFocused={false} />); | |
| rerender(<TestComponent isFocused={true} />); | |
| expect(debugState.debugNumAnimatedComponents).toBe(1); | |
| // Advance timers by enough time for animation to complete (200 + 1000 + 300 + buffer) | |
| await act(async () => { | |
| await vi.advanceTimersByTimeAsync(2000); | |
| }); | |
| expect(debugState.debugNumAnimatedComponents).toBe(0); | |
| }); | |
| it('should not crash if Date.now() goes backwards (regression test)', async () => { | |
| // Only fake timers, keep Date real so we can mock it manually | |
| vi.useFakeTimers({ | |
| toFake: ['setInterval', 'clearInterval', 'setTimeout', 'clearTimeout'], | |
| }); | |
| const dateSpy = vi.spyOn(Date, 'now'); | |
| let currentTime = 1000; | |
| dateSpy.mockImplementation(() => currentTime); | |
| const { rerender } = await render(<TestComponent isFocused={false} />); | |
| // Start animation. This captures start = 1000. | |
| rerender(<TestComponent isFocused={true} />); | |
| // Simulate time going backwards before the next frame | |
| currentTime = 900; | |
| // Trigger the interval (33ms) | |
| await act(async () => { | |
| vi.advanceTimersByTime(50); | |
| }); | |
| // If it didn't crash, we are good. | |
| // Cleanup | |
| dateSpy.mockRestore(); | |
| // Reset timers to default full fake for other tests (handled by afterEach/beforeEach usually, but here we overrode it) | |
| }); | |
| }); | |