use std::fs;
use std::path::{Path, PathBuf};
const SMOKE_TEMPLATE: &str = include_str!("../templates/test_init/smoke.rs.tmpl");
const TARGET_FILE: &str = "smoke.rs";
pub(crate) fn run(force: bool, out: &str) -> Result<(), String> {
let out_root = Path::new(out);
let dest: PathBuf = out_root.join(TARGET_FILE);
if dest.exists() && !force {
return Err(format!(
"{} already exists. Pass --force to overwrite, or move the existing file first.",
dest.display()
));
}
if let Some(parent) = dest.parent() {
fs::create_dir_all(parent)
.map_err(|e| format!("create directory {}: {e}", parent.display()))?;
}
fs::write(&dest, SMOKE_TEMPLATE).map_err(|e| format!("write {}: {e}", dest.display()))?;
println!("Wrote {} ({} bytes).", dest.display(), SMOKE_TEMPLATE.len());
println!();
println!("Run it with:");
println!(" cargo test --test smoke");
println!();
println!("The test boots `cargo run`, probes the bound HTTP port, and");
println!("asserts /admin/ → 302 /admin/login. Edit it as your project grows.");
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn smoke_template_is_a_valid_rust_test_skeleton() {
assert!(
SMOKE_TEMPLATE.contains("#[test]"),
"smoke template missing #[test] attribute"
);
assert!(
SMOKE_TEMPLATE.contains("fn admin_root_redirects_to_login"),
"smoke template missing the expected test fn"
);
}
#[test]
fn run_refuses_to_clobber_without_force() {
let dir = tempdir();
let nested = dir.join("tests");
fs::create_dir_all(&nested).unwrap();
fs::write(nested.join("smoke.rs"), "existing").unwrap();
let err =
run(false, dir.join("tests").to_str().unwrap()).expect_err("must refuse to clobber");
assert!(
err.contains("already exists"),
"expected clobber-refusal, got: {err}"
);
let content = fs::read_to_string(nested.join("smoke.rs")).unwrap();
assert_eq!(content, "existing");
}
#[test]
fn run_writes_smoke_rs_to_default_out_under_force() {
let dir = tempdir();
let out = dir.join("custom_tests");
run(true, out.to_str().unwrap()).expect("should write");
let written = fs::read_to_string(out.join("smoke.rs")).expect("smoke.rs must exist");
assert!(written.contains("#[test]"));
}
fn tempdir() -> PathBuf {
use std::sync::atomic::{AtomicU64, Ordering};
static COUNTER: AtomicU64 = AtomicU64::new(0);
let n = COUNTER.fetch_add(1, Ordering::Relaxed);
let pid = std::process::id();
let dir = std::env::temp_dir().join(format!("rustio-test-init-{pid}-{n}"));
fs::create_dir_all(&dir).unwrap();
dir
}
}