Skip to main content

insta_cmd/
lib.rs

1//! `insta-cmd` is an extension to [insta](https://insta.rs/) that lets you snapshot
2//! a command that produces (text) output to stdout and stderr.  It takes a
3//! [`Command`](std::process::Command) from the standard library, runs it and
4//! snapshots the output alongside the exit code.
5//!
6//! ```no_run
7//! use std::process::Command;
8//! use insta_cmd::assert_cmd_snapshot;
9//!
10//! assert_cmd_snapshot!(Command::new("echo").arg("Hello World!"));
11//! ```
12//!
13//! ## Testing Binaries
14//!
15//! If you want to test binaries from your own project you can use the
16//! [`get_cargo_bin`] and [`get_cargo_example`] functions to retrieve the path to
17//! your binary. Cargo will automatically build binaries before running an
18//! [integration test](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#integration-tests).
19//! You will have to run ``cargo build --bin my-bin`` or
20//! ``cargo build --example my-example`` before using `insta_cmd` in a unit test.
21//!
22//! Afterwards you can test it like this:
23//!
24//! ```no_run
25//! use std::process::Command;
26//! use insta_cmd::{assert_cmd_snapshot, get_cargo_bin};
27//!
28//! assert_cmd_snapshot!(Command::new(get_cargo_bin("hello")).arg("first arg"));
29//! ```
30//!
31//! ## Passing Stdin
32//!
33//! To pass data via stdin and to have it snapshotted alongside, use the
34//! [`pass_stdin`](SpawnExt::pass_stdin) extension method.  Inside the macro
35//! it's automatically in scope.
36//!
37//! ```no_run
38//! use std::process::Command;
39//! use insta_cmd::assert_cmd_snapshot;
40//!
41//! assert_cmd_snapshot!(Command::new("cat").arg("-b").pass_stdin("Hello World"));
42//! ```
43#[doc(hidden)]
44#[macro_use]
45mod macros;
46
47mod cargo;
48mod spawn;
49
50pub use crate::cargo::{get_cargo_bin, get_cargo_example};
51pub use crate::spawn::{Spawn, SpawnExt};
52
53#[allow(deprecated)]
54pub use crate::spawn::StdinCommand;
55
56pub use std::process::Command;
57
58#[doc(hidden)]
59pub mod _macro_support {
60    pub use super::spawn::Spawn;
61    pub use insta;
62}
63
64#[cfg(test)]
65fn echo_test_helper(msg: &str) -> Command {
66    #[cfg(windows)]
67    {
68        use std::os::windows::process::CommandExt;
69        let mut rv = Command::new("cmd.exe");
70        rv.arg("/c").arg("echo").raw_arg(msg);
71        rv
72    }
73    #[cfg(unix)]
74    {
75        let mut rv = Command::new("echo");
76        rv.arg(msg);
77        rv
78    }
79}
80
81#[cfg(test)]
82fn cat_test_helper() -> Command {
83    #[cfg(windows)]
84    {
85        use std::os::windows::process::CommandExt;
86        let mut rv = Command::new("cmd.exe");
87        rv.arg("/c").arg("find").arg("/v").raw_arg("\"\"");
88        rv
89    }
90    #[cfg(unix)]
91    {
92        Command::new("cat")
93    }
94}
95
96#[cfg(unix)]
97#[test]
98fn test_basic() {
99    assert_cmd_snapshot!(["/bin/echo", "Hello World"]);
100}
101
102#[test]
103fn test_command() {
104    assert_cmd_snapshot!(echo_test_helper("Just some stuff"));
105}
106
107#[test]
108fn test_env() {
109    assert_cmd_snapshot!(echo_test_helper("Just some stuff")
110        .env("K", "V")
111        .env("A", "B")
112        .env("Y", "Z"));
113}
114
115#[test]
116fn test_env_remove_vs_empty() {
117    assert_cmd_snapshot!(echo_test_helper("Testing env")
118        .env("EMPTY_VAR", "")
119        .env_remove("REMOVED_VAR"));
120}
121
122#[cfg(unix)]
123#[test]
124#[allow(deprecated)]
125fn test_stdin() {
126    assert_cmd_snapshot!(StdinCommand::new("cat", "Hello World!"));
127}
128
129#[test]
130fn test_pass_stdin() {
131    assert_cmd_snapshot!(cat_test_helper().pass_stdin("Hello World!\n"));
132}
133
134#[cfg(unix)]
135#[test]
136fn test_pass_stdin_on_array() {
137    assert_cmd_snapshot!(["cat"].pass_stdin("Hello World!"));
138}
139
140#[cfg(unix)]
141#[test]
142fn test_failure() {
143    assert_cmd_snapshot!(["false"]);
144}
145
146#[cfg(unix)]
147#[test]
148fn test_trailing_comma_one_arg() {
149    assert_cmd_snapshot!(["echo", "42"],);
150}
151
152#[test]
153fn test_trailing_comma_named_snapshot() {
154    assert_cmd_snapshot!("named_snapshot_with_trailing_comma", echo_test_helper("27"),);
155}
156
157#[cfg(unix)]
158#[test]
159fn test_trailing_comma_inline_snapshot() {
160    assert_cmd_snapshot!(
161        Command::new("true"),
162        @r###"
163            success: true
164            exit_code: 0
165            ----- stdout -----
166
167            ----- stderr -----
168        "###,
169    );
170}