,
}
let t = VecJoinTemplate {
s: vec!["foo".into(), "bar".into(), "bazz".into()],
};
assert_eq!(t.render().unwrap(), "foo, bar, bazz");
}
#[cfg(feature = "serde_json")]
#[test]
fn test_json() {
#[derive(Template)]
#[template(
source = r#"{
"foo": "{{ foo }}",
"bar": {{ bar|json|safe }}
}"#,
ext = "txt"
)]
struct JsonTemplate<'a> {
foo: &'a str,
bar: &'a Value,
}
let val = json!({"arr": [ "one", 2, true, null ]});
let t = JsonTemplate {
foo: "a",
bar: &val,
};
assert_eq!(
t.render().unwrap(),
r#"{
"foo": "a",
"bar": {"arr":["one",2,true,null]}
}"#
);
}
#[cfg(feature = "serde_json")]
#[test]
fn test_pretty_json() {
#[derive(Template)]
#[template(
source = r#"{
"foo": "{{ foo }}",
"bar": {{ bar|json(2)|safe }}
}"#,
ext = "txt"
)]
struct PrettyJsonTemplate<'a> {
foo: &'a str,
bar: &'a Value,
}
let val = json!({"arr": [ "one", 2, true, null ]});
let t = PrettyJsonTemplate {
foo: "a",
bar: &val,
};
// Note: the json filter lacks a way to specify initial indentation
assert_eq!(
t.render().unwrap(),
r#"{
"foo": "a",
"bar": {
"arr": [
"one",
2,
true,
null
]
}
}"#
);
}
#[cfg(feature = "serde_json")]
#[test]
fn test_dynamic_json() {
#[derive(Template)]
#[template(source = r#"{{ bar|json(indent)|safe }}"#, ext = "txt")]
struct DynamicJsonTemplate<'a> {
bar: &'a Value,
indent: &'a str,
}
let val = json!({"arr": ["one", 2]});
let t = DynamicJsonTemplate {
bar: &val,
indent: "?",
};
assert_eq!(
t.render().unwrap(),
r#"{
?"arr": [
??"one",
??2
?]
}"#
);
}
#[test]
fn test_nested_filter_ref() {
#[derive(Template)]
#[template(source = "{{ x|mytrim|safe }}", ext = "html")]
struct NestedFilterTemplate {
x: String,
}
let t = NestedFilterTemplate {
x: " floo & bar".to_string(),
};
assert_eq!(t.render().unwrap(), "floo & bar");
}
#[test]
fn test_filter_let_filter() {
#[derive(Template)]
#[template(
source = "{% let p = baz.print(foo.as_ref()) %}{{ p|upper }}",
ext = "html"
)]
struct FilterLetFilterTemplate {
foo: String,
baz: Baz,
}
struct Baz {}
impl Baz {
fn print(&self, s: &str) -> String {
s.trim().to_owned()
}
}
let t = FilterLetFilterTemplate {
foo: " bar ".to_owned(),
baz: Baz {},
};
assert_eq!(t.render().unwrap(), "BAR");
}
#[test]
fn test_filter_truncate() {
#[derive(Template)]
#[template(source = "{{ foo|truncate(10) }}{{ foo|truncate(5) }}", ext = "txt")]
struct TruncateFilter {
foo: String,
}
let t = TruncateFilter {
foo: "alpha bar".into(),
};
assert_eq!(t.render().unwrap(), "alpha baralpha...");
}
#[cfg(feature = "serde_json")]
#[test]
fn test_json_attribute() {
#[derive(Template)]
#[template(source = r#""#, ext = "html")]
struct JsonAttributeTemplate<'a> {
name: &'a str,
}
let t = JsonAttributeTemplate {
name: r#"">"#,
};
assert_eq!(
t.render().unwrap(),
r#""#
);
}
#[cfg(feature = "serde_json")]
#[test]
fn test_json_attribute2() {
#[derive(Template)]
#[template(source = r#""#, ext = "html")]
struct JsonAttribute2Template<'a> {
name: &'a str,
}
let t = JsonAttribute2Template {
name: r"'>",
};
assert_eq!(
t.render().unwrap(),
r#""#
);
}
#[cfg(feature = "serde_json")]
#[test]
fn test_json_script() {
#[derive(Template)]
#[template(
source = r#""#,
ext = "html"
)]
struct JsonScriptTemplate<'a> {
name: &'a str,
}
let t = JsonScriptTemplate {
name: r"",
};
assert_eq!(
t.render().unwrap(),
r#""#
);
}
#[test]
fn test_let_borrow() {
#[derive(askama::Template)]
#[template(
source = r#"{% let word = s|ref %}{{ word }}
{%- let hello = String::from("hello") %}
{%- if word|deref == hello %}1{% else %}2{% endif %}"#,
ext = "html"
)]
struct LetBorrow {
s: String,
}
let template = LetBorrow {
s: "hello".to_owned(),
};
assert_eq!(template.render().unwrap(), "hello1");
}
#[test]
fn test_linebreaks() {
let s = "";
#[derive(Template)]
#[template(source = r#"{{ s|linebreaks }}"#, ext = "html")]
struct LineBreaks {
s: &'static str,
}
assert_eq!(
LineBreaks { s }.render().unwrap(),
"<script>
alert('Hello, world!')
</script>
",
);
#[derive(Template)]
#[template(source = r#"{{ s|escape|linebreaks }}"#, ext = "html")]
struct LineBreaksExtraEscape {
s: &'static str,
}
assert_eq!(
LineBreaksExtraEscape { s }.render().unwrap(),
"<script>
alert('Hello, world!')
</script>
",
);
#[derive(Template)]
#[template(source = r#"{{ s|linebreaks|safe }}"#, ext = "html")]
struct LineBreaksExtraSafe {
s: &'static str,
}
assert_eq!(
LineBreaksExtraSafe { s }.render().unwrap(),
"<script>
alert('Hello, world!')
</script>
",
);
#[derive(Template)]
#[template(source = r#"{{ s|escape|linebreaks|safe }}"#, ext = "html")]
struct LineBreaksExtraBoth {
s: &'static str,
}
assert_eq!(
LineBreaksExtraBoth { s }.render().unwrap(),
"<script>
alert('Hello, world!')
</script>
",
);
}
// Regression tests for .
#[test]
fn test_filesizeformat() {
#[derive(Template)]
#[template(
source = r#"{% if let Some(x) = s %}{{x|filesizeformat}}{% endif %}"#,
ext = "html"
)]
struct S {
s: Option,
}
assert_eq!(S { s: Some(12) }.render().unwrap(), "12 B");
}
#[test]
fn test_whitespace_around_filter_operator() {
#[derive(Template)]
#[template(
source = r#"{{ 12 |safe }}
{{ 8| safe }}
{{ 4 | safe }}"#,
ext = "html"
)]
struct S;
assert_eq!(S.render().unwrap(), "12\n8\n4");
}