]> git.r.bdr.sh - rbdr/page/commitdiff
Update main and file_finder tests
authorRuben Beltran del Rio <redacted>
Fri, 3 Jan 2025 22:17:06 +0000 (23:17 +0100)
committerRuben Beltran del Rio <redacted>
Fri, 3 Jan 2025 22:17:06 +0000 (23:17 +0100)
.gitignore
Cargo.lock
Cargo.toml
src/file_finder.rs
src/main.rs
test_utilities/Cargo.toml [new file with mode: 0644]
test_utilities/src/lib.rs [new file with mode: 0644]
tests/cli_test.rs [new file with mode: 0644]

index 0e05966eb7a39ac8ff7795189eed7af3393af88f..687cf4dfd54e725541ba7ecdd43edb39148bf026 100644 (file)
@@ -1,8 +1,4 @@
 /target
-tests/fixtures/empty
-tests/fixtures/output
-tests/fixtures/output_gemini
-tests/fixtures/output_html
 .DS_Store
 
 *.tar.gz
index bafb58cd33c1b5d8bcbdf2a613c9d5a1053381b9..7e1370be0b0d0871ed05eb567713ee4ee3896f40 100644 (file)
@@ -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"
index 5c0f2f36ae2524c2e89962708b3c702ff5f99e6c..31709bc05844f005a90e279609f5c38a5c4a991a 100644 (file)
@@ -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 <page@r.bdr.sh>"]
 
 [dependencies]
 
+[dev-dependencies]
+test_utilities = { path = "test_utilities" }
+
 [profile.release]
 strip = true
 lto = true
index a94aa8aea59a4763cd927fcf41c72c18f354adba..43eee33ca0233fbc2a6d60eaacb4c1cc632d7115 100644 (file)
@@ -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<File>) -> HashSet<String> {
+    use crate::file_handler::FileType;
+    use crate::file_handler::File;
+    use test_utilities::*;
+
+    fn get_paths(root_directory: &PathBuf, files: &Vec<File>) -> HashSet<String> {
         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());
     }
 }
index 533a6bb1470610d65322f7ebe01a9fbcc007a931..902f3c3a757747e08581999b0e57d1c85f5cd732 100644 (file)
@@ -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 (file)
index 0000000..c8a753f
--- /dev/null
@@ -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 <page@r.bdr.sh>"]
+
+[dependencies]
diff --git a/test_utilities/src/lib.rs b/test_utilities/src/lib.rs
new file mode 100644 (file)
index 0000000..cb69853
--- /dev/null
@@ -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 (file)
index 0000000..0bb46bb
--- /dev/null
@@ -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<PathBuf>,
+}
+
+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"), "\
+<html>
+<head><title>{{ title }}</title></head>
+<body>{{ content }}</body>
+</html>
+");
+    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, "\
+<html>
+<head><title>Page Is Cool!</title></head>
+<body><section class=\"h1\">
+<h1> Test</h1>
+<p>Hello world</p>
+</section>
+</body>
+</html>
+");
+
+    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());
+}