]> git.r.bdr.sh - rbdr/page/blobdiff - src/file_handler/mod.rs
Update file handler mod tests
[rbdr/page] / src / file_handler / mod.rs
index 4932ef17f567f70066e8ce480fd03b6ec1afc81a..cefe6a20b374072dd735e4be19922fb2f7cfc8ba 100644 (file)
@@ -35,7 +35,7 @@ impl FileHandler {
         FileType::Unknown
     }
 
-    pub fn get_layout_or_panic(&mut self, files: &Vec<File>) -> Result<(), &str> {
+    pub fn get_layout_or_panic(&mut self, files: &[File]) -> Result<(), &str> {
         for file in files {
             match file.file_type {
                 FileType::Layout => {
@@ -49,18 +49,22 @@ impl FileHandler {
         Err("No layout found. Please ensure there's a _layout.html file at the root")
     }
 
-    pub fn handle_all(&self, source: &PathBuf, destination: &PathBuf, files: &Vec<File>) {
-        for file in files {
-            self.handle(source, destination, file);
-        }
+    pub fn handle_all(&self, source: &PathBuf, html_destination: &PathBuf, gemini_destination: &PathBuf, files: &[File]) {
+        files.iter().for_each(|file| {
+            self.handle(source, html_destination, gemini_destination, file);
+        });
     }
 
-    pub fn handle(&self, source: &PathBuf, destination: &PathBuf, file: &File) {
-        for strategy in self.strategies.iter() {
-            if strategy.can_handle(&file.file_type) {
-                let layout = self.layout.as_ref().unwrap();
-                return strategy.handle(source, destination, file, layout);
-            }
+    pub fn handle(&self, source: &PathBuf, html_destination: &PathBuf, gemini_destination: &PathBuf, file: &File) {
+        if let Some(strategy) = self.strategies
+            .iter()
+            .find(|s| s.can_handle(&file.file_type)) 
+        {
+                let layout = self.layout.as_ref()
+                    .expect("Layout should be initialized before handling files");
+                strategy.handle_html(source, html_destination, file, layout);
+                strategy.handle_gemini(source, gemini_destination, file);
+                return;
         }
     }
 }
@@ -69,9 +73,11 @@ pub trait FileHandlerStrategy {
     fn is(&self, path: &PathBuf) -> bool;
     fn identify(&self) -> FileType;
     fn can_handle(&self, file_type: &FileType) -> bool;
-    fn handle(&self, source: &PathBuf, destination: &PathBuf, file: &File, layout: &String);
+    fn handle_html(&self, source: &PathBuf, destination: &PathBuf, file: &File, layout: &str);
+    fn handle_gemini(&self, source: &PathBuf, destination: &PathBuf, file: &File);
 }
 
+#[derive(Debug, Clone, PartialEq)]
 pub enum FileType {
     Gemini,
     File,
@@ -79,7 +85,188 @@ pub enum FileType {
     Unknown,
 }
 
+#[derive(PartialEq, Debug)]
 pub struct File {
     pub path: PathBuf,
     pub file_type: FileType,
 }
+
+
+#[cfg(test)]
+mod tests {
+    use std::path::PathBuf;
+
+    use super::*;
+
+    use test_utilities::*;
+
+    fn create_test_internal_file(path: &str, file_type: FileType) -> File {
+        File {
+            path: PathBuf::from(path),
+            file_type,
+        }
+    }
+
+    #[test]
+    fn test_identify_gemini_file() {
+        let handler = FileHandler::default();
+        let path = PathBuf::from("test.gmi");
+        assert!(matches!(handler.identify(&path), FileType::Gemini));
+    }
+
+    #[test]
+    fn test_identify_layout_file() {
+        let handler = FileHandler::default();
+        let path = PathBuf::from("_layout.html");
+        assert!(matches!(handler.identify(&path), FileType::Layout));
+    }
+
+    #[test]
+    fn test_identify_regular_file() {
+        let handler = FileHandler::default();
+        let path = PathBuf::from("regular.html");
+        assert!(matches!(handler.identify(&path), FileType::File));
+    }
+
+    #[test]
+    fn test_identify_unknown_file() {
+        let handler = FileHandler::default();
+        let path = PathBuf::from("tests");
+        assert!(matches!(handler.identify(&path), FileType::Unknown));
+    }
+
+    #[test]
+    fn test_get_layout_success() {
+        let test_dir = setup_test_dir();
+        let layout_path = test_dir.join("_layout.html");
+        create_test_file(&layout_path, "");
+
+        let mut handler = FileHandler::default();
+        let files = vec![
+            create_test_internal_file("test.gmi", FileType::Gemini),
+            create_test_internal_file(&layout_path.to_str().expect("Could not encode layout"), FileType::Layout),
+            create_test_internal_file("regular.html", FileType::File),
+        ];
+
+        assert!(handler.get_layout_or_panic(&files).is_ok());
+    }
+
+    #[test]
+    fn test_get_layout_failure() {
+        let mut handler = FileHandler::default();
+        let files = vec![
+            create_test_internal_file("test.gmi", FileType::Gemini),
+            create_test_internal_file("regular.html", FileType::File),
+        ];
+
+        assert!(handler.get_layout_or_panic(&files).is_err());
+    }
+
+    // Mock strategy for testing
+    struct MockStrategy {
+        is_match: bool,
+        file_type: FileType,
+    }
+
+    impl FileHandlerStrategy for MockStrategy {
+        fn is(&self, _path: &PathBuf) -> bool {
+            self.is_match
+        }
+
+        fn identify(&self) -> FileType {
+            self.file_type.clone()
+        }
+
+        fn can_handle(&self, file_type: &FileType) -> bool {
+            &self.file_type == file_type
+        }
+
+        fn handle_html(&self, _source: &PathBuf, _destination: &PathBuf, _file: &File, _layout: &str) {}
+        fn handle_gemini(&self, _source: &PathBuf, _destination: &PathBuf, _file: &File) {}
+    }
+
+    #[test]
+    fn test_custom_strategy() {
+        let mock_strategy = MockStrategy {
+            is_match: true,
+            file_type: FileType::Gemini,
+        };
+
+        let handler = FileHandler {
+            strategies: vec![Box::new(mock_strategy)],
+            layout: None,
+        };
+
+        let path = PathBuf::from("test.whatever");
+        assert!(matches!(handler.identify(&path), FileType::Gemini));
+    }
+
+    #[test]
+    fn test_handle_all_empty_files() {
+        let handler = FileHandler::default();
+        let files: Vec<File> = vec![];
+
+        // Should not panic with empty vector
+        handler.handle_all(
+            &PathBuf::from("source"),
+            &PathBuf::from("tests/fixtures/output"),
+            &PathBuf::from("tests/fixtures/output"),
+            &files
+        );
+    }
+
+    #[test]
+    fn test_handle_with_layout() {
+        let mut handler = FileHandler::default();
+        handler.layout = Some("test layout".to_string());
+
+        let file = create_test_internal_file("tests/fixtures/test1.gmi", FileType::Gemini);
+
+        // Should not panic with valid layout
+        handler.handle(
+            &PathBuf::from(""),
+            &PathBuf::from("tests/fixtures/output"),
+            &PathBuf::from("tests/fixtures/output"),
+            &file
+        );
+    }
+
+    #[test]
+    #[should_panic(expected = "Layout should be initialized before handling files")]
+    fn test_handle_without_layout() {
+        let handler = FileHandler::default();
+        let file = create_test_internal_file("test.gmi", FileType::Gemini);
+
+        handler.handle(
+            &PathBuf::from("source"),
+            &PathBuf::from("tests/fixtures/output"),
+            &PathBuf::from("tests/fixtures/output"),
+            &file
+        );
+    }
+
+    #[test]
+    fn test_slice_handling() {
+        let test_dir = setup_test_dir();
+        let layout_path = test_dir.join("_layout.html");
+        create_test_file(&layout_path, "");
+
+        let mut handler = FileHandler::default();
+        let files = vec![
+            create_test_internal_file("tests/fixtures/test1.gmi", FileType::Gemini),
+            create_test_internal_file(&layout_path.to_str().expect("Could not encode layout"), FileType::Layout),
+            create_test_internal_file("tests/fixtures/test2.gmi", FileType::Gemini),
+            create_test_internal_file("tests/fixtures/test3.gmi", FileType::Gemini),
+        ];
+
+        let _ = handler.get_layout_or_panic(&files[1..]);
+
+        // Test with slice
+        handler.handle_all(
+            &PathBuf::from(""),
+            &PathBuf::from("tests/fixtures/output"),
+            &PathBuf::from("tests/fixtures/output"),
+            &files[1..] // Test with slice of last three elements
+        );
+    }
+}