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.  Note that it's unlikely that cargo will have built the binary
18//! under normal circumstances so you will have to run ``cargo build --bin my-bin``
19//! or ``cargo build --example my-example`` before.
20//!
21//! Afterwards you can test it like this:
22//!
23//! ```no_run
24//! use std::process::Command;
25//! use insta_cmd::{assert_cmd_snapshot, get_cargo_bin};
26//!
27//! assert_cmd_snapshot!(Command::new(get_cargo_bin("hello")).arg("first arg"));
28//! ```
29//!
30//! ## Passing Stdin
31//!
32//! To pass data via stdin and to have it snapshotted alongside, use the
33//! [`pass_stdin`](SpawnExt::pass_stdin) extension method.  Inside the macro
34//! it's automatically in scope.
35//!
36//! ```no_run
37//! use std::process::Command;
38//! use insta_cmd::assert_cmd_snapshot;
39//!
40//! assert_cmd_snapshot!(Command::new("cat").arg("-b").pass_stdin("Hello World"));
41//! ```
42#[doc(hidden)]
43#[macro_use]
44mod macros;
45
46mod cargo;
47mod spawn;
48
49pub use crate::cargo::{get_cargo_bin, get_cargo_example};
50pub use crate::spawn::{Spawn, SpawnExt};
51
52#[allow(deprecated)]
53pub use crate::spawn::StdinCommand;
54
55pub use std::process::Command;
56
57#[doc(hidden)]
58pub mod _macro_support {
59    pub use super::spawn::Spawn;
60    pub use insta;
61}
62
63#[cfg(test)]
64fn echo_test_helper(msg: &str) -> Command {
65    #[cfg(windows)]
66    {
67        use std::os::windows::process::CommandExt;
68        let mut rv = Command::new("cmd.exe");
69        rv.arg("/c").arg("echo").raw_arg(msg);
70        rv
71    }
72    #[cfg(unix)]
73    {
74        let mut rv = Command::new("echo");
75        rv.arg(msg);
76        rv
77    }
78}
79
80#[cfg(test)]
81fn cat_test_helper() -> Command {
82    #[cfg(windows)]
83    {
84        use std::os::windows::process::CommandExt;
85        let mut rv = Command::new("cmd.exe");
86        rv.arg("/c").arg("find").arg("/v").raw_arg("\"\"");
87        rv
88    }
89    #[cfg(unix)]
90    {
91        Command::new("cat")
92    }
93}
94
95#[cfg(unix)]
96#[test]
97fn test_basic() {
98    assert_cmd_snapshot!(["/bin/echo", "Hello World"]);
99}
100
101#[test]
102fn test_command() {
103    assert_cmd_snapshot!(echo_test_helper("Just some stuff"));
104}
105
106#[test]
107fn test_env() {
108    assert_cmd_snapshot!(echo_test_helper("Just some stuff")
109        .env("K", "V")
110        .env("A", "B")
111        .env("Y", "Z"));
112}
113
114#[cfg(unix)]
115#[test]
116#[allow(deprecated)]
117fn test_stdin() {
118    assert_cmd_snapshot!(StdinCommand::new("cat", "Hello World!"));
119}
120
121#[test]
122fn test_pass_stdin() {
123    assert_cmd_snapshot!(cat_test_helper().pass_stdin("Hello World!\n"));
124}
125
126#[cfg(unix)]
127#[test]
128fn test_pass_stdin_on_array() {
129    assert_cmd_snapshot!(["cat"].pass_stdin("Hello World!"));
130}
131
132#[cfg(unix)]
133#[test]
134fn test_failure() {
135    assert_cmd_snapshot!(["false"]);
136}
137
138#[cfg(unix)]
139#[test]
140fn test_trailing_comma_one_arg() {
141    assert_cmd_snapshot!(["echo", "42"],);
142}
143
144#[test]
145fn test_trailing_comma_named_snapshot() {
146    assert_cmd_snapshot!("named_snapshot_with_trailing_comma", echo_test_helper("27"),);
147}
148
149#[cfg(unix)]
150#[test]
151fn test_trailing_comma_inline_snapshot() {
152    assert_cmd_snapshot!(
153        Command::new("true"),
154        @r###"
155            success: true
156            exit_code: 0
157            ----- stdout -----
158
159            ----- stderr -----
160        "###,
161    );
162}