]> git.r.bdr.sh - rbdr/blog/blobdiff - src/generator/html.rs
Address more of the formatter comments
[rbdr/blog] / src / generator / html.rs
index 7b369444478b442d3fdbe9c9f7610b5f87c38277..7895a83ca71d35b47cf19f650ec56befb8ed1c20 100644 (file)
-use crate::template::{find, parse, TemplateContext};
+use crate::template::{find, parse, Context};
 use std::fs::write;
 use std::io::{Error, ErrorKind::Other, Result};
-use std::path::PathBuf;
+use std::path::Path;
 
 const FILENAME: &str = "index.html";
 
 pub fn generate(
-    _: &PathBuf,
-    template_directory: &PathBuf,
-    target: &PathBuf,
-    context: &TemplateContext,
+    _: &Path,
+    template_directory: &Path,
+    target: &Path,
+    context: &Context,
 ) -> Result<()> {
-    match find(template_directory, FILENAME) {
-        Some(template) => {
-            let parsed_template = parse(&template)
-                .ok_or_else(|| Error::new(Other, "Unable to parse HTML template"))?;
-            let rendered_template = parsed_template.render(context)?;
-            let location = target.join(FILENAME);
-            write(location, rendered_template)?;
-        }
-        None => {}
+    if let Some(template) = find(template_directory, FILENAME) {
+        let parsed_template =
+            parse(&template).ok_or_else(|| Error::new(Other, "Unable to parse HTML template"))?;
+        let rendered_template = parsed_template.render(context)?;
+        let location = target.join(FILENAME);
+        write(location, rendered_template)?;
     }
     Ok(())
 }
+
+#[cfg(test)]
+mod tests {
+    use std::collections::HashMap;
+    use std::fs::create_dir_all;
+
+    use super::*;
+
+    use crate::template::Value;
+
+    use test_utilities::*;
+
+    #[test]
+    fn test_generates_html_with_default_layout() {
+        let test_dir = setup_test_dir();
+        let static_dir = test_dir.join("static");
+        let template_dir = test_dir.join("templates");
+        let output_dir = test_dir.join("output");
+
+        create_dir_all(&static_dir).expect("Could not create static directory");
+        create_dir_all(&template_dir).expect("Could not create template directory");
+        create_dir_all(&output_dir).expect("Could not create output directory");
+
+        let context = HashMap::from([
+            ("has_posts".to_string(), Value::Bool(true)),
+            (
+                "posts".to_string(),
+                Value::Collection(vec![
+                    HashMap::from([
+                        ("index".to_string(), Value::Unsigned(2828)),
+                        (
+                            "html".to_string(),
+                            Value::String("<p>Contextualization</p>".to_string()),
+                        ),
+                    ]),
+                    HashMap::from([
+                        ("index".to_string(), Value::Unsigned(2828)),
+                        (
+                            "html".to_string(),
+                            Value::String("<p>Contexternalization</p>".to_string()),
+                        ),
+                    ]),
+                ]),
+            ),
+        ]);
+
+        generate(&static_dir, &template_dir, &output_dir, &context).expect("Generate failed");
+
+        assert_file_contains(&output_dir.join("index.html"), "<p>Contextualization</p>");
+        assert_file_contains(&output_dir.join("index.html"), "<p>Contexternalization</p>");
+    }
+
+    #[test]
+    fn test_uses_custom_layout_if_available() {
+        let test_dir = setup_test_dir();
+        let static_dir = test_dir.join("static");
+        let template_dir = test_dir.join("templates");
+        let output_dir = test_dir.join("output");
+
+        create_dir_all(&static_dir).expect("Could not create static directory");
+        create_dir_all(&template_dir).expect("Could not create template directory");
+        create_dir_all(&output_dir).expect("Could not create output directory");
+        create_test_file(
+            &template_dir.join("index.html"),
+            "\
+{{~ posts:post }}
+    {{= post.html }}
+{{~}}
+",
+        );
+        let context = HashMap::from([(
+            "posts".to_string(),
+            Value::Collection(vec![
+                HashMap::from([(
+                    "html".to_string(),
+                    Value::String("<p>Recontextualization</p>".to_string()),
+                )]),
+                HashMap::from([(
+                    "html".to_string(),
+                    Value::String("<p>Recontexternalization</p>".to_string()),
+                )]),
+            ]),
+        )]);
+
+        generate(&static_dir, &template_dir, &output_dir, &context).expect("Generate failed");
+
+        assert_file_contents(
+            &output_dir.join("index.html"),
+            "\
+<p>Recontextualization</p>
+
+    <p>Recontexternalization</p>
+",
+        );
+    }
+
+    #[test]
+    fn test_fails_if_html_is_malformed() {
+        let test_dir = setup_test_dir();
+        let static_dir = test_dir.join("static");
+        let template_dir = test_dir.join("templates");
+        let output_dir = test_dir.join("output");
+
+        create_dir_all(&static_dir).expect("Could not create static directory");
+        create_dir_all(&template_dir).expect("Could not create template directory");
+        create_dir_all(&output_dir).expect("Could not create output directory");
+        create_test_file(
+            &template_dir.join("index.html"),
+            "\
+{{~ posts:post }}
+    {{ post.html }}
+{{~}}
+",
+        );
+        let context = HashMap::new();
+
+        let result = generate(&static_dir, &template_dir, &output_dir, &context);
+
+        assert!(result.is_err());
+    }
+
+    #[test]
+    fn test_fails_if_output_is_not_writable() {
+        let test_dir = setup_test_dir();
+        let static_dir = test_dir.join("static");
+        let template_dir = test_dir.join("templates");
+        let output_dir = test_dir.join("output");
+
+        create_dir_all(&template_dir).expect("Could not create template directory");
+        create_test_file(
+            &template_dir.join("index.html"),
+            "\
+{{~ posts:post }}
+    {{= post.html }}
+{{~}}
+",
+        );
+        let context = HashMap::from([(
+            "posts".to_string(),
+            Value::Collection(vec![
+                HashMap::from([(
+                    "html".to_string(),
+                    Value::String("<p>Recontextualization</p>".to_string()),
+                )]),
+                HashMap::from([(
+                    "html".to_string(),
+                    Value::String("<p>Recontexternalization</p>".to_string()),
+                )]),
+            ]),
+        )]);
+
+        let result = generate(&static_dir, &template_dir, &output_dir, &context);
+
+        assert!(result.is_err());
+    }
+}