From: Ruben Beltran del Rio Date: Fri, 3 Jan 2025 22:17:06 +0000 (+0100) Subject: Update main and file_finder tests X-Git-Tag: 1.4.0~13 X-Git-Url: https://git.r.bdr.sh/rbdr/page/commitdiff_plain/1c5797fadeea6be505c01f13508203ba234cbdfa Update main and file_finder tests --- diff --git a/.gitignore b/.gitignore index 0e05966..687cf4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,4 @@ /target -tests/fixtures/empty -tests/fixtures/output -tests/fixtures/output_gemini -tests/fixtures/output_html .DS_Store *.tar.gz diff --git a/Cargo.lock b/Cargo.lock index bafb58c..7e1370b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,7 +1,14 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "page" -version = "1.3.2" +version = "1.4.0" +dependencies = [ + "test_utilities", +] + +[[package]] +name = "test_utilities" +version = "1.4.0" diff --git a/Cargo.toml b/Cargo.toml index 5c0f2f3..31709bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "page" -version = "1.3.2" +version = "1.4.0" edition = "2021" license = "AGPL-3.0-or-later" description = "Command line tool to generate a static website and gemini capsule from a directory with gemtext." @@ -9,6 +9,9 @@ authors = ["Rubén Beltrán del Río "] [dependencies] +[dev-dependencies] +test_utilities = { path = "test_utilities" } + [profile.release] strip = true lto = true diff --git a/src/file_finder.rs b/src/file_finder.rs index a94aa8a..43eee33 100644 --- a/src/file_finder.rs +++ b/src/file_finder.rs @@ -32,26 +32,44 @@ fn find_files_recursively(root_path: &PathBuf, directory_path: &PathBuf) -> Vec< #[cfg(test)] mod tests { - use super::*; - use crate::file_handler::FileType; use std::collections::HashSet; + use std::path::PathBuf; use std::fs::create_dir_all; - fn fixtures_dir() -> PathBuf { - PathBuf::from("tests/fixtures") - } + use super::*; - fn get_paths(files: &Vec) -> HashSet { + use crate::file_handler::FileType; + use crate::file_handler::File; + use test_utilities::*; + + fn get_paths(root_directory: &PathBuf, files: &Vec) -> HashSet { files .iter() - .map(|f| f.path.strip_prefix(&fixtures_dir()).unwrap().to_string_lossy().to_string()) + .map( |file| + file.path + .strip_prefix(root_directory) + .unwrap() + .to_string_lossy() + .to_string() + ) .collect() } #[test] fn finds_all_files() { - let files = find_files(&fixtures_dir()); - let paths = get_paths(&files); + let test_dir = setup_test_dir(); + create_dir_all(&test_dir.join("nested")) + .expect("Could not create nested test directory"); + create_dir_all(&test_dir.join("assets")) + .expect("Could not create assets test directory"); + create_test_file(&test_dir.join("test1.gmi"), ""); + create_test_file(&test_dir.join("_layout.html"), ""); + create_test_file(&test_dir.join("nested/nested.gmi"), ""); + create_test_file(&test_dir.join("assets/style.css"), ""); + create_test_file(&test_dir.join("image.png"), ""); + + let files = find_files(&test_dir); + let paths = get_paths(&test_dir, &files); assert!(paths.contains("test1.gmi")); assert!(paths.contains("_layout.html")); @@ -62,7 +80,16 @@ mod tests { #[test] fn identifies_correct_file_types() { - let files = find_files(&fixtures_dir()); + let test_dir = setup_test_dir(); + create_dir_all(&test_dir.join("nested")) + .expect("Could not create nested test directory"); + create_dir_all(&test_dir.join("assets")) + .expect("Could not create assets test directory"); + create_test_file(&test_dir.join("_layout.html"), ""); + create_test_file(&test_dir.join("nested/nested.gmi"), ""); + create_test_file(&test_dir.join("assets/style.css"), ""); + create_test_file(&test_dir.join("image.png"), ""); + let files = find_files(&test_dir); for file in files { let extension = file.path.extension().and_then(|e| e.to_str()); @@ -82,35 +109,30 @@ mod tests { #[test] fn ignores_git_directory() { - let files = find_files(&fixtures_dir()); - let paths = get_paths(&files); + let test_dir = setup_test_dir(); + create_dir_all(&test_dir.join("nested")) + .expect("Could not create nested test directory"); + create_dir_all(&test_dir.join("assets")) + .expect("Could not create assets test directory"); + create_dir_all(&test_dir.join(".git")) + .expect("Could not create git test directory"); + create_test_file(&test_dir.join("_layout.html"), ""); + create_test_file(&test_dir.join("nested/nested.gmi"), ""); + create_test_file(&test_dir.join("assets/style.css"), ""); + create_test_file(&test_dir.join("image.png"), ""); + create_test_file(&test_dir.join(".git/config"), ""); + let files = find_files(&test_dir); + + let paths = get_paths(&test_dir, &files); - // These files should exist in the fixtures but not be included assert!(!paths.iter().any(|p| p.starts_with(".git/"))); assert!(!paths.contains(".gitignore")); } - #[test] - fn handles_nested_directories() { - let files = find_files(&fixtures_dir()); - let paths = get_paths(&files); - - // Check that files in nested directories are found - assert!(paths.contains("nested/nested.gmi")); - assert!(paths.contains("assets/style.css")); - - // Verify directory structure is preserved in paths - let nested_files: Vec<_> = files.iter() - .filter(|f| f.path.starts_with(fixtures_dir().join("nested"))) - .collect(); - assert!(!nested_files.is_empty()); - } - #[test] fn returns_empty_for_empty_directory() { - let empty_dir = fixtures_dir().join("empty"); - let _ = create_dir_all(&empty_dir); - let files = find_files(&empty_dir); + let test_dir = setup_test_dir(); + let files = find_files(&test_dir); assert!(files.is_empty()); } } diff --git a/src/main.rs b/src/main.rs index 533a6bb..902f3c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,17 +23,7 @@ fn main() -> Result<()> { // Step 1. Identify the files let files = find_files(&source); - // Step 2. Prepare the target priority - match remove_dir_all(&html_destination) { - _ => {} - }; - create_dir_all(&html_destination)?; - match remove_dir_all(&gemini_destination) { - _ => {} - }; - create_dir_all(&gemini_destination)?; - - // Step 3. Load the layout + // Step 2. Load the layout let mut file_handler = FileHandler::default(); match file_handler.get_layout_or_panic(&files) { Ok(_) => {}, @@ -43,6 +33,19 @@ fn main() -> Result<()> { } } + // Step 3. Prepare the target priority + match remove_dir_all(&html_destination) { + _ => {} + }; + match remove_dir_all(&gemini_destination) { + _ => {} + }; + + create_dir_all(&html_destination) + .expect("Could not create HTML directory."); + create_dir_all(&gemini_destination) + .expect("Could not create Gemini directory."); + // Step 4. Process all files file_handler.handle_all(&source, &html_destination, &gemini_destination, &files); Ok(()) diff --git a/test_utilities/Cargo.toml b/test_utilities/Cargo.toml new file mode 100644 index 0000000..c8a753f --- /dev/null +++ b/test_utilities/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "test_utilities" +version = "1.4.0" +edition = "2021" +license = "AGPL-3.0-or-later" +description = "Shared test utilities for page" +homepage = "https://r.bdr.sh/page.html" +authors = ["Rubén Beltrán del Río "] + +[dependencies] diff --git a/test_utilities/src/lib.rs b/test_utilities/src/lib.rs new file mode 100644 index 0000000..cb69853 --- /dev/null +++ b/test_utilities/src/lib.rs @@ -0,0 +1,34 @@ +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::PathBuf; +use std::time::{SystemTime, UNIX_EPOCH}; +use std::process::id; + +pub fn setup_test_dir() -> PathBuf { + let timestamp = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_nanos(); + let process_id = id(); + let test_dir = temp_dir().join(format!("page_test_{}_{}", timestamp, process_id)); + 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()); +} diff --git a/tests/cli_test.rs b/tests/cli_test.rs new file mode 100644 index 0000000..0bb46bb --- /dev/null +++ b/tests/cli_test.rs @@ -0,0 +1,113 @@ +use std::env; +use std::fs::read_to_string; +use std::path::PathBuf; +use std::process::Command; +use test_utilities::*; + +struct TestDir { + paths: Vec, +} + +impl Drop for TestDir { + fn drop(&mut self) { + for path in &self.paths { + cleanup_test_dir(path); + } + } +} + +#[test] +fn test_basic_generation() { + let test_dir = setup_test_dir(); + let dir_name = test_dir.file_name().unwrap().to_string_lossy(); + let parent = test_dir.parent().unwrap(); + let html_dir = parent.join(format!("{}_html", dir_name)); + let gemini_dir = parent.join(format!("{}_gemini", dir_name)); + + let _cleanup = TestDir { + paths: vec![test_dir.clone(), html_dir.clone(), gemini_dir.clone()] + }; + + // Create test input files + create_test_file(&test_dir.join("_layout.html"), "\ + +{{ title }} +{{ content }} + +"); + create_test_file(&test_dir.join("test.gmi"), "\ +--- title: Page Is Cool! +# Test +Hello world +"); + create_test_file(&test_dir.join("test.png"), "A picture of a cute cat"); + + // Run the program from the test directory + let status = Command::new(env!("CARGO_BIN_EXE_page")) + .current_dir(&test_dir) + .status() + .expect("Failed to execute command"); + + assert!(status.success()); + + assert!(html_dir.exists()); + assert!(gemini_dir.exists()); + + let html_output = html_dir.join("test.html"); + assert_file_contents(&html_output, "\ + +Page Is Cool! +
+

