use crate::error::RenderError;
use crate::registry::Registry;
use serde::Serialize;
pub trait TestHandlebars {
fn register(&mut self, name: &str, template: &str);
fn assert_render_template<T: Serialize>(&self, template: &str, data: &T, expected: &str);
fn assert_render<T: Serialize>(&self, name: &str, data: &T, expected: &str);
fn assert_render_template_ok<T: Serialize>(&self, template: &str, data: &T);
fn assert_render_template_err<T: Serialize>(
&self,
template: &str,
data: &T,
msg: Option<&str>,
) -> RenderError;
fn assert_render_err<T: Serialize>(
&self,
name: &str,
data: &T,
msg: Option<&str>,
) -> RenderError;
}
impl<'reg> TestHandlebars for Registry<'reg> {
fn register(&mut self, name: &str, template: &str) {
if let Err(e) = self.register_template_string(name, template) {
panic!("failed to register template {name:?} ({template:?}):\n{e}");
}
}
fn assert_render_template<T: Serialize>(&self, template: &str, data: &T, expected: &str) {
let actual = self.render_template(template, data).unwrap_or_else(|e| {
panic!("render_template failed:\n template: {template:?}\n error: {e}")
});
assert_eq!(
actual,
expected,
"\nrender_template mismatch\n template: {template:?}\n data: {}\n",
data_to_string(data)
);
}
fn assert_render<T: Serialize>(&self, name: &str, data: &T, expected: &str) {
let actual = self
.render(name, data)
.unwrap_or_else(|e| panic!("render({name:?}) failed:\n error: {e}"));
assert_eq!(
actual,
expected,
"\nrender({name:?}) mismatch\n data: {}\n",
data_to_string(data)
);
}
fn assert_render_template_ok<T: Serialize>(&self, template: &str, data: &T) {
if let Err(e) = self.render_template(template, data) {
panic!(
"expected render_template to succeed, but it errored:\n template: {template:?}\n error: {e}"
);
}
}
fn assert_render_template_err<T: Serialize>(
&self,
template: &str,
data: &T,
msg: Option<&str>,
) -> RenderError {
match self.render_template(template, data) {
Ok(actual) => panic!(
"expected render_template to fail, but it produced:\n template: {template:?}\n output: {actual:?}"
),
Err(e) => {
if let Some(needle) = msg {
let s = e.to_string();
assert!(
s.contains(needle),
"render_template failed as expected, but the error did not contain \
{needle:?}:\n {s}"
);
}
e
}
}
}
fn assert_render_err<T: Serialize>(
&self,
name: &str,
data: &T,
msg: Option<&str>,
) -> RenderError {
match self.render(name, data) {
Ok(actual) => {
panic!("expected render({name:?}) to fail, but it produced:\n output: {actual:?}")
}
Err(e) => {
if let Some(needle) = msg {
let s = e.to_string();
assert!(
s.contains(needle),
"render({name:?}) failed as expected, but the error did not contain \
{needle:?}:\n {s}"
);
}
e
}
}
}
}
fn data_to_string<T: Serialize>(data: &T) -> String {
serde_json::to_string(data).unwrap_or_else(|_| "<non-serializable>".to_owned())
}