#[macro_export] macro_rules! shell { ($executable:expr, $args:expr, $text:expr) => {{ use std::io::Write; use std::process::{Command, Stdio}; let mut child = Command::new($executable) .args($args) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .expect("error swawning oursh process"); { let stdin = child.stdin.as_mut() .expect("error opening stdin"); stdin.write_all($text.as_bytes()) .expect("error writing to stdin"); } let output = child.wait_with_output() .expect("error reading stdout"); output }}; (> $executable:expr, $args:expr, $filename:expr) => {{ use std::process::{Command, Stdio}; let child = Command::new($executable) .arg($filename) .args($args) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .expect("error swawning oursh process"); let output = child.wait_with_output() .expect("error reading stdout"); output }}; } #[macro_export] macro_rules! oursh_release { ($text:expr) => {{ shell!("target/release/oursh", &["--noprofile"], $text) }}; // Run `oursh` on a script file argument and collect it's output. (> $filename:expr) => {{ shell!(> "target/release/oursh", &["--noprofile"], $filename) }}; } /// Run `oursh` and collect it's output for testing... Mmmmm testing. #[macro_export] macro_rules! oursh { ($text:expr) => {{ shell!("target/debug/oursh", &["--noprofile"], $text) }}; // Run `oursh` on a script file argument and collect it's output. (> $filename:expr) => {{ shell!(> "target/debug/oursh", &["--noprofile"], $filename) }}; } #[macro_export] macro_rules! assert_oursh { (! $text:expr) => {{ use std::process::Output; let Output { status, .. } = oursh!($text); assert!(!status.success()); }}; ($text:expr) => {{ use std::process::Output; let Output { status, stdout, stderr } = oursh!($text); let stdout = String::from_utf8_lossy(&stdout); let stderr = String::from_utf8_lossy(&stderr); println!("stdout: {}\nstderr: {}", stdout, stderr); assert!(status.success()); }}; ($text:expr, $stdout:expr) => {{ use std::process::Output; let Output { status, stdout, stderr } = oursh!($text); let stdout = String::from_utf8_lossy(&stdout); let stderr = String::from_utf8_lossy(&stderr); println!("stdout: {}\nstderr: {}", stdout, stderr); assert!(status.success()); assert_eq!($stdout, stdout); }}; ($text:expr, $stdout:expr, $stderr:expr) => {{ use std::process::Output; let Output { status, stdout, stderr } = oursh!($text); let stdout = String::from_utf8_lossy(&stdout); let stderr = String::from_utf8_lossy(&stderr); println!("stdout: {}\nstderr: {}", stdout, stderr); assert!(status.success()); assert_eq!($stdout, stdout); assert_eq!($stderr, stderr); }}; (> ! $filename:expr) => {{ use std::process::Output; let Output { status, .. } = oursh!(> $filename); assert!(!status.success()); }}; (> $filename:expr) => {{ use std::process::Output; let Output { status, stdout, stderr } = oursh!($filename); let stdout = String::from_utf8_lossy(&stdout); let stderr = String::from_utf8_lossy(&stderr); println!("stdout: {}\nstderr: {}", stdout, stderr); assert!(status.success()); assert!(stderr.is_empty()); }}; (> $filename:expr, $stdout:expr) => {{ use std::process::Output; let Output { status, stdout, stderr } = oursh!(> $filename); let stdout = String::from_utf8_lossy(&stdout); let stderr = String::from_utf8_lossy(&stderr); println!("stdout: {}\nstderr: {}", stdout, stderr); assert!(status.success()); assert_eq!($stdout, stdout); assert!(stderr.is_empty()); }}; (> $filename:expr, $stdout:expr, $stderr:expr) => {{ use std::process::Output; let Output { status, stdout, stderr } = oursh!($filename); let stdout = String::from_utf8_lossy(&stdout); let stderr = String::from_utf8_lossy(&stderr); println!("stdout: {}\nstderr: {}", stdout, stderr); assert!(status.success()); assert_eq!($stdout, stdout); assert_eq!($stderr, stderr); }}; }