Test

+

Hello world

+
+ + +"); + + let html_asset_output = html_dir.join("test.png"); + assert_file_contents(&html_asset_output, "A picture of a cute cat"); + + let gemini_output = gemini_dir.join("test.gmi"); + assert_file_contents(&gemini_output, "\ +# Test +Hello world +"); + + let gemini_asset_output = gemini_dir.join("test.png"); + assert!(gemini_asset_output.exists()); + let gemini_asset_content = read_to_string(gemini_asset_output).unwrap(); + assert_eq!(gemini_asset_content, "A picture of a cute cat"); +} + +#[test] +fn test_missing_layout() { + let test_dir = setup_test_dir(); + let dir_name = test_dir.file_name().unwrap().to_string_lossy(); + let parent = test_dir.parent().unwrap(); + let html_dir = parent.join(format!("{}_html", dir_name)); + let gemini_dir = parent.join(format!("{}_gemini", dir_name)); + + let _cleanup = TestDir { + paths: vec![test_dir.clone(), html_dir.clone(), gemini_dir.clone()] + }; + + // Create test input files + create_test_file(&test_dir.join("test.gmi"), "\ +--- title: Page Is Cool! +# Test +Hello world +"); + create_test_file(&test_dir.join("test.png"), "A picture of a cute cat"); + + // Run the program from the test directory + let status = Command::new(env!("CARGO_BIN_EXE_page")) + .current_dir(&test_dir) + .status() + .expect("Failed to execute command"); + + assert!(!status.success()); + + assert!(!html_dir.exists()); + assert!(!gemini_dir.exists()); +}