]> git.r.bdr.sh - rbdr/blog/blob - src/generator/html.rs
Address more of the formatter comments
[rbdr/blog] / src / generator / html.rs
1 use crate::template::{find, parse, Context};
2 use std::fs::write;
3 use std::io::{Error, ErrorKind::Other, Result};
4 use std::path::Path;
5
6 const FILENAME: &str = "index.html";
7
8 pub fn generate(
9 _: &Path,
10 template_directory: &Path,
11 target: &Path,
12 context: &Context,
13 ) -> Result<()> {
14 if let Some(template) = find(template_directory, FILENAME) {
15 let parsed_template =
16 parse(&template).ok_or_else(|| Error::new(Other, "Unable to parse HTML template"))?;
17 let rendered_template = parsed_template.render(context)?;
18 let location = target.join(FILENAME);
19 write(location, rendered_template)?;
20 }
21 Ok(())
22 }
23
24 #[cfg(test)]
25 mod tests {
26 use std::collections::HashMap;
27 use std::fs::create_dir_all;
28
29 use super::*;
30
31 use crate::template::Value;
32
33 use test_utilities::*;
34
35 #[test]
36 fn test_generates_html_with_default_layout() {
37 let test_dir = setup_test_dir();
38 let static_dir = test_dir.join("static");
39 let template_dir = test_dir.join("templates");
40 let output_dir = test_dir.join("output");
41
42 create_dir_all(&static_dir).expect("Could not create static directory");
43 create_dir_all(&template_dir).expect("Could not create template directory");
44 create_dir_all(&output_dir).expect("Could not create output directory");
45
46 let context = HashMap::from([
47 ("has_posts".to_string(), Value::Bool(true)),
48 (
49 "posts".to_string(),
50 Value::Collection(vec![
51 HashMap::from([
52 ("index".to_string(), Value::Unsigned(2828)),
53 (
54 "html".to_string(),
55 Value::String("<p>Contextualization</p>".to_string()),
56 ),
57 ]),
58 HashMap::from([
59 ("index".to_string(), Value::Unsigned(2828)),
60 (
61 "html".to_string(),
62 Value::String("<p>Contexternalization</p>".to_string()),
63 ),
64 ]),
65 ]),
66 ),
67 ]);
68
69 generate(&static_dir, &template_dir, &output_dir, &context).expect("Generate failed");
70
71 assert_file_contains(&output_dir.join("index.html"), "<p>Contextualization</p>");
72 assert_file_contains(&output_dir.join("index.html"), "<p>Contexternalization</p>");
73 }
74
75 #[test]
76 fn test_uses_custom_layout_if_available() {
77 let test_dir = setup_test_dir();
78 let static_dir = test_dir.join("static");
79 let template_dir = test_dir.join("templates");
80 let output_dir = test_dir.join("output");
81
82 create_dir_all(&static_dir).expect("Could not create static directory");
83 create_dir_all(&template_dir).expect("Could not create template directory");
84 create_dir_all(&output_dir).expect("Could not create output directory");
85 create_test_file(
86 &template_dir.join("index.html"),
87 "\
88 {{~ posts:post }}
89 {{= post.html }}
90 {{~}}
91 ",
92 );
93 let context = HashMap::from([(
94 "posts".to_string(),
95 Value::Collection(vec![
96 HashMap::from([(
97 "html".to_string(),
98 Value::String("<p>Recontextualization</p>".to_string()),
99 )]),
100 HashMap::from([(
101 "html".to_string(),
102 Value::String("<p>Recontexternalization</p>".to_string()),
103 )]),
104 ]),
105 )]);
106
107 generate(&static_dir, &template_dir, &output_dir, &context).expect("Generate failed");
108
109 assert_file_contents(
110 &output_dir.join("index.html"),
111 "\
112 <p>Recontextualization</p>
113
114 <p>Recontexternalization</p>
115 ",
116 );
117 }
118
119 #[test]
120 fn test_fails_if_html_is_malformed() {
121 let test_dir = setup_test_dir();
122 let static_dir = test_dir.join("static");
123 let template_dir = test_dir.join("templates");
124 let output_dir = test_dir.join("output");
125
126 create_dir_all(&static_dir).expect("Could not create static directory");
127 create_dir_all(&template_dir).expect("Could not create template directory");
128 create_dir_all(&output_dir).expect("Could not create output directory");
129 create_test_file(
130 &template_dir.join("index.html"),
131 "\
132 {{~ posts:post }}
133 {{ post.html }}
134 {{~}}
135 ",
136 );
137 let context = HashMap::new();
138
139 let result = generate(&static_dir, &template_dir, &output_dir, &context);
140
141 assert!(result.is_err());
142 }
143
144 #[test]
145 fn test_fails_if_output_is_not_writable() {
146 let test_dir = setup_test_dir();
147 let static_dir = test_dir.join("static");
148 let template_dir = test_dir.join("templates");
149 let output_dir = test_dir.join("output");
150
151 create_dir_all(&template_dir).expect("Could not create template directory");
152 create_test_file(
153 &template_dir.join("index.html"),
154 "\
155 {{~ posts:post }}
156 {{= post.html }}
157 {{~}}
158 ",
159 );
160 let context = HashMap::from([(
161 "posts".to_string(),
162 Value::Collection(vec![
163 HashMap::from([(
164 "html".to_string(),
165 Value::String("<p>Recontextualization</p>".to_string()),
166 )]),
167 HashMap::from([(
168 "html".to_string(),
169 Value::String("<p>Recontexternalization</p>".to_string()),
170 )]),
171 ]),
172 )]);
173
174 let result = generate(&static_dir, &template_dir, &output_dir, &context);
175
176 assert!(result.is_err());
177 }
178 }