Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Using Library

Add this to your Crate.toml:

[dependencies]
term-transcript = "0.5.0-beta.1"

See the library docs for detailed description of its API.

Basic workflow

The code snippet below executes a single echo command in the default shell (sh for *NIX, cmd for Windows), and captures the rendered transcript to stdout.

#![allow(unused)]
fn main() {
use term_transcript::{svg::Template, ShellOptions, Transcript, UserInput};
use std::str;

let transcript = Transcript::from_inputs(
    &mut ShellOptions::default(),
    vec![UserInput::command(r#"echo "Hello world!""#)],
)?;
let mut writer = vec![];
// ^ Any `std::io::Write` implementation will do, such as a `File`.
Template::default().render(&transcript, &mut writer)?;
println!("{}", str::from_utf8(&writer)?);
anyhow::Ok(())
}

Use in CLI tests

CLI tests are effectively slightly more sophisticated snapshot tests. Such tests usually adhere to the following workflow.

Tip

The snippets below are taken from end-to-end tests for term-transcript CLI.

Define path to snapshots

For example, snapshots may be located in the examples directory of the crate, or in a tests subdirectory.

fn svg_snapshot(name: &str) -> PathBuf {
    let mut snapshot_path = Path::new("tests/snapshots").join(name);
    snapshot_path.set_extension("svg");
    snapshot_path
}

Configure shell

This configures the used shell (e.g., sh or bash), the working directory, PATH additions etc. Usually can be shared among all tests.

// Executes commands in a temporary dir, with paths to the `term-transcript` binary and
// the `rainbow` script added to PATH.
fn test_config() -> (TestConfig<StdShell>, TempDir) {
    let temp_dir = tempdir().expect("cannot create temporary directory");
    let rainbow_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("../e2e-tests/rainbow/bin");

    let shell_options = ShellOptions::sh()
        .with_env("COLOR", "always")
        // Switch off logging if `RUST_LOG` is set in the surrounding env
        .with_env("RUST_LOG", "off")
        .with_current_dir(temp_dir.path())
        .with_cargo_path()
        .with_additional_path(rainbow_dir)
        .with_io_timeout(Duration::from_secs(2));
    let config = TestConfig::new(shell_options).with_match_kind(MatchKind::Precise);
    (config, temp_dir)
}

Configure template(s)

Zero or more template options determining how the captured snapshots are displayed, e.g., scrolling options, window frame, line numbering etc.

fn scrolled_template() -> Template {
    let template_options = TemplateOptions {
        window: Some(WindowOptions::default()),
        scroll: Some(ScrollOptions::default()),
        ..TemplateOptions::default()
    };
    Template::new(template_options.validated().unwrap())
}

Define tests

Finally, use the definitions above for tests. Each test will provide inputs supplied to the shell, and will compare the captured output to one recorded in the snapshot.

#[test]
fn print_example() {
    let (mut config, _dir) = test_config();
    config.test(
        svg_snapshot("print"),
        [
            "term-transcript exec -I 300ms -T 100ms 'rainbow --short' > short.svg",
            "term-transcript print short.svg",
        ],
    );
}