use crate::context::Context;
use log::debug;
use std::{
panic::{UnwindSafe, catch_unwind, resume_unwind},
path::Path,
process::{Child, Output},
};
pub fn test_php_script(lib_path: impl AsRef<Path>, script: impl AsRef<Path>) {
let condition = |output: Output| output.status.success();
let scripts = Some(script);
let scripts = scripts
.iter()
.map(|s| (s as _, &condition as _))
.collect::<Vec<_>>();
test_php_scripts_with_condition(lib_path, &scripts);
}
pub fn test_php_scripts(lib_path: impl AsRef<Path>, scripts: &[&dyn AsRef<Path>]) {
let condition = |output: Output| output.status.success();
let scripts = scripts
.iter()
.map(|s| (*s, &condition as _))
.collect::<Vec<_>>();
test_php_scripts_with_condition(lib_path, &scripts);
}
pub fn test_php_script_with_condition(
lib_path: impl AsRef<Path>, script: impl AsRef<Path>, condition: impl Fn(Output) -> bool,
) {
let scripts = Some(script);
let scripts = scripts
.iter()
.map(|s| (s as _, &condition as _))
.collect::<Vec<_>>();
test_php_scripts_with_condition(lib_path, &scripts);
}
pub type ScriptCondition<'a> = (&'a dyn AsRef<Path>, &'a dyn Fn(Output) -> bool);
pub fn test_php_scripts_with_condition(
lib_path: impl AsRef<Path>, scripts: &[ScriptCondition<'_>],
) {
let context = Context::get_global();
for (script, condition) in scripts {
let mut cmd = context.create_command_with_lib(&lib_path, script);
let output = cmd.output().unwrap();
let path = script.as_ref().to_str().unwrap();
let mut stdout = String::from_utf8_lossy(&output.stdout).to_string();
if stdout.is_empty() {
stdout.push_str("<empty>");
}
let mut stderr = String::from_utf8_lossy(&output.stderr).to_string();
if stderr.is_empty() {
stderr.push_str("<empty>");
};
debug!(command:% = cmd.get_command().join(" ".as_ref()).to_string_lossy(),
status:? = output.status.code(),
stdout = &*stdout,
stderr:%,
signal:? = {
#[cfg(unix)]
{
use std::os::unix::process::ExitStatusExt as _;
output.status.signal()
}
#[cfg(not(unix))]
{
None
}
};
"execute php test command");
if !condition(output) {
eprintln!("--- stdout ---\n{}", stdout);
eprintln!("--- stderr ---\n{}", stderr);
panic!("test php file `{}` failed", path);
}
}
}
#[allow(clippy::zombie_processes)]
pub fn test_long_term_php_script_with_condition(
lib_path: impl AsRef<Path>, script: impl AsRef<Path>,
condition: impl FnOnce(&Child) + UnwindSafe,
) {
let context = Context::get_global();
let mut command = context.create_command_with_lib(lib_path, script);
let mut child = command.spawn().unwrap();
let r = catch_unwind(|| condition(&child));
child.kill().unwrap();
if let Err(e) = r {
resume_unwind(e);
}
}