use pretty_assertions::assert_eq;
#[cfg(feature = "serde")]
use serde::Serialize;
use crate::{Templates, TemplatesBuilder, Value};
#[derive(Debug)]
pub struct SingleSourceTestBuilder {
path: &'static str,
source: &'static str,
}
impl SingleSourceTestBuilder {
#[must_use]
pub fn new(path: &'static str, source: &'static str) -> SingleSourceTestBuilder {
SingleSourceTestBuilder { path, source }
}
#[must_use]
pub fn parse(self) -> ParsedTemplateTestBuilder {
ParsedTemplateTestBuilder {
builder: TemplatesBuilder::new()
.with_source_file(self.path, self.source)
.expect("templates should parse correctly"),
}
}
}
#[derive(Debug)]
pub struct ParsedTemplateTestBuilder {
builder: TemplatesBuilder<'static>,
}
impl ParsedTemplateTestBuilder {
#[must_use]
pub fn build_single(self, name: &'static str) -> SingleBuiltTemplateTestBuilder {
assert!(
self.builder.template_names().len() == 1,
"Expected a single template but got {tmpls:#?} instead.",
tmpls = self.builder.template_names().collect::<Vec<_>>()
);
let tmpl = self.builder.template_names().next().unwrap();
assert_eq!(tmpl, name);
let tmpls = match self.builder.build() {
Ok(tmpls) => tmpls,
Err(err) => {
panic!("{err}")
}
};
SingleBuiltTemplateTestBuilder { name, tmpls }
}
pub fn build_multi<I: IntoIterator<Item = &'static str>>(
self,
names: I,
) -> MultiBuiltTemplateTestBuilder {
let mut expected_names: Vec<&'static str> = names.into_iter().collect();
expected_names.sort_unstable();
let mut actual_names: Vec<&'static str> = self.builder.template_names().collect();
actual_names.sort_unstable();
assert_eq!(actual_names, expected_names);
let tmpls = match self.builder.build() {
Ok(tmpls) => tmpls,
Err(err) => {
panic!("{err}")
}
};
MultiBuiltTemplateTestBuilder { tmpls }
}
}
pub struct SingleBuiltTemplateTestBuilder {
name: &'static str,
tmpls: Templates,
}
impl SingleBuiltTemplateTestBuilder {
#[must_use]
pub fn into_inner(self) -> Templates {
self.tmpls
}
pub fn render_and_expect<V: Into<Value>>(&self, arguments: V, expected: &str) {
assert_eq!(
self.tmpls
.render(self.name, arguments)
.expect("templates should render correctly"),
expected
);
}
#[cfg(feature = "serde")]
pub fn render_serde_and_expect<D: Serialize>(&self, data: D, expected: &str) {
assert_eq!(
self.tmpls
.render_serde(self.name, data)
.expect("templates should render correctly"),
expected
);
}
}
#[derive(Debug)]
pub struct MultiBuiltTemplateTestBuilder {
tmpls: Templates,
}
impl MultiBuiltTemplateTestBuilder {
#[must_use]
pub fn into_inner(self) -> Templates {
self.tmpls
}
pub fn render_and_expect<V: Into<Value>>(&self, name: &str, arguments: V, expected: &str) {
assert_eq!(
self.tmpls
.render(name, arguments)
.expect("templates should render correctly"),
expected
);
}
#[cfg(feature = "serde")]
pub fn render_serde_and_expect<D: Serialize>(&self, name: &str, data: D, expected: &str) {
assert_eq!(
self.tmpls
.render_serde(name, data)
.expect("templates should render correctly"),
expected
);
}
}
#[allow(clippy::crate_in_macro_def, non_snake_case)]
#[macro_export]
#[doc(hidden)]
macro_rules! __internal__single_source_single_template_tests {
($test_name:ident, $expected:literal, $path:literal, $proc:expr, $name:literal, $data:expr, {$($serde_types:item)*}, $serde_data:expr) => {
mod $test_name {
use cookie_cutter::*;
fn common() -> $crate::__internal__tests_util::SingleBuiltTemplateTestBuilder {
$crate::__internal__tests_util::SingleSourceTestBuilder::new($path, include_str!($path))
.parse()
.build_single($name)
}
#[test]
fn manual() {
common().render_and_expect($data, $expected);
}
#[cfg(feature = "serde")]
use serde::Serialize;
#[cfg(feature = "serde")]
$($serde_types)*
#[cfg(feature = "serde")]
#[test]
fn serde() {
common().render_serde_and_expect(
$serde_data,
$expected,
)
}
#[cfg(feature = "proc_macros")]
#[test]
fn proc_macro() {
assert_eq!(
$proc
.render($name, $data)
.unwrap(),
$expected
)
}
}
};
}
#[macro_export]
#[allow(non_snake_case)]
#[doc(hidden)]
macro_rules! __internal__single_source_single_template_no_params_tests {
($test_name:ident, $expected:literal, $path:literal, $proc:expr, $name:literal) => {
$crate::__internal__single_source_single_template_tests!(
$test_name,
$expected,
$path,
$proc,
$name,
$crate::Value::Struct(::std::collections::BTreeMap::new()),
{
#[derive(Serialize)]
struct Data {}
},
Data {}
);
};
}
#[macro_export]
#[allow(non_snake_case)]
#[doc(hidden)]
macro_rules! __internal__single_source_multi_template_tests {
($test_name:ident, $expected:literal, $path:literal, $proc:expr, $names:expr, $name:literal, $data:expr, {$($serde_types:item)*}, $serde_data:expr) => {
mod $test_name {
use cookie_cutter::*;
fn common() -> $crate::__internal__tests_util::MultiBuiltTemplateTestBuilder {
$crate::__internal__tests_util::SingleSourceTestBuilder::new($path, include_str!($path))
.parse()
.build_multi($names)
}
#[test]
fn manual() {
common().render_and_expect($name, $data, $expected);
}
#[cfg(feature = "serde")]
use serde::Serialize;
#[cfg(feature = "serde")]
$($serde_types)*
#[cfg(feature = "serde")]
#[test]
fn serde() {
common().render_serde_and_expect($name, $serde_data, $expected);
}
#[cfg(feature = "proc_macros")]
#[test]
fn proc_macro() {
assert_eq!(
$proc
.render($name, $data)
.unwrap(),
$expected
)
}
}
};
}
#[macro_export]
#[allow(non_snake_case)]
#[doc(hidden)]
macro_rules! __internal__single_source_multi_template_no_params_tests {
($test_name:ident, $expected:literal, $path:literal, $proc:expr, $names:expr, $name:literal) => {
$crate::__internal__single_source_multi_template_tests!(
$test_name,
$expected,
$path,
$proc,
$names,
$name,
$crate::Value::Struct(::std::collections::BTreeMap::new()),
{
#[derive(Serialize)]
struct Data {}
},
Data {}
);
};
}