| |
| |
| |
| |
| |
|
|
| import { describe, it, expect, vi } from 'vitest'; |
| import { useState, useEffect, act } from 'react'; |
| import { Text } from 'ink'; |
| import { renderHook, render } from './render.js'; |
| import { waitFor } from './async.js'; |
|
|
| describe('render', () => { |
| it('should render a component', async () => { |
| const { lastFrame, unmount } = await render(<Text>Hello World</Text>); |
| expect(lastFrame()).toBe('Hello World\n'); |
| unmount(); |
| }); |
|
|
| it('should support rerender', async () => { |
| const { lastFrame, rerender, waitUntilReady, unmount } = await render( |
| <Text>Hello</Text>, |
| ); |
| expect(lastFrame()).toBe('Hello\n'); |
|
|
| await act(async () => rerender(<Text>World</Text>)); |
| await waitUntilReady(); |
| expect(lastFrame()).toBe('World\n'); |
| unmount(); |
| }); |
|
|
| it('should support unmount', async () => { |
| const cleanupMock = vi.fn(); |
| function TestComponent() { |
| useEffect(() => cleanupMock, []); |
| return <Text>Hello</Text>; |
| } |
|
|
| const { unmount } = await render(<TestComponent />); |
| unmount(); |
| expect(cleanupMock).toHaveBeenCalled(); |
| }); |
| }); |
|
|
| describe('renderHook', () => { |
| it('should rerender with previous props when called without arguments', async () => { |
| const useTestHook = ({ value }: { value: number }) => { |
| const [count, setCount] = useState(0); |
| useEffect(() => setCount((c) => c + 1), [value]); |
| return { count, value }; |
| }; |
|
|
| const { result, rerender, waitUntilReady, unmount } = await renderHook( |
| useTestHook, |
| { initialProps: { value: 1 } }, |
| ); |
|
|
| expect(result.current.value).toBe(1); |
| await waitFor(() => expect(result.current.count).toBe(1)); |
|
|
| |
| await act(async () => rerender({ value: 2 })); |
| await waitUntilReady(); |
| expect(result.current.value).toBe(2); |
| await waitFor(() => expect(result.current.count).toBe(2)); |
|
|
| |
| |
| await act(async () => rerender()); |
| await waitUntilReady(); |
| expect(result.current.value).toBe(2); |
| |
| await waitFor(() => expect(result.current.count).toBe(2)); |
| unmount(); |
| }); |
|
|
| it('should handle initial render without props', async () => { |
| const useTestHook = () => { |
| const [count, setCount] = useState(0); |
| return { count, increment: () => setCount((c) => c + 1) }; |
| }; |
|
|
| const { result, rerender, waitUntilReady, unmount } = |
| await renderHook(useTestHook); |
|
|
| expect(result.current.count).toBe(0); |
|
|
| await act(async () => rerender()); |
| await waitUntilReady(); |
| expect(result.current.count).toBe(0); |
| unmount(); |
| }); |
|
|
| it('should update props if undefined is passed explicitly', async () => { |
| const useTestHook = (val: string | undefined) => val; |
| const { result, rerender, waitUntilReady, unmount } = await renderHook( |
| useTestHook, |
| { initialProps: 'initial' }, |
| ); |
|
|
| expect(result.current).toBe('initial'); |
|
|
| await act(async () => rerender(undefined)); |
| await waitUntilReady(); |
| expect(result.current).toBeUndefined(); |
| unmount(); |
| }); |
| }); |
|
|