use anyhow::{Context, Result};
use std::path::PathBuf;
fn repo_root() -> Result<PathBuf> {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.and_then(|path| path.parent())
.map(PathBuf::from)
.context("resolve repo root")
}
fn read_script(relative_path: &str) -> Result<String> {
std::fs::read_to_string(repo_root()?.join(relative_path))
.with_context(|| format!("read script {relative_path}"))
}
#[test]
fn test_macos_contract_scripts_enforce_app_cleanup() -> Result<()> {
for relative_path in [
"scripts/macos-settings-smoke.sh",
"scripts/macos-workspace-routing-contract.sh",
] {
let script = read_script(relative_path)?;
assert!(
script.contains("terminate_contract_app()"),
"{relative_path} should define explicit app termination cleanup"
);
assert!(
script.contains("trap cleanup EXIT INT TERM"),
"{relative_path} should clean up on normal exit and interruption"
);
assert!(
script.contains("pkill -TERM -f \"$APP_EXECUTABLE\""),
"{relative_path} should terminate lingering RalphMac contract processes"
);
assert!(
script.contains("lingering app process"),
"{relative_path} should fail loudly if the app still runs after the contract completes"
);
assert!(
script.contains("rm -rf \"$TEMP_ROOT\""),
"{relative_path} should remove disposable temp roots during cleanup"
);
}
Ok(())
}