ink-testing-library

repository·master·Indexed 41 days ago

https://github.com/vadimdemedes/ink-testing-library

Utilities for testing Ink applications version 4.0.0. It provides a render function to simulate the rendering lifecycle, simulate stdin input via stdin.write(), and capture stdout/stderr output using lastFrame() and frames.

Tokens
1.6K
Snippets
12
Records
12
Agent score
50%

What's inside ink-testing-library

  1. Basic usage of ink-testing-library

    master

    Use render to wrap your Ink component. You can then use lastFrame() to assert the current output or rerender() to update the component with new props and verify the changes.

    import React from 'react';
    import {Text} from 'ink';
    import {render} from 'ink-testing-library';
    
    const Counter = ({count}) => <Text>Count: {count}</Text>;
    
    const {lastFrame, rerender} = render(<Counter count={0}/>);
    lastFrame() === 'Count: 0'; //=> true
    
    rerender(<Counter count={1}/>);
    lastFrame() === 'Count: 1'; //=> true
  2. Inspect stdout and stderr streams

    master

    Both stdout and stderr objects provide methods to inspect the output rendered by your component:

    • lastFrame(): Returns the most recent rendered frame (output) from the stream.
    • frames: An array of all rendered frames, where the last frame is the final item in the array.

    Note: lastFrame() is also available as a top-level shortcut on the object returned by render.

    const Counter = ({count}) => <Text>Count: {count}</Text>;
    const {stdout, rerender} = render(<Counter count={0}/>);
    rerender(<Counter count={1}/>);
    
    console.log(stdout.frames); //=> ['Count: 0', 'Count: 1']
  3. Interact with stdin using stdin.write()

    master

    The stdin object allows you to simulate user input. Use stdin.write(data) to write data to the current component's stdin stream, which can be captured by hooks like useInput in Ink.

    import {useInput, Text} from 'ink';
    
    const Test = () => {
    	useInput(input => {
    		console.log(input);
    		//=> 'hello'
    	});
    
    	return …;
    };
    
    const {stdin} = render(<Test/>);
    stdin.write('hello');
  4. Use render(tree) to test Ink components

    master

    The render(tree) function is the primary entry point. It takes a ReactElement (the component you want to test) and returns an object containing utilities to interact with the rendered component's lifecycle and streams.

    Parameters:

    • tree: The ReactElement to render.

    Returns: An object containing lastFrame, frames, rerender, unmount, stdin, stdout, and stderr.

    render(<MyApp/>);
  5. Clean up all rendered instances with cleanup()

    master

    The cleanup() function unmounts and cleans up every Ink instance created via render() during the current process. This is typically called in a test runner's global teardown hook to prevent memory leaks and side effects between tests.

    import { cleanup } from 'ink-testing-library';
    
    // In your test runner's global teardown (e.g., Vitest or Jest)
    afterEach(() => {
      cleanup();
    });
  6. Inspect output using stdout, stderr, and lastFrame()

    master

    To assert against what the component printed to the terminal, use the stdout and stderr objects or the lastFrame() helper:

    • stdout.frames: An array of all frames written to standard output.
    • stderr.frames: An array of all frames written to standard error.
    • lastFrame(): A function that returns the most recent frame written to stdout.
    const { stdout, lastFrame } = render(<MyComponent />);
    
    // Check the most recent output
    expect(lastFrame()).toContain('Hello World');
    
    // Check all frames captured
    expect(stdout.frames).toContain('Initial State');
  7. Manage component lifecycle with rerender, unmount, and cleanup

    master

    The Instance returned by render() provides the following lifecycle methods:

    • rerender(tree: ReactElement): Updates the rendered component with a new React element.
    • unmount(): Unmounts the current component instance.
    • cleanup(): Cleans up all currently rendered instances (useful in afterEach hooks).
    const { rerender, unmount, cleanup } = render(<MyComponent />);
    
    // To update the component:
    rerender(<MyComponent updated />);
    
    // To unmount this specific instance:
    unmount();
    
    // To clean up all instances globally:
    cleanup();
  8. Simulate user input using stdin

    master

    The stdin object allows you to simulate user typing or terminal input. You can use the write(data: string) method to push data into the stream, which will trigger 'data' and 'readable' events on the stdin instance.

    const { stdin } = render(<MyComponent />);
    
    // Simulate user typing 'hello'
    stdin.write('hello');
  9. Render an Ink component with render()

    master

    Use render(tree) to mount a React element within a test environment. It returns an Instance object that provides access to simulated stdin, stdout, and stderr streams, as well as methods to control the component lifecycle. This is the primary entry point for testing Ink applications.

    import { render } from 'ink-testing-library';
    
    const { 
      rerender, 
      unmount, 
      cleanup, 
      stdout, 
      stdin, 
      lastFrame 
    } = render(<MyComponent />);