use std::io::{Read, Write};
use std::process::{Command, Stdio};
fn a_long_flow() -> String {
let mut s = String::from("appId: com.example.app\n---\n");
for i in 0..20_000 {
s.push_str(&format!("- tapOn: \"row {i}\"\n"));
}
s
}
#[test]
fn a_closed_stdout_leaves_the_exit_code_to_the_work() {
let machine = tempfile::tempdir().expect("a temp dir is available in tests");
let mut child = Command::new(env!("CARGO_BIN_EXE_smix"))
.arg("migrate")
.env("SMIX_MACHINE_DIR", machine.path())
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("the smix binary this test was built with runs");
let flow = a_long_flow();
let mut stdin = child.stdin.take().expect("stdin was piped");
let writer = std::thread::spawn(move || {
stdin
.write_all(flow.as_bytes())
.expect("smix reads all of stdin before it writes");
});
let mut stdout = child.stdout.take().expect("stdout was piped");
let mut first = [0u8; 10];
stdout
.read_exact(&mut first)
.expect("smix printed at least ten bytes before the reader left");
drop(stdout);
writer.join().expect("the stdin writer finished");
let out = child.wait_with_output().expect("smix exits");
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(
!stderr.contains("panicked"),
"smix panicked when its reader left:\n{stderr}"
);
assert_eq!(
out.status.code(),
Some(0),
"the migration succeeded, so the exit code says so whoever stopped reading; stderr:\n{stderr}"
);
}