use std::env;
use std::io::Write;
use std::path::PathBuf;
use std::process::{Command, Stdio};
fn run_binary(binary: &str, input: &str) -> String {
let build_status = Command::new("cargo")
.args(["build", "--bins"])
.status()
.expect("Failed to build workspace binaries");
if !build_status.success() {
panic!("Failed to build workspace binaries");
}
let binary_path = env::var(format!("CARGO_BIN_EXE_{}", binary.replace("-", "_")))
.ok()
.or_else(|| {
let mut path = PathBuf::from("target/debug");
path.push(binary);
if path.exists() {
Some(path.to_string_lossy().into_owned())
} else {
None
}
})
.unwrap_or_else(|| panic!("Failed to find binary: {}", binary));
let mut child = Command::new(binary_path)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.expect(&format!("Failed to spawn process: {}", binary));
if let Some(mut stdin) = child.stdin.take() {
if !input.is_empty() {
writeln!(stdin, "{}", input).expect("Failed to write to stdin");
}
drop(stdin); }
let output = child.wait_with_output().expect("Failed to read stdout");
String::from_utf8(output.stdout).expect("Invalid UTF-8 output")
}
#[test]
fn test_piped_input_sync_app() {
let output = run_binary("test_binary", "test input");
assert!(output.contains("Received input: test input"));
}
#[test]
fn test_empty_input_sync_app() {
let output = run_binary("test_binary", "");
assert!(
output.contains("fallback_value"),
"Expected fallback value but got: {}",
output
);
}
#[test]
fn test_piped_input_tokio_app() {
let output = run_binary("tokio-example-app", "test input");
assert!(output.contains("Received input: test input"));
}
#[test]
fn test_empty_input_tokio_app() {
let output = run_binary("tokio-example-app", "");
assert!(
output.contains("fallback_value"),
"Expected fallback value but got: {}",
output
);
}