mirror of
https://github.com/askama-rs/askama.git
synced 2025-09-28 21:41:35 +00:00
add test cases and rework spaces
Signed-off-by: Michael Pollind <mpollind@gmail.com>
This commit is contained in:
parent
8862325e9b
commit
ef489b60f6
@ -608,7 +608,7 @@ impl<'a> Generator<'a, '_> {
|
|||||||
call: &'a WithSpan<'a, Call<'_>>,
|
call: &'a WithSpan<'a, Call<'_>>,
|
||||||
) -> Result<usize, CompileError> {
|
) -> Result<usize, CompileError> {
|
||||||
let Call {
|
let Call {
|
||||||
ws,
|
ws1,
|
||||||
scope,
|
scope,
|
||||||
name,
|
name,
|
||||||
ref args,
|
ref args,
|
||||||
@ -650,7 +650,7 @@ impl<'a> Generator<'a, '_> {
|
|||||||
self.seen_macros.push((def, ctx.file_info_of(call.span())));
|
self.seen_macros.push((def, ctx.file_info_of(call.span())));
|
||||||
}
|
}
|
||||||
self.seen_callers.push(call);
|
self.seen_callers.push(call);
|
||||||
self.flush_ws(ws); // Cannot handle_ws() here: whitespace from macro definition comes first
|
self.flush_ws(ws1); // Cannot handle_ws() here: whitespace from macro definition comes first
|
||||||
let size_hint = self.push_locals(|this| {
|
let size_hint = self.push_locals(|this| {
|
||||||
macro_call_ensure_arg_count(call, def, ctx)?;
|
macro_call_ensure_arg_count(call, def, ctx)?;
|
||||||
|
|
||||||
@ -771,7 +771,7 @@ impl<'a> Generator<'a, '_> {
|
|||||||
buf.write('}');
|
buf.write('}');
|
||||||
Ok(size_hint)
|
Ok(size_hint)
|
||||||
})?;
|
})?;
|
||||||
self.prepare_ws(ws);
|
self.prepare_ws(ws1);
|
||||||
self.seen_macros.pop();
|
self.seen_macros.pop();
|
||||||
self.seen_callers.pop();
|
self.seen_callers.pop();
|
||||||
Ok(size_hint)
|
Ok(size_hint)
|
||||||
@ -1119,9 +1119,10 @@ impl<'a> Generator<'a, '_> {
|
|||||||
if ***path == Expr::Var("super") {
|
if ***path == Expr::Var("super") {
|
||||||
return self.write_block(ctx, buf, None, ws, s.span());
|
return self.write_block(ctx, buf, None, ws, s.span());
|
||||||
} else if ***path == Expr::Var("caller") {
|
} else if ***path == Expr::Var("caller") {
|
||||||
let def = self.seen_callers.last().ok_or_else(|| {
|
let def = self.seen_callers.pop().ok_or_else(|| {
|
||||||
ctx.generate_error(format_args!("block is not defined for caller"), s.span())
|
ctx.generate_error(format_args!("block is not defined for caller"), s.span())
|
||||||
})?;
|
})?;
|
||||||
|
self.handle_ws(ws);
|
||||||
let size_hint = self.push_locals(|this| {
|
let size_hint = self.push_locals(|this| {
|
||||||
this.write_buf_writable(ctx, buf)?;
|
this.write_buf_writable(ctx, buf)?;
|
||||||
buf.write('{');
|
buf.write('{');
|
||||||
@ -1180,14 +1181,14 @@ impl<'a> Generator<'a, '_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut size_hint = this.handle(ctx, &def.nodes, buf, AstLevel::Nested)?;
|
let mut size_hint = this.handle(ctx, &def.nodes, buf, AstLevel::Nested)?;
|
||||||
|
|
||||||
this.flush_ws(def.ws2);
|
this.flush_ws(def.ws2);
|
||||||
size_hint += this.write_buf_writable(ctx, buf)?;
|
size_hint += this.write_buf_writable(ctx, buf)?;
|
||||||
buf.write('}');
|
buf.write('}');
|
||||||
Ok(size_hint)
|
Ok(size_hint)
|
||||||
})?;
|
})?;
|
||||||
self.prepare_ws(ws);
|
self.seen_callers.push(def);
|
||||||
return Ok(size_hint);
|
return Ok(size_hint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -877,12 +877,11 @@ impl<'a> Import<'a> {
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Call<'a> {
|
pub struct Call<'a> {
|
||||||
pub ws: Ws,
|
pub ws1: Ws,
|
||||||
pub caller_args: Vec<&'a str>,
|
pub caller_args: Vec<&'a str>,
|
||||||
pub scope: Option<&'a str>,
|
pub scope: Option<&'a str>,
|
||||||
pub name: &'a str,
|
pub name: &'a str,
|
||||||
pub args: Vec<WithSpan<'a, Expr<'a>>>,
|
pub args: Vec<WithSpan<'a, Expr<'a>>>,
|
||||||
pub ws1: Ws,
|
|
||||||
pub nodes: Vec<Node<'a>>,
|
pub nodes: Vec<Node<'a>>,
|
||||||
pub ws2: Ws,
|
pub ws2: Ws,
|
||||||
}
|
}
|
||||||
@ -947,12 +946,11 @@ impl<'a> Call<'a> {
|
|||||||
|
|
||||||
Ok(WithSpan::new(
|
Ok(WithSpan::new(
|
||||||
Self {
|
Self {
|
||||||
ws: Ws(pws, nws),
|
ws1: Ws(pws, nws),
|
||||||
caller_args: call_args.unwrap_or_default(),
|
caller_args: call_args.unwrap_or_default(),
|
||||||
scope,
|
scope,
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
ws1: Ws(pws, pws2),
|
|
||||||
nodes,
|
nodes,
|
||||||
ws2: Ws(pws2, nws2),
|
ws2: Ws(pws2, nws2),
|
||||||
},
|
},
|
||||||
|
@ -125,17 +125,18 @@ nested
|
|||||||
assert_eq!(x.render().unwrap(), "nested");
|
assert_eq!(x.render().unwrap(), "nested");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_caller_struct() {
|
fn test_caller_struct() {
|
||||||
struct TestInput<'a> {
|
struct TestInput<'a> {
|
||||||
a: &'a str,
|
a: &'a str,
|
||||||
b: &'a str
|
b: &'a str,
|
||||||
}
|
}
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(
|
#[template(
|
||||||
source = r#"
|
source = r#"
|
||||||
{%- macro test(a) -%}
|
{%- macro test(a) -%}
|
||||||
{{caller(a)}}
|
{{- caller(a) -}}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
{%- call(value) test(a) -%}
|
{%- call(value) test(a) -%}
|
||||||
a: {{value.a}}
|
a: {{value.a}}
|
||||||
@ -145,13 +146,10 @@ b: {{value.b}}
|
|||||||
ext = "txt"
|
ext = "txt"
|
||||||
)]
|
)]
|
||||||
struct Tmpl<'a> {
|
struct Tmpl<'a> {
|
||||||
a: TestInput<'a>
|
a: TestInput<'a>,
|
||||||
}
|
}
|
||||||
let x = Tmpl {
|
let x = Tmpl {
|
||||||
a: TestInput {
|
a: TestInput { a: "one", b: "two" },
|
||||||
a: "one",
|
|
||||||
b: "two"
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
assert_eq!(x.render().unwrap(), "a: one\nb: two");
|
assert_eq!(x.render().unwrap(), "a: one\nb: two");
|
||||||
}
|
}
|
||||||
@ -162,18 +160,18 @@ fn test_caller_args() {
|
|||||||
#[template(
|
#[template(
|
||||||
source = r#"
|
source = r#"
|
||||||
{%- macro test() -%}
|
{%- macro test() -%}
|
||||||
{{- caller("test") -}}
|
{{~ caller("test") ~}}
|
||||||
{{- caller(1) -}}
|
{{~ caller(1) ~}}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
{%- call(value) test() -%}
|
{%- call(value) test() -%}
|
||||||
nested {{value}}
|
nested {{value}}
|
||||||
{%- endcall -%}
|
{%- endcall -%}
|
||||||
"#,
|
"#,
|
||||||
ext = "html"
|
ext = "html"
|
||||||
)]
|
)]
|
||||||
struct CallerEmpty {}
|
struct CallerEmpty {}
|
||||||
let x = CallerEmpty {};
|
let x = CallerEmpty {};
|
||||||
assert_eq!(x.render().unwrap(), "nested testnested 1");
|
assert_eq!(x.render().unwrap(), "nested test\nnested 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensures that fields are not moved when calling a jinja macro.
|
// Ensures that fields are not moved when calling a jinja macro.
|
||||||
|
@ -238,6 +238,48 @@ fn test_default_value3() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test a caller expression with expressions in the arguments.
|
||||||
|
#[test]
|
||||||
|
fn test_caller_expr() {
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
source = "{%- macro thrice(a, b, c) -%}
|
||||||
|
{{caller(a+10,b - 10,a+b+c)}}
|
||||||
|
{% endmacro -%}
|
||||||
|
{%- call(a,b,c) thrice(10,11,13) -%}{{a}} {{b}} {{c + 1}}{%- endcall -%}
|
||||||
|
",
|
||||||
|
ext = "html"
|
||||||
|
)]
|
||||||
|
struct MacroCallerExpr;
|
||||||
|
assert_eq!(MacroCallerExpr.render().unwrap(), "20 1 35\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_caller_in_caller() {
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
source = r#"
|
||||||
|
{%- macro test2() -%}
|
||||||
|
{{~ caller("bb") ~}}
|
||||||
|
{%- endmacro -%}
|
||||||
|
{%- macro test() -%}
|
||||||
|
{{~ caller("a") ~}}
|
||||||
|
{%- endmacro -%}
|
||||||
|
{%- call(a) test() -%}
|
||||||
|
{%- call(b) test2() -%}
|
||||||
|
one: {{ b }}
|
||||||
|
{%- endcall -%}
|
||||||
|
two: {{- a -}}
|
||||||
|
{%- endcall -%}
|
||||||
|
"#,
|
||||||
|
ext = "txt"
|
||||||
|
)]
|
||||||
|
struct CallerInCaller;
|
||||||
|
assert_eq!(CallerInCaller.render().unwrap(), "one: bbtwo:a");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// This test ensures that we can use declared variables as default value for
|
// This test ensures that we can use declared variables as default value for
|
||||||
// macro arguments.
|
// macro arguments.
|
||||||
#[test]
|
#[test]
|
||||||
|
70
testing/tests/ui/caller_arguments.rs
Normal file
70
testing/tests/ui/caller_arguments.rs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
use askama::Template;
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
source = r#"
|
||||||
|
{% macro test() %}
|
||||||
|
{{- caller("a", "b") -}}
|
||||||
|
{%- endmacro -%}
|
||||||
|
{%- call(a,b,c) test() -%}
|
||||||
|
{{- a -}}
|
||||||
|
{%- endcall -%}
|
||||||
|
"#,
|
||||||
|
ext = "txt"
|
||||||
|
)]
|
||||||
|
struct InvalidNumberArguments {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
source = r#"
|
||||||
|
{% macro test() %}
|
||||||
|
{{- caller("a") -}}
|
||||||
|
{%- endmacro -%}
|
||||||
|
{%- call(a test() -%}
|
||||||
|
{{- a -}}
|
||||||
|
{%- endcall -%}
|
||||||
|
"#,
|
||||||
|
ext = "txt"
|
||||||
|
)]
|
||||||
|
struct NoClosingParen {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
source = r#"
|
||||||
|
{% macro test() %}
|
||||||
|
{{- caller("a") -}}
|
||||||
|
{%- endmacro -%}
|
||||||
|
{%- call(a) test() -%}
|
||||||
|
{{- caller(a) -}}
|
||||||
|
{%- endcall -%}
|
||||||
|
"#,
|
||||||
|
ext = "txt"
|
||||||
|
)]
|
||||||
|
struct CallerInCaller {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
source = r#"
|
||||||
|
{% macro test2() %}
|
||||||
|
{{ caller("bb") }}
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro test() %}
|
||||||
|
{{ caller("a") }}
|
||||||
|
{%- endmacro -%}
|
||||||
|
{%- call(a) test() -%}
|
||||||
|
{% call(b) test2() %}
|
||||||
|
{{ caller("b") }}
|
||||||
|
{% endcall %}
|
||||||
|
{{- a -}}
|
||||||
|
{%- endcall -%}
|
||||||
|
"#,
|
||||||
|
ext = "txt"
|
||||||
|
)]
|
||||||
|
struct CallerInCaller1 {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
59
testing/tests/ui/caller_arguments.stderr
Normal file
59
testing/tests/ui/caller_arguments.stderr
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
error: missing `c` argument
|
||||||
|
--> InvalidNumberArguments.txt:3:18
|
||||||
|
"(\"a\", \"b\") -}}\n {%- endmacro -%}\n {%- call(a,b,c) test() -%}\n {{- a"...
|
||||||
|
--> tests/ui/caller_arguments.rs:5:14
|
||||||
|
|
|
||||||
|
5 | source = r#"
|
||||||
|
| ______________^
|
||||||
|
6 | | {% macro test() %}
|
||||||
|
7 | | {{- caller("a", "b") -}}
|
||||||
|
8 | | {%- endmacro -%}
|
||||||
|
... |
|
||||||
|
11 | | {%- endcall -%}
|
||||||
|
12 | | "#,
|
||||||
|
| |______^
|
||||||
|
|
||||||
|
error: expected `)` to close call argument list
|
||||||
|
--> <source attribute>:5:15
|
||||||
|
"test() -%}\n {{- a -}}\n {%- endcall -%}\n "
|
||||||
|
--> tests/ui/caller_arguments.rs:20:14
|
||||||
|
|
|
||||||
|
20 | source = r#"
|
||||||
|
| ______________^
|
||||||
|
21 | | {% macro test() %}
|
||||||
|
22 | | {{- caller("a") -}}
|
||||||
|
23 | | {%- endmacro -%}
|
||||||
|
... |
|
||||||
|
26 | | {%- endcall -%}
|
||||||
|
27 | | "#,
|
||||||
|
| |______^
|
||||||
|
|
||||||
|
error: block is not defined for caller
|
||||||
|
--> CallerInCaller.txt:6:18
|
||||||
|
"(a) -}}\n {%- endcall -%}\n "
|
||||||
|
--> tests/ui/caller_arguments.rs:35:14
|
||||||
|
|
|
||||||
|
35 | source = r#"
|
||||||
|
| ______________^
|
||||||
|
36 | | {% macro test() %}
|
||||||
|
37 | | {{- caller("a") -}}
|
||||||
|
38 | | {%- endmacro -%}
|
||||||
|
... |
|
||||||
|
41 | | {%- endcall -%}
|
||||||
|
42 | | "#,
|
||||||
|
| |______^
|
||||||
|
|
||||||
|
error: block is not defined for caller
|
||||||
|
--> CallerInCaller1.txt:10:21
|
||||||
|
"(\"b\") }}\n {% endcall %}\n {{- a -}}\n {%- endcall -%}\n "
|
||||||
|
--> tests/ui/caller_arguments.rs:50:14
|
||||||
|
|
|
||||||
|
50 | source = r#"
|
||||||
|
| ______________^
|
||||||
|
51 | | {% macro test2() %}
|
||||||
|
52 | | {{ caller("bb") }}
|
||||||
|
53 | | {% endmacro %}
|
||||||
|
... |
|
||||||
|
62 | | {%- endcall -%}
|
||||||
|
63 | | "#,
|
||||||
|
| |______^
|
Loading…
x
Reference in New Issue
Block a user