mirror of
https://github.com/askama-rs/askama.git
synced 2025-09-27 13:00:57 +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<'_>>,
|
||||
) -> Result<usize, CompileError> {
|
||||
let Call {
|
||||
ws,
|
||||
ws1,
|
||||
scope,
|
||||
name,
|
||||
ref args,
|
||||
@ -650,7 +650,7 @@ impl<'a> Generator<'a, '_> {
|
||||
self.seen_macros.push((def, ctx.file_info_of(call.span())));
|
||||
}
|
||||
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| {
|
||||
macro_call_ensure_arg_count(call, def, ctx)?;
|
||||
|
||||
@ -771,7 +771,7 @@ impl<'a> Generator<'a, '_> {
|
||||
buf.write('}');
|
||||
Ok(size_hint)
|
||||
})?;
|
||||
self.prepare_ws(ws);
|
||||
self.prepare_ws(ws1);
|
||||
self.seen_macros.pop();
|
||||
self.seen_callers.pop();
|
||||
Ok(size_hint)
|
||||
@ -1119,9 +1119,10 @@ impl<'a> Generator<'a, '_> {
|
||||
if ***path == Expr::Var("super") {
|
||||
return self.write_block(ctx, buf, None, ws, s.span());
|
||||
} 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())
|
||||
})?;
|
||||
self.handle_ws(ws);
|
||||
let size_hint = self.push_locals(|this| {
|
||||
this.write_buf_writable(ctx, buf)?;
|
||||
buf.write('{');
|
||||
@ -1180,14 +1181,14 @@ impl<'a> Generator<'a, '_> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut size_hint = this.handle(ctx, &def.nodes, buf, AstLevel::Nested)?;
|
||||
|
||||
this.flush_ws(def.ws2);
|
||||
size_hint += this.write_buf_writable(ctx, buf)?;
|
||||
buf.write('}');
|
||||
Ok(size_hint)
|
||||
})?;
|
||||
self.prepare_ws(ws);
|
||||
self.seen_callers.push(def);
|
||||
return Ok(size_hint);
|
||||
}
|
||||
}
|
||||
|
@ -877,12 +877,11 @@ impl<'a> Import<'a> {
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Call<'a> {
|
||||
pub ws: Ws,
|
||||
pub ws1: Ws,
|
||||
pub caller_args: Vec<&'a str>,
|
||||
pub scope: Option<&'a str>,
|
||||
pub name: &'a str,
|
||||
pub args: Vec<WithSpan<'a, Expr<'a>>>,
|
||||
pub ws1: Ws,
|
||||
pub nodes: Vec<Node<'a>>,
|
||||
pub ws2: Ws,
|
||||
}
|
||||
@ -947,12 +946,11 @@ impl<'a> Call<'a> {
|
||||
|
||||
Ok(WithSpan::new(
|
||||
Self {
|
||||
ws: Ws(pws, nws),
|
||||
ws1: Ws(pws, nws),
|
||||
caller_args: call_args.unwrap_or_default(),
|
||||
scope,
|
||||
name,
|
||||
args,
|
||||
ws1: Ws(pws, pws2),
|
||||
nodes,
|
||||
ws2: Ws(pws2, nws2),
|
||||
},
|
||||
|
@ -125,17 +125,18 @@ nested
|
||||
assert_eq!(x.render().unwrap(), "nested");
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_caller_struct() {
|
||||
struct TestInput<'a> {
|
||||
a: &'a str,
|
||||
b: &'a str
|
||||
a: &'a str,
|
||||
b: &'a str,
|
||||
}
|
||||
#[derive(Template)]
|
||||
#[template(
|
||||
source = r#"
|
||||
{%- macro test(a) -%}
|
||||
{{caller(a)}}
|
||||
{{- caller(a) -}}
|
||||
{%- endmacro -%}
|
||||
{%- call(value) test(a) -%}
|
||||
a: {{value.a}}
|
||||
@ -145,13 +146,10 @@ b: {{value.b}}
|
||||
ext = "txt"
|
||||
)]
|
||||
struct Tmpl<'a> {
|
||||
a: TestInput<'a>
|
||||
a: TestInput<'a>,
|
||||
}
|
||||
let x = Tmpl {
|
||||
a: TestInput {
|
||||
a: "one",
|
||||
b: "two"
|
||||
}
|
||||
a: TestInput { a: "one", b: "two" },
|
||||
};
|
||||
assert_eq!(x.render().unwrap(), "a: one\nb: two");
|
||||
}
|
||||
@ -162,18 +160,18 @@ fn test_caller_args() {
|
||||
#[template(
|
||||
source = r#"
|
||||
{%- macro test() -%}
|
||||
{{- caller("test") -}}
|
||||
{{- caller(1) -}}
|
||||
{{~ caller("test") ~}}
|
||||
{{~ caller(1) ~}}
|
||||
{%- endmacro -%}
|
||||
{%- call(value) test() -%}
|
||||
nested {{value}}
|
||||
nested {{value}}
|
||||
{%- endcall -%}
|
||||
"#,
|
||||
ext = "html"
|
||||
)]
|
||||
struct 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.
|
||||
|
@ -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
|
||||
// macro arguments.
|
||||
#[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