]> git.r.bdr.sh - rbdr/blog/blobdiff - src/generator/rss.rs
Add tests for generators
[rbdr/blog] / src / generator / rss.rs
index 5ed9f5c3a05867f4f606eebfb128ac04fc755651..c4b8bdb01090fb65527f3a60ca0cd3544d179bdd 100644 (file)
-use std::io::Result;
-use std::path::PathBuf;
-use crate::template::{find, parse, TemplateContext};
-
-pub fn generate(_: &PathBuf, template_directory: &PathBuf, _: &PathBuf, context: &TemplateContext) -> Result<()> {
-    match find(template_directory, "feed.xml") {
-        Some(template) => {
-            let parsed_template = parse(&template);
-            println!("TOKEN {}", parsed_template.render(context));
-        },
-        None => {}
+use crate::template::{find, parse, Context};
+use std::fs::write;
+use std::io::{Error, ErrorKind::Other, Result};
+use std::path::Path;
+
+const FILENAME: &str = "feed.xml";
+
+pub fn generate(
+    _: &Path,
+    template_directory: &Path,
+    target: &Path,
+    context: &Context,
+) -> Result<()> {
+    if let Some(template) = find(template_directory, FILENAME) {
+        let parsed_template =
+            parse(&template).ok_or_else(|| Error::new(Other, "Unable to parse RSS 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_rss_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([
+                        ("id".to_string(), Value::String("123".to_string())),
+                        (
+                            "created_on_utc".to_string(),
+                            Value::String("Last Saturday".to_string()),
+                        ),
+                        (
+                            "title".to_string(),
+                            Value::String("Big words I know.".to_string()),
+                        ),
+                        (
+                            "escaped_html".to_string(),
+                            Value::String("<p>Contextualization</p>".to_string()),
+                        ),
+                    ]),
+                    HashMap::from([
+                        ("id".to_string(), Value::String("456".to_string())),
+                        (
+                            "created_on_utc".to_string(),
+                            Value::String("This Saturday".to_string()),
+                        ),
+                        (
+                            "title".to_string(),
+                            Value::String("Big words I don't know.".to_string()),
+                        ),
+                        (
+                            "escaped_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("feed.xml"), "<p>Contextualization</p>");
+        assert_file_contains(&output_dir.join("feed.xml"), "<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("feed.xml"),
+            "\
+{{~ 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("feed.xml"),
+            "\
+<p>Recontextualization</p>
+
+    <p>Recontexternalization</p>
+",
+        );
+    }
+
+    #[test]
+    fn test_fails_if_rss_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("feed.xml"),
+            "\
+{{~ 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("feed.xml"),
+            "\
+{{~ 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());
+    }
+}