use crate::constants::CONFIG_FILE_NAME;
use rstest::fixture;
use std::fs;
use std::path::PathBuf;
use tempfile::TempDir;
pub struct TempScrapProject {
#[expect(dead_code, reason = "held only so the directory is removed on drop")]
temp_dir: TempDir,
pub scraps_dir: PathBuf,
pub static_dir: PathBuf,
pub output_dir: PathBuf,
pub project_root: PathBuf,
}
impl TempScrapProject {
pub fn new() -> Self {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let project_root = temp_dir.path().to_path_buf();
let scraps_dir = project_root.clone();
let static_dir = project_root.join("static");
let output_dir = project_root.join("_site");
fs::create_dir_all(&static_dir).expect("Failed to create static dir");
fs::create_dir_all(&output_dir).expect("Failed to create output dir");
Self {
temp_dir,
scraps_dir,
static_dir,
output_dir,
project_root,
}
}
pub fn add_scrap(&self, filename: &str, content: &[u8]) -> &Self {
let path = self.project_root.join(filename);
if let Some(parent) = path.parent() {
fs::create_dir_all(parent).expect("Failed to create parent dir");
}
fs::write(&path, content).expect("Failed to write scrap file");
self
}
pub fn add_scrap_with_context(&self, context: &str, filename: &str, content: &[u8]) -> &Self {
let context_dir = self.project_root.join(context);
fs::create_dir_all(&context_dir).expect("Failed to create context dir");
let path = context_dir.join(filename);
fs::write(&path, content).expect("Failed to write scrap file");
self
}
pub fn add_config(&self, content: &[u8]) -> &Self {
let config_path = self.project_root.join(CONFIG_FILE_NAME);
fs::write(&config_path, content).expect("Failed to write config file");
self
}
pub fn add_static_file(&self, filename: &str, content: &[u8]) -> &Self {
let path = self.static_dir.join(filename);
if let Some(parent) = path.parent() {
fs::create_dir_all(parent).expect("Failed to create parent dir");
}
fs::write(&path, content).expect("Failed to write static file");
self
}
pub fn output_path(&self, filename: &str) -> PathBuf {
self.output_dir.join(filename)
}
pub fn scrap_path(&self, filename: &str) -> PathBuf {
self.project_root.join(filename)
}
}
impl Default for TempScrapProject {
fn default() -> Self {
Self::new()
}
}
#[fixture]
pub fn temp_scrap_project() -> TempScrapProject {
TempScrapProject::new()
}
pub struct SimpleTempDir {
#[expect(dead_code, reason = "held only so the directory is removed on drop")]
temp_dir: TempDir,
pub path: PathBuf,
}
impl SimpleTempDir {
pub fn new() -> Self {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let path = temp_dir.path().to_path_buf();
Self { temp_dir, path }
}
pub fn add_file(&self, relative_path: &str, content: &[u8]) -> &Self {
let full_path = self.path.join(relative_path);
if let Some(parent) = full_path.parent() {
fs::create_dir_all(parent).expect("Failed to create parent dir");
}
fs::write(&full_path, content).expect("Failed to write file");
self
}
pub fn add_dir(&self, relative_path: &str) -> &Self {
let full_path = self.path.join(relative_path);
fs::create_dir_all(&full_path).expect("Failed to create directory");
self
}
}
impl Default for SimpleTempDir {
fn default() -> Self {
Self::new()
}
}
#[fixture]
pub fn simple_temp_dir() -> SimpleTempDir {
SimpleTempDir::new()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_temp_scrap_project_creates_directories() {
let project = TempScrapProject::new();
assert_eq!(project.scraps_dir, project.project_root);
assert!(project.static_dir.exists());
assert!(project.output_dir.exists());
assert!(project.project_root.exists());
}
#[test]
fn test_temp_scrap_project_add_scrap() {
let project = TempScrapProject::new();
project.add_scrap("test.md", b"# Test Content");
let scrap_path = project.scrap_path("test.md");
assert!(scrap_path.exists());
assert_eq!(fs::read_to_string(scrap_path).unwrap(), "# Test Content");
}
#[test]
fn test_temp_scrap_project_add_scrap_with_context() {
let project = TempScrapProject::new();
project.add_scrap_with_context("Context", "test.md", b"# Contextual");
let scrap_path = project.project_root.join("Context/test.md");
assert!(scrap_path.exists());
assert_eq!(fs::read_to_string(scrap_path).unwrap(), "# Contextual");
}
#[test]
fn test_temp_scrap_project_add_config() {
let project = TempScrapProject::new();
project.add_config(b"[ssg]\nbase_url = \"https://example.com/\"\ntitle = \"Test\"");
let config_path = project.project_root.join(CONFIG_FILE_NAME);
assert!(config_path.exists());
}
#[test]
fn test_simple_temp_dir_creates_directory() {
let temp_dir = SimpleTempDir::new();
assert!(temp_dir.path.exists());
}
#[test]
fn test_simple_temp_dir_add_file() {
let temp_dir = SimpleTempDir::new();
temp_dir.add_file("test.txt", b"content");
let file_path = temp_dir.path.join("test.txt");
assert!(file_path.exists());
assert_eq!(fs::read_to_string(file_path).unwrap(), "content");
}
#[test]
fn test_simple_temp_dir_add_dir() {
let temp_dir = SimpleTempDir::new();
temp_dir.add_dir("subdir");
let dir_path = temp_dir.path.join("subdir");
assert!(dir_path.exists());
assert!(dir_path.is_dir());
}
#[test]
fn test_cleanup_on_drop() {
let path = {
let temp_dir = SimpleTempDir::new();
temp_dir.add_file("test.txt", b"content");
temp_dir.path.clone()
};
assert!(!path.exists());
}
}