use std::env::temp_dir; use std::fs::{create_dir_all, read_to_string, remove_dir_all, File}; use std::io::Write; use std::path::{Path, PathBuf}; use std::process::{id, Command, Stdio}; use std::time::{SystemTime, UNIX_EPOCH}; pub fn setup_test_dir() -> PathBuf { let timestamp = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() .as_nanos(); let process_id = id(); let random = random_string(); let test_dir = temp_dir().join(format!("blog_test_{timestamp}_{process_id}_{random}")); create_dir_all(&test_dir) .expect("Could not create test directory"); test_dir } pub fn cleanup_test_dir(test_dir: &PathBuf) { if test_dir.exists() { remove_dir_all(test_dir).unwrap(); } } pub fn create_test_file(path: &PathBuf, content: &str) { let mut file = File::create(path).unwrap(); file.write_all(content.as_bytes()).unwrap(); } pub fn assert_file_contents(path: &PathBuf, expected: &str) { let content = read_to_string(path).unwrap(); assert_eq!(content.trim(), expected.trim()); } pub fn assert_file_contains(path: &PathBuf, expected: &str) { let content = read_to_string(path).unwrap(); assert!(content.contains(expected)); } pub fn assert_file_does_not_contain(path: &PathBuf, expected: &str) { let content = read_to_string(path).unwrap(); assert!(!content.contains(expected)); } pub fn create_remote(path: &Path) { Command::new("git") .current_dir(&path) .args(["init", "--bare", "-b", "main"]) .stdout(Stdio::null()) .stderr(Stdio::null()) .status() .expect("Failed to initialize bare repository"); } pub fn assert_file_in_repo_does_not_exist(repo_path: &str, file_path: &str) { let output = Command::new("git") .current_dir(&repo_path) .args(["show", &format!("main:{file_path}")]) .stderr(Stdio::null()) .output() .expect("Failed to read from repo"); assert!(output.status.code().unwrap() != 0); } pub fn assert_file_in_repo_with_contents(repo_path: &str, file_path: &str, contents: &str) { let output = Command::new("git") .current_dir(&repo_path) .args(["show", &format!("main:{file_path}")]) .stderr(Stdio::null()) .output() .expect("Failed to read from repo"); assert!(String::from_utf8(output.stdout) .map(|file| file.trim() == contents) .unwrap_or(false)); } pub fn commit_file_to_remote(repo_path: &str, file_path: &str, contents: &str) { let test_dir = setup_test_dir(); Command::new("git") .current_dir(&test_dir) .args(["clone", &repo_path, "."]) .stdout(Stdio::null()) .stderr(Stdio::null()) .status() .expect("Failed to clone repo"); create_test_file(&test_dir.join(file_path), contents); Command::new("git") .current_dir(&test_dir) .args(["add", file_path]) .stdout(Stdio::null()) .stderr(Stdio::null()) .status() .expect("Failed to add file to repo"); Command::new("git") .current_dir(&test_dir) .args(["-c", "user.name=test", "-c", "user.email=test@example.com", "commit", "-m", "test commit"]) .stdout(Stdio::null()) .stderr(Stdio::null()) .status() .expect("Failed to commit file to repo"); Command::new("git") .current_dir(&test_dir) .args(["push", "origin", "main"]) .stdout(Stdio::null()) .stderr(Stdio::null()) .status() .expect("Failed to push repo"); cleanup_test_dir(&test_dir); } fn random_string() -> String { let x = Box::new(0); format!("{:p}", x) }