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-transcriptCLI.
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",
],
);
}