mirror of
https://github.com/askama-rs/askama.git
synced 2025-10-02 15:25:19 +00:00
Add tests for if (not) defined
feature
This commit is contained in:
parent
0372dac003
commit
fcf1a97d9d
@ -8,98 +8,106 @@ use similar::{Algorithm, ChangeTag, TextDiffConfig};
|
|||||||
|
|
||||||
use crate::build_template;
|
use crate::build_template;
|
||||||
|
|
||||||
|
// This function makes it much easier to compare expected code by adding the wrapping around
|
||||||
|
// the code we want to check.
|
||||||
|
#[track_caller]
|
||||||
|
fn compare(jinja: &str, expected: &str, fields: &[(&str, &str)], size_hint: usize) {
|
||||||
|
let jinja = format!(
|
||||||
|
r##"#[template(source = {jinja:?}, ext = "txt")]
|
||||||
|
struct Foo {{ {} }}"##,
|
||||||
|
fields
|
||||||
|
.iter()
|
||||||
|
.map(|(name, type_)| format!("{name}: {type_}"))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(","),
|
||||||
|
);
|
||||||
|
let generated = build_template(&syn::parse_str::<syn::DeriveInput>(&jinja).unwrap())
|
||||||
|
.unwrap()
|
||||||
|
.parse()
|
||||||
|
.unwrap();
|
||||||
|
let generated: syn::File = syn::parse2(generated).unwrap();
|
||||||
|
|
||||||
|
let size_hint = proc_macro2::Literal::usize_unsuffixed(size_hint);
|
||||||
|
let expected: proc_macro2::TokenStream = expected.parse().unwrap();
|
||||||
|
let expected: syn::File = syn::parse_quote! {
|
||||||
|
impl ::rinja::Template for Foo {
|
||||||
|
fn render_into<RinjaW>(&self, writer: &mut RinjaW) -> ::rinja::Result<()>
|
||||||
|
where
|
||||||
|
RinjaW: ::core::fmt::Write + ?::core::marker::Sized,
|
||||||
|
{
|
||||||
|
use ::rinja::filters::AutoEscape as _;
|
||||||
|
use ::core::fmt::Write as _;
|
||||||
|
#expected
|
||||||
|
::rinja::Result::Ok(())
|
||||||
|
}
|
||||||
|
const EXTENSION: ::std::option::Option<&'static ::std::primitive::str> = Some("txt");
|
||||||
|
const SIZE_HINT: ::std::primitive::usize = #size_hint;
|
||||||
|
const MIME_TYPE: &'static ::std::primitive::str = "text/plain; charset=utf-8";
|
||||||
|
}
|
||||||
|
impl ::std::fmt::Display for Foo {
|
||||||
|
#[inline]
|
||||||
|
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||||
|
::rinja::Template::render_into(self, f).map_err(|_| ::std::fmt::Error {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if expected != generated {
|
||||||
|
let expected = prettyplease::unparse(&expected);
|
||||||
|
let generated = prettyplease::unparse(&generated);
|
||||||
|
|
||||||
|
struct Diff<'a>(&'a str, &'a str);
|
||||||
|
|
||||||
|
impl fmt::Display for Diff<'_> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
let diff = TextDiffConfig::default()
|
||||||
|
.algorithm(Algorithm::Patience)
|
||||||
|
.diff_lines(self.0, self.1);
|
||||||
|
for change in diff.iter_all_changes() {
|
||||||
|
let (change, line) = match change.tag() {
|
||||||
|
ChangeTag::Equal => (
|
||||||
|
style(" ").dim().bold(),
|
||||||
|
style(change.to_string_lossy()).dim(),
|
||||||
|
),
|
||||||
|
ChangeTag::Delete => (
|
||||||
|
style("-").red().bold(),
|
||||||
|
style(change.to_string_lossy()).red(),
|
||||||
|
),
|
||||||
|
ChangeTag::Insert => (
|
||||||
|
style("+").green().bold(),
|
||||||
|
style(change.to_string_lossy()).green(),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
write!(f, "{change}{line}")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!(
|
||||||
|
"\n\
|
||||||
|
=== Expected ===\n\
|
||||||
|
\n\
|
||||||
|
{expected}\n\
|
||||||
|
\n\
|
||||||
|
=== Generated ===\n\
|
||||||
|
\n\
|
||||||
|
{generated}\n\
|
||||||
|
\n\
|
||||||
|
=== Diff ===\n\
|
||||||
|
\n\
|
||||||
|
{diff}\n\
|
||||||
|
\n\
|
||||||
|
=== FAILURE ===",
|
||||||
|
expected = style(&expected).red(),
|
||||||
|
generated = style(&generated).green(),
|
||||||
|
diff = Diff(&expected, &generated),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_if_let() {
|
fn check_if_let() {
|
||||||
// This function makes it much easier to compare expected code by adding the wrapping around
|
|
||||||
// the code we want to check.
|
|
||||||
#[track_caller]
|
|
||||||
fn compare(jinja: &str, expected: &str, size_hint: usize) {
|
|
||||||
let jinja = format!(r#"#[template(source = {jinja:?}, ext = "txt")] struct Foo;"#);
|
|
||||||
let generated = build_template(&syn::parse_str::<syn::DeriveInput>(&jinja).unwrap())
|
|
||||||
.unwrap()
|
|
||||||
.parse()
|
|
||||||
.unwrap();
|
|
||||||
let generated: syn::File = syn::parse2(generated).unwrap();
|
|
||||||
|
|
||||||
let size_hint = proc_macro2::Literal::usize_unsuffixed(size_hint);
|
|
||||||
let expected: proc_macro2::TokenStream = expected.parse().unwrap();
|
|
||||||
let expected: syn::File = syn::parse_quote! {
|
|
||||||
impl ::rinja::Template for Foo {
|
|
||||||
fn render_into<RinjaW>(&self, writer: &mut RinjaW) -> ::rinja::Result<()>
|
|
||||||
where
|
|
||||||
RinjaW: ::core::fmt::Write + ?::core::marker::Sized,
|
|
||||||
{
|
|
||||||
use ::rinja::filters::AutoEscape as _;
|
|
||||||
use ::core::fmt::Write as _;
|
|
||||||
#expected
|
|
||||||
::rinja::Result::Ok(())
|
|
||||||
}
|
|
||||||
const EXTENSION: ::std::option::Option<&'static ::std::primitive::str> = Some("txt");
|
|
||||||
const SIZE_HINT: ::std::primitive::usize = #size_hint;
|
|
||||||
const MIME_TYPE: &'static ::std::primitive::str = "text/plain; charset=utf-8";
|
|
||||||
}
|
|
||||||
impl ::std::fmt::Display for Foo {
|
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
|
||||||
::rinja::Template::render_into(self, f).map_err(|_| ::std::fmt::Error {})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if expected != generated {
|
|
||||||
let expected = prettyplease::unparse(&expected);
|
|
||||||
let generated = prettyplease::unparse(&generated);
|
|
||||||
|
|
||||||
struct Diff<'a>(&'a str, &'a str);
|
|
||||||
|
|
||||||
impl fmt::Display for Diff<'_> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
let diff = TextDiffConfig::default()
|
|
||||||
.algorithm(Algorithm::Patience)
|
|
||||||
.diff_lines(self.0, self.1);
|
|
||||||
for change in diff.iter_all_changes() {
|
|
||||||
let (change, line) = match change.tag() {
|
|
||||||
ChangeTag::Equal => (
|
|
||||||
style(" ").dim().bold(),
|
|
||||||
style(change.to_string_lossy()).dim(),
|
|
||||||
),
|
|
||||||
ChangeTag::Delete => (
|
|
||||||
style("-").red().bold(),
|
|
||||||
style(change.to_string_lossy()).red(),
|
|
||||||
),
|
|
||||||
ChangeTag::Insert => (
|
|
||||||
style("+").green().bold(),
|
|
||||||
style(change.to_string_lossy()).green(),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
write!(f, "{change}{line}")?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
panic!(
|
|
||||||
"\n\
|
|
||||||
=== Expected ===\n\
|
|
||||||
\n\
|
|
||||||
{expected}\n\
|
|
||||||
\n\
|
|
||||||
=== Generated ===\n\
|
|
||||||
\n\
|
|
||||||
{generated}\n\
|
|
||||||
\n\
|
|
||||||
=== Diff ===\n\
|
|
||||||
\n\
|
|
||||||
{diff}\n\
|
|
||||||
\n\
|
|
||||||
=== FAILURE ===",
|
|
||||||
expected = style(&expected).red(),
|
|
||||||
generated = style(&generated).green(),
|
|
||||||
diff = Diff(&expected, &generated),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// In this test, we ensure that `query` never is `self.query`.
|
// In this test, we ensure that `query` never is `self.query`.
|
||||||
compare(
|
compare(
|
||||||
"{% if let Some(query) = s && !query.is_empty() %}{{query}}{% endif %}",
|
"{% if let Some(query) = s && !query.is_empty() %}{{query}}{% endif %}",
|
||||||
@ -110,6 +118,7 @@ fn check_if_let() {
|
|||||||
expr0 = &(&&::rinja::filters::AutoEscaper::new(&(query), ::rinja::filters::Text)).rinja_auto_escape()?,
|
expr0 = &(&&::rinja::filters::AutoEscaper::new(&(query), ::rinja::filters::Text)).rinja_auto_escape()?,
|
||||||
)?;
|
)?;
|
||||||
}"#,
|
}"#,
|
||||||
|
&[],
|
||||||
3,
|
3,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -124,6 +133,7 @@ fn check_if_let() {
|
|||||||
expr0 = &(&&::rinja::filters::AutoEscaper::new(&(s), ::rinja::filters::Text)).rinja_auto_escape()?,
|
expr0 = &(&&::rinja::filters::AutoEscaper::new(&(s), ::rinja::filters::Text)).rinja_auto_escape()?,
|
||||||
)?;
|
)?;
|
||||||
}"#,
|
}"#,
|
||||||
|
&[],
|
||||||
3,
|
3,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -138,6 +148,7 @@ fn check_if_let() {
|
|||||||
expr0 = &(&&::rinja::filters::AutoEscaper::new(&(s), ::rinja::filters::Text)).rinja_auto_escape()?,
|
expr0 = &(&&::rinja::filters::AutoEscaper::new(&(s), ::rinja::filters::Text)).rinja_auto_escape()?,
|
||||||
)?;
|
)?;
|
||||||
}"#,
|
}"#,
|
||||||
|
&[],
|
||||||
3,
|
3,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -157,6 +168,161 @@ fn check_if_let() {
|
|||||||
writer.write_str("3")?;
|
writer.write_str("3")?;
|
||||||
writer.write_str("3")?;"#
|
writer.write_str("3")?;"#
|
||||||
),
|
),
|
||||||
|
&[],
|
||||||
4,
|
4,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_is_defined() {
|
||||||
|
// Checks that it removes conditions if we know at compile-time that they always return false.
|
||||||
|
//
|
||||||
|
// We're forced to add `bla` otherwise `compare` assert fails in weird ways...
|
||||||
|
compare(
|
||||||
|
"{% if y is defined %}{{query}}{% endif %}bla",
|
||||||
|
r#"writer.write_str("bla")?;"#,
|
||||||
|
&[],
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
compare(
|
||||||
|
"{% if x is not defined %}{{query}}{% endif %}bla",
|
||||||
|
r#"writer.write_str("bla")?;"#,
|
||||||
|
&[("x", "u32")],
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
compare(
|
||||||
|
"{% if y is defined && x is not defined %}{{query}}{% endif %}bla",
|
||||||
|
r#"writer.write_str("bla")?;"#,
|
||||||
|
&[("x", "u32")],
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Same with declared variables.
|
||||||
|
compare(
|
||||||
|
"{% set y = 12 %}
|
||||||
|
{%- if y is not defined %}{{query}}{% endif %}bla",
|
||||||
|
r#"let y = 12;
|
||||||
|
writer.write_str("bla")?;"#,
|
||||||
|
&[],
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
compare(
|
||||||
|
"{% set y = 12 %}
|
||||||
|
{%- if y is not defined && x is defined %}{{query}}{% endif %}bla",
|
||||||
|
r#"let y = 12;
|
||||||
|
writer.write_str("bla")?;"#,
|
||||||
|
&[],
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Checks that if the condition is always `true` at compile-time, then we keep the code but
|
||||||
|
// remove the condition.
|
||||||
|
compare(
|
||||||
|
"{% if y is defined %}bla{% endif %}",
|
||||||
|
r#"writer.write_str("bla")?;"#,
|
||||||
|
&[("y", "u32")],
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
compare(
|
||||||
|
"{% if x is not defined %}bla{% endif %}",
|
||||||
|
r#"writer.write_str("bla")?;"#,
|
||||||
|
&[],
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
// Same with declared variables.
|
||||||
|
compare(
|
||||||
|
"{% set y = 12 %}
|
||||||
|
{%- if y is defined %}bla{% endif %}",
|
||||||
|
r#"let y = 12;
|
||||||
|
writer.write_str("bla")?;"#,
|
||||||
|
&[],
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
|
||||||
|
// If the always `true` condition is followed by more `else if`/`else`, check that they are
|
||||||
|
// removed as well.
|
||||||
|
compare(
|
||||||
|
"{% if x is defined %}bli
|
||||||
|
{%- else if x == 12 %}12{% endif %}bla",
|
||||||
|
r#"writer.write_str("bli")?;
|
||||||
|
writer.write_str("bla")?;"#,
|
||||||
|
&[("x", "u32")],
|
||||||
|
6,
|
||||||
|
);
|
||||||
|
compare(
|
||||||
|
"{% if x is defined %}bli
|
||||||
|
{%- else if x == 12 %}12
|
||||||
|
{%- else %}nope{% endif %}bla",
|
||||||
|
r#"writer.write_str("bli")?;
|
||||||
|
writer.write_str("bla")?;"#,
|
||||||
|
&[("x", "u32")],
|
||||||
|
6,
|
||||||
|
);
|
||||||
|
// If it's not the first one.
|
||||||
|
compare(
|
||||||
|
"{% if x == 12 %}bli
|
||||||
|
{%- else if x is defined %}12
|
||||||
|
{%- else %}nope{% endif %}",
|
||||||
|
r#"if *(&(self.x == 12) as &bool) {
|
||||||
|
writer.write_str("bli")?;
|
||||||
|
} else {
|
||||||
|
writer.write_str("12")?;
|
||||||
|
}"#,
|
||||||
|
&[("x", "u32")],
|
||||||
|
5,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Checking that it doesn't remove the condition if other non-"if (not) defined" checks
|
||||||
|
// are present.
|
||||||
|
compare(
|
||||||
|
"{% if y is defined || x == 12 %}{{x}}{% endif %}",
|
||||||
|
r#"if *(&(false || self.x == 12) as &bool) {
|
||||||
|
::std::write!(writer, "{expr0}",
|
||||||
|
expr0 = &(&&::rinja::filters::AutoEscaper::new(&(self.x), ::rinja::filters::Text)).rinja_auto_escape()?,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
&[("x", "u32")],
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
compare(
|
||||||
|
"{% if y is defined || x == 12 %}{{x}}{% endif %}",
|
||||||
|
r#"if *(&(true || self.x == 12) as &bool) {
|
||||||
|
::std::write!(writer, "{expr0}",
|
||||||
|
expr0 = &(&&::rinja::filters::AutoEscaper::new(&(self.x), ::rinja::filters::Text)).rinja_auto_escape()?,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
&[("y", "u32"), ("x", "u32")],
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Checking some funny cases.
|
||||||
|
|
||||||
|
// This one is a bit useless because you can use `is not defined` but I suppose it's possible
|
||||||
|
// to encounter cases like that in the wild so better have a check.
|
||||||
|
compare(
|
||||||
|
"{% if !(y is defined) %}bla{% endif %}",
|
||||||
|
r#"writer.write_str("bla")?;"#,
|
||||||
|
&[],
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
compare(
|
||||||
|
"{% if !(y is not defined) %}bli{% endif %}bla",
|
||||||
|
r#"writer.write_str("bla")?;"#,
|
||||||
|
&[],
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
compare(
|
||||||
|
"{% if !(y is defined) %}bli{% endif %}bla",
|
||||||
|
r#"writer.write_str("bla")?;"#,
|
||||||
|
&[("y", "u32")],
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
compare(
|
||||||
|
"{% if !(y is not defined) %}bla{% endif %}",
|
||||||
|
r#"writer.write_str("bla")?;"#,
|
||||||
|
&[("y", "u32")],
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
33
testing/tests/is_defined.rs
Normal file
33
testing/tests/is_defined.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use rinja::Template;
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
source = r#"<script>
|
||||||
|
const x = {{ x is defined }};
|
||||||
|
const y = {{ y is not defined }};
|
||||||
|
const z = {{ y is defined }};
|
||||||
|
const w = {{ x is not defined }};
|
||||||
|
const v = {{ y }};
|
||||||
|
</script>"#,
|
||||||
|
ext = "html"
|
||||||
|
)]
|
||||||
|
struct IsDefined {
|
||||||
|
y: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test ensures that `include` are correctly working inside filter blocks and that external
|
||||||
|
// variables are used correctly.
|
||||||
|
#[test]
|
||||||
|
fn is_defined_in_expr() {
|
||||||
|
let s = IsDefined { y: 0 };
|
||||||
|
assert_eq!(
|
||||||
|
s.render().unwrap(),
|
||||||
|
r#"<script>
|
||||||
|
const x = false;
|
||||||
|
const y = false;
|
||||||
|
const z = true;
|
||||||
|
const w = true;
|
||||||
|
const v = 0;
|
||||||
|
</script>"#
|
||||||
|
);
|
||||||
|
}
|
46
testing/tests/ui/is_defined.rs
Normal file
46
testing/tests/ui/is_defined.rs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
use rinja::Template;
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
ext = "html",
|
||||||
|
source = r#"{% if x.y is defined %}{% endif %}"#,
|
||||||
|
)]
|
||||||
|
struct A;
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
ext = "html",
|
||||||
|
source = r#"{% if true is defined %}{% endif %}"#,
|
||||||
|
)]
|
||||||
|
struct B;
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
ext = "html",
|
||||||
|
source = r#"{% if true is %}{% endif %}"#,
|
||||||
|
)]
|
||||||
|
struct C;
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
ext = "html",
|
||||||
|
source = r#"{% if x is %}{% endif %}"#,
|
||||||
|
)]
|
||||||
|
struct D;
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
ext = "html",
|
||||||
|
source = r#"{% if x is blue %}{% endif %}"#,
|
||||||
|
)]
|
||||||
|
struct E;
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
ext = "html",
|
||||||
|
source = r#"{% if x is blue.red %}{% endif %}"#,
|
||||||
|
)]
|
||||||
|
struct F;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
59
testing/tests/ui/is_defined.stderr
Normal file
59
testing/tests/ui/is_defined.stderr
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
error: `is defined` operator can only be used on variables, not on their fields
|
||||||
|
failed to parse template source at row 1, column 6 near:
|
||||||
|
"x.y is defined %}{% endif %}"
|
||||||
|
--> tests/ui/is_defined.rs:3:10
|
||||||
|
|
|
||||||
|
3 | #[derive(Template)]
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: `is defined` operator can only be used on variables
|
||||||
|
failed to parse template source at row 1, column 6 near:
|
||||||
|
"true is defined %}{% endif %}"
|
||||||
|
--> tests/ui/is_defined.rs:10:10
|
||||||
|
|
|
||||||
|
10 | #[derive(Template)]
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: expected `defined` or `not defined` after `is`
|
||||||
|
failed to parse template source at row 1, column 6 near:
|
||||||
|
"true is %}{% endif %}"
|
||||||
|
--> tests/ui/is_defined.rs:17:10
|
||||||
|
|
|
||||||
|
17 | #[derive(Template)]
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: expected `defined` or `not defined` after `is`
|
||||||
|
failed to parse template source at row 1, column 6 near:
|
||||||
|
"x is %}{% endif %}"
|
||||||
|
--> tests/ui/is_defined.rs:24:10
|
||||||
|
|
|
||||||
|
24 | #[derive(Template)]
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: expected `defined` or `not defined` after `is`
|
||||||
|
failed to parse template source at row 1, column 6 near:
|
||||||
|
"x is blue %}{% endif %}"
|
||||||
|
--> tests/ui/is_defined.rs:31:10
|
||||||
|
|
|
||||||
|
31 | #[derive(Template)]
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: expected `defined` or `not defined` after `is`
|
||||||
|
failed to parse template source at row 1, column 6 near:
|
||||||
|
"x is blue.red %}{% endif %}"
|
||||||
|
--> tests/ui/is_defined.rs:38:10
|
||||||
|
|
|
||||||
|
38 | #[derive(Template)]
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
|
Loading…
x
Reference in New Issue
Block a user