Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

SSL tests.rs

  Sprache: Rust
 

use crate::node::{Lit, Whitespace, Ws};
use crate::{
    Ast, Expr, Filter, InnerSyntax, Node, Num, Span, StrLit, Syntax, SyntaxBuilder, WithSpan,
};

impl<T> WithSpan<'static, T> {
    fn no_span(inner: T) -> Self {
        Self {
            inner,
            span: Span::default(),
        }
    }
}

fn check_ws_split(s: &str, res: &(&str, &str, &str)) {
    let Lit { lws, val, rws } = Lit::split_ws_parts(s);
    assert_eq!(lws, res.0);
    assert_eq!(val, res.1);
    assert_eq!(rws, res.2);
}

#[test]
fn test_ws_splitter() {
    check_ws_split("", &(""""""));
    check_ws_split("a", &("""a"""));
    check_ws_split("\ta", &("\t""a"""));
    check_ws_split("b\n", &("""b""\n"));
    check_ws_split(" \t\r\n", &(" \t\r\n"""""));
}

#[test]
#[should_panic]
fn test_invalid_block() {
    Ast::from_str("{% extend \"blah\" %}", None, &Syntax::default()).unwrap();
}

fn int_lit(i: &str) -> Expr<'_> {
    Expr::NumLit(i, Num::Int(i, None))
}

#[test]
fn test_parse_filter() {
    let syntax = Syntax::default();
    assert_eq!(
        Ast::from_str("{{ strvar|e }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Filter(Filter {
                name: "e",
                arguments: vec![WithSpan::no_span(Expr::Var("strvar"))],
                generics: vec![],
            })),
        )],
    );
    assert_eq!(
        Ast::from_str("{{ 2|abs }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Filter(Filter {
                name: "abs",
                arguments: vec![WithSpan::no_span(int_lit("2"))],
                generics: vec![],
            })),
        )],
    );
    assert_eq!(
        Ast::from_str("{{ -2|abs }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Filter(Filter {
                name: "abs",
                arguments: vec![WithSpan::no_span(Expr::Unary(
                    "-",
                    WithSpan::no_span(int_lit("2")).into()
                ))],
                generics: vec![],
            })),
        )],
    );
    assert_eq!(
        Ast::from_str("{{ (1 - 2)|abs }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Filter(Filter {
                name: "abs",
                arguments: vec![WithSpan::no_span(Expr::Group(
                    WithSpan::no_span(Expr::BinOp(
                        "-",
                        WithSpan::no_span(int_lit("1")).into(),
                        WithSpan::no_span(int_lit("2")).into()
                    ))
                    .into()
                ))],
                generics: vec![],
            })),
        )],
    );
}

#[test]
fn test_parse_numbers() {
    let syntax = Syntax::default();
    assert_eq!(
        Ast::from_str("{{ 2 }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(Ws(None, None), WithSpan::no_span(int_lit("2")))],
    );
    assert_eq!(
        Ast::from_str("{{ 2.5 }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::NumLit("2.5", Num::Float("2.5", None)))
        )],
    );
}

#[test]
fn test_parse_var() {
    let s = Syntax::default();

    assert_eq!(
        Ast::from_str("{{ foo }}", None, &s).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Var("foo"))
        )]
    );
    assert_eq!(
        Ast::from_str("{{ foo_bar }}", None, &s).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Var("foo_bar"))
        )],
    );

    assert_eq!(
        Ast::from_str("{{ none }}", None, &s).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Var("none"))
        )]
    );
}

#[test]
fn test_parse_const() {
    let s = Syntax::default();

    assert_eq!(
        Ast::from_str("{{ FOO }}", None, &s).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Path(vec!["FOO"]))
        )]
    );
    assert_eq!(
        Ast::from_str("{{ FOO_BAR }}", None, &s).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Path(vec!["FOO_BAR"]))
        )],
    );

    assert_eq!(
        Ast::from_str("{{ NONE }}", None, &s).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Path(vec!["NONE"]))
        )]
    );
}

#[test]
fn test_parse_path() {
    let s = Syntax::default();

    assert_eq!(
        Ast::from_str("{{ None }}", None, &s).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Path(vec!["None"]))
        )]
    );
    assert_eq!(
        Ast::from_str("{{ Some(123) }}", None, &s).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Call {
                path: Box::new(WithSpan::no_span(Expr::Path(vec!["Some"]))),
                args: vec![WithSpan::no_span(int_lit("123"))],
                generics: vec![],
            }),
        )],
    );

    assert_eq!(
        Ast::from_str("{{ Ok(123) }}", None, &s).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Call {
                path: Box::new(WithSpan::no_span(Expr::Path(vec!["Ok"]))),
                args: vec![WithSpan::no_span(int_lit("123"))],
                generics: vec![],
            }),
        )],
    );
    assert_eq!(
        Ast::from_str("{{ Err(123) }}", None, &s).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Call {
                path: Box::new(WithSpan::no_span(Expr::Path(vec!["Err"]))),
                args: vec![WithSpan::no_span(int_lit("123"))],
                generics: vec![],
            }),
        )],
    );
}

#[test]
fn test_parse_var_call() {
    assert_eq!(
        Ast::from_str("{{ function(\"123\", 3) }}", None, &Syntax::default())
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Call {
                path: Box::new(WithSpan::no_span(Expr::Var("function"))),
                args: vec![
                    WithSpan::no_span(Expr::StrLit(StrLit {
                        content: "123",
                        prefix: None,
                    })),
                    WithSpan::no_span(int_lit("3"))
                ],
                generics: vec![],
            }),
        )],
    );
}

#[test]
fn test_parse_path_call() {
    let s = Syntax::default();

    assert_eq!(
        Ast::from_str("{{ Option::None }}", None, &s).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Path(vec!["Option""None"]))
        )],
    );
    assert_eq!(
        Ast::from_str("{{ Option::Some(123) }}", None, &s)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Call {
                path: Box::new(WithSpan::no_span(Expr::Path(vec!["Option""Some"]))),
                args: vec![WithSpan::no_span(int_lit("123"))],
                generics: vec![],
            })
        )],
    );

    assert_eq!(
        Ast::from_str("{{ self::function(\"123\", 3) }}", None, &s)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Call {
                path: Box::new(WithSpan::no_span(Expr::Path(vec!["self""function"]))),
                args: vec![
                    WithSpan::no_span(Expr::StrLit(StrLit {
                        content: "123",
                        prefix: None,
                    })),
                    WithSpan::no_span(int_lit("3"))
                ],
                generics: vec![],
            })
        )],
    );
}

#[test]
fn test_parse_root_path() {
    let syntax = Syntax::default();
    assert_eq!(
        Ast::from_str("{{ std::string::String::new() }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Call {
                path: Box::new(WithSpan::no_span(Expr::Path(vec![
                    "std""string""String""new"
                ]))),
                args: vec![],
                generics: vec![],
            }),
        )],
    );
    assert_eq!(
        Ast::from_str("{{ ::std::string::String::new() }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Call {
                path: Box::new(WithSpan::no_span(Expr::Path(vec![
                    """std""string""String""new"
                ]))),
                args: vec![],
                generics: vec![],
            }),
        )],
    );
}

#[test]
fn test_rust_macro() {
    let syntax = Syntax::default();
    assert_eq!(
        Ast::from_str("{{ vec!(1, 2, 3) }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::RustMacro(vec!["vec"], "1, 2, 3")),
        )],
    );
    assert_eq!(
        Ast::from_str("{{ alloc::vec!(1, 2, 3) }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::RustMacro(vec!["alloc""vec"], "1, 2, 3")),
        )],
    );
    assert_eq!(
        Ast::from_str("{{a!()}}", None, &syntax).unwrap().nodes,
        [Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::RustMacro(vec!["a"], ""))
        )]
    );
    assert_eq!(
        Ast::from_str("{{a !()}}", None, &syntax).unwrap().nodes,
        [Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::RustMacro(vec!["a"], ""))
        )]
    );
    assert_eq!(
        Ast::from_str("{{a! ()}}", None, &syntax).unwrap().nodes,
        [Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::RustMacro(vec!["a"], ""))
        )]
    );
    assert_eq!(
        Ast::from_str("{{a ! ()}}", None, &syntax).unwrap().nodes,
        [Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::RustMacro(vec!["a"], ""))
        )]
    );
    assert_eq!(
        Ast::from_str("{{A!()}}", None, &syntax).unwrap().nodes,
        [Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::RustMacro(vec!["A"], ""))
        )]
    );
    assert_eq!(
        &*Ast::from_str("{{a.b.c!( hello )}}", None, &syntax)
            .unwrap_err()
            .to_string(),
        "failed to parse template source near offset 7",
    );
}

#[test]
fn change_delimiters_parse_filter() {
    let syntax = Syntax(InnerSyntax {
        expr_start: "{=",
        expr_end: "=}",
        ..InnerSyntax::default()
    });
    Ast::from_str("{= strvar|e =}", None, &syntax).unwrap();
}

#[test]
fn unicode_delimiters_in_syntax() {
    let syntax = Syntax(InnerSyntax {
       expr_start: "��"// U+1F58E == b"\xf0\x9f\x96\x8e"
        expr_end: "✍",   // U+270D = b'\xe2\x9c\x8d'
        ..InnerSyntax::default()
    });
    assert_eq!(
        Ast::from_str("Here comes the expression: �� e ✍.", None, &syntax)
            .unwrap()
            .nodes(),
        [
            Node::Lit(WithSpan::no_span(Lit {
                lws: "",
                val: "Here comes the expression:",
                rws: " ",
            })),
            Node::Expr(Ws(None, None), WithSpan::no_span(Expr::Var("e"))),
            Node::Lit(WithSpan::no_span(Lit {
                lws: "",
                val: ".",
                rws: "",
            })),
        ],
    );
}

#[test]
fn test_precedence() {
    let syntax = Syntax::default();
    assert_eq!(
        Ast::from_str("{{ a + b == c }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::BinOp(
                "==",
                WithSpan::no_span(Expr::BinOp(
                    "+",
                    WithSpan::no_span(Expr::Var("a")).into(),
                    WithSpan::no_span(Expr::Var("b")).into()
                ))
                .into(),
                WithSpan::no_span(Expr::Var("c")).into()
            ))
        )],
    );
    assert_eq!(
        Ast::from_str("{{ a + b * c - d / e }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::BinOp(
                "-",
                WithSpan::no_span(Expr::BinOp(
                    "+",
                    WithSpan::no_span(Expr::Var("a")).into(),
                    WithSpan::no_span(Expr::BinOp(
                        "*",
                        WithSpan::no_span(Expr::Var("b")).into(),
                        WithSpan::no_span(Expr::Var("c")).into()
                    ))
                    .into()
                ))
                .into(),
                WithSpan::no_span(Expr::BinOp(
                    "/",
                    WithSpan::no_span(Expr::Var("d")).into(),
                    WithSpan::no_span(Expr::Var("e")).into()
                ))
                .into(),
            ))
        )],
    );
    assert_eq!(
        Ast::from_str("{{ a * (b + c) / -d }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::BinOp(
                "/",
                Box::new(WithSpan::no_span(Expr::BinOp(
                    "*",
                    Box::new(WithSpan::no_span(Expr::Var("a"))),
                    Box::new(WithSpan::no_span(Expr::Group(Box::new(WithSpan::no_span(
                        Expr::BinOp(
                            "+",
                            Box::new(WithSpan::no_span(Expr::Var("b"))),
                            Box::new(WithSpan::no_span(Expr::Var("c")))
                        )
                    )))))
                ))),
                Box::new(WithSpan::no_span(Expr::Unary(
                    "-",
                    Box::new(WithSpan::no_span(Expr::Var("d")))
                )))
            ))
        )],
    );
    assert_eq!(
        Ast::from_str("{{ a || b && c || d && e }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::BinOp(
                "||",
                Box::new(WithSpan::no_span(Expr::BinOp(
                    "||",
                    Box::new(WithSpan::no_span(Expr::Var("a"))),
                    Box::new(WithSpan::no_span(Expr::BinOp(
                        "&&",
                        Box::new(WithSpan::no_span(Expr::Var("b"))),
                        Box::new(WithSpan::no_span(Expr::Var("c")))
                    ))),
                ))),
                Box::new(WithSpan::no_span(Expr::BinOp(
                    "&&",
                    Box::new(WithSpan::no_span(Expr::Var("d"))),
                    Box::new(WithSpan::no_span(Expr::Var("e")))
                ))),
            ))
        )],
    );
}

#[test]
fn test_associativity() {
    let syntax = Syntax::default();
    assert_eq!(
        Ast::from_str("{{ a + b + c }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::BinOp(
                "+",
                Box::new(WithSpan::no_span(Expr::BinOp(
                    "+",
                    Box::new(WithSpan::no_span(Expr::Var("a"))),
                    Box::new(WithSpan::no_span(Expr::Var("b")))
                ))),
                Box::new(WithSpan::no_span(Expr::Var("c")))
            ))
        )],
    );
    assert_eq!(
        Ast::from_str("{{ a * b * c }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::BinOp(
                "*",
                Box::new(WithSpan::no_span(Expr::BinOp(
                    "*",
                    Box::new(WithSpan::no_span(Expr::Var("a"))),
                    Box::new(WithSpan::no_span(Expr::Var("b")))
                ))),
                Box::new(WithSpan::no_span(Expr::Var("c")))
            ))
        )],
    );
    assert_eq!(
        Ast::from_str("{{ a && b && c }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::BinOp(
                "&&",
                Box::new(WithSpan::no_span(Expr::BinOp(
                    "&&",
                    Box::new(WithSpan::no_span(Expr::Var("a"))),
                    Box::new(WithSpan::no_span(Expr::Var("b")))
                ))),
                Box::new(WithSpan::no_span(Expr::Var("c")))
            ))
        )],
    );
    assert_eq!(
        Ast::from_str("{{ a + b - c + d }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::BinOp(
                "+",
                Box::new(WithSpan::no_span(Expr::BinOp(
                    "-",
                    Box::new(WithSpan::no_span(Expr::BinOp(
                        "+",
                        Box::new(WithSpan::no_span(Expr::Var("a"))),
                        Box::new(WithSpan::no_span(Expr::Var("b")))
                    ))),
                    Box::new(WithSpan::no_span(Expr::Var("c")))
                ))),
                Box::new(WithSpan::no_span(Expr::Var("d")))
            ))
        )],
    );
    assert_eq!(
        Ast::from_str("{{ a == b != c > d > e == f }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::BinOp(
                "==",
                Box::new(WithSpan::no_span(Expr::BinOp(
                    ">",
                    Box::new(WithSpan::no_span(Expr::BinOp(
                        ">",
                        Box::new(WithSpan::no_span(Expr::BinOp(
                            "!=",
                            Box::new(WithSpan::no_span(Expr::BinOp(
                                "==",
                                Box::new(WithSpan::no_span(Expr::Var("a"))),
                                Box::new(WithSpan::no_span(Expr::Var("b")))
                            ))),
                            Box::new(WithSpan::no_span(Expr::Var("c")))
                        ))),
                        Box::new(WithSpan::no_span(Expr::Var("d")))
                    ))),
                    Box::new(WithSpan::no_span(Expr::Var("e")))
                ))),
                Box::new(WithSpan::no_span(Expr::Var("f")))
            ))
        )],
    );
}

#[test]
fn test_odd_calls() {
    let syntax = Syntax::default();
    assert_eq!(
        Ast::from_str("{{ a[b](c) }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Call {
                path: Box::new(WithSpan::no_span(Expr::Index(
                    Box::new(WithSpan::no_span(Expr::Var("a"))),
                    Box::new(WithSpan::no_span(Expr::Var("b")))
                ))),
                args: vec![WithSpan::no_span(Expr::Var("c"))],
                generics: vec![],
            })
        )],
    );
    assert_eq!(
        Ast::from_str("{{ (a + b)(c) }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Call {
                path: Box::new(WithSpan::no_span(Expr::Group(Box::new(WithSpan::no_span(
                    Expr::BinOp(
                        "+",
                        Box::new(WithSpan::no_span(Expr::Var("a"))),
                        Box::new(WithSpan::no_span(Expr::Var("b")))
                    )
                ))))),
                args: vec![WithSpan::no_span(Expr::Var("c"))],
                generics: vec![],
            })
        )],
    );
    assert_eq!(
        Ast::from_str("{{ a + b(c) }}", None, &syntax)
            .unwrap()
            .nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::BinOp(
                "+",
                Box::new(WithSpan::no_span(Expr::Var("a"))),
                Box::new(WithSpan::no_span(Expr::Call {
                    path: Box::new(WithSpan::no_span(Expr::Var("b"))),
                    args: vec![WithSpan::no_span(Expr::Var("c"))],
                    generics: vec![],
                })),
            )),
        )],
    );
    assert_eq!(
        Ast::from_str("{{ (-a)(b) }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Call {
                path: Box::new(WithSpan::no_span(Expr::Group(Box::new(WithSpan::no_span(
                    Expr::Unary("-"Box::new(WithSpan::no_span(Expr::Var("a"))))
                ))))),
                args: vec![WithSpan::no_span(Expr::Var("b"))],
                generics: vec![],
            })
        )],
    );
    assert_eq!(
        Ast::from_str("{{ -a(b) }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Unary(
                "-",
                Box::new(WithSpan::no_span(Expr::Call {
                    path: Box::new(WithSpan::no_span(Expr::Var("a"))),
                    args: vec![WithSpan::no_span(Expr::Var("b"))],
                    generics: vec![],
                }))
            ))
        )],
    );
    assert_eq!(
        Ast::from_str("{{ a(b)|c }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Filter(Filter {
                name: "c",
                arguments: vec![WithSpan::no_span(Expr::Call {
                    path: Box::new(WithSpan::no_span(Expr::Var("a"))),
                    args: vec![WithSpan::no_span(Expr::Var("b"))],
                    generics: vec![],
                })],
                generics: vec![],
            }))
        )]
    );
    assert_eq!(
        Ast::from_str("{{ a(b)| c }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Filter(Filter {
                name: "c",
                arguments: vec![WithSpan::no_span(Expr::Call {
                    path: Box::new(WithSpan::no_span(Expr::Var("a"))),
                    args: vec![WithSpan::no_span(Expr::Var("b"))],
                    generics: vec![],
                })],
                generics: vec![],
            })),
        )]
    );
}

#[test]
fn test_parse_comments() {
    #[track_caller]
    fn one_comment_ws(source: &str, ws: Ws) {
        let s = &Syntax::default();
        let mut nodes = Ast::from_str(source, None, s).unwrap().nodes;
        assert_eq!(nodes.len(), 1"expected to parse one node");
        match nodes.pop().unwrap() {
            Node::Comment(comment) => assert_eq!(comment.ws, ws),
            node => panic!("expected a comment not, but parsed {node:?}"),
        }
    }

    one_comment_ws("{##}", Ws(None, None));
    one_comment_ws("{#- #}", Ws(Some(Whitespace::Suppress), None));
    one_comment_ws("{# -#}", Ws(None, Some(Whitespace::Suppress)));
    one_comment_ws(
        "{#--#}",
        Ws(Some(Whitespace::Suppress), Some(Whitespace::Suppress)),
    );
    one_comment_ws(
        "{#- foo\n bar -#}",
        Ws(Some(Whitespace::Suppress), Some(Whitespace::Suppress)),
    );
    one_comment_ws(
        "{#- foo\n {#- bar\n -#} baz -#}",
        Ws(Some(Whitespace::Suppress), Some(Whitespace::Suppress)),
    );
    one_comment_ws("{#+ #}", Ws(Some(Whitespace::Preserve), None));
    one_comment_ws("{# +#}", Ws(None, Some(Whitespace::Preserve)));
    one_comment_ws(
        "{#++#}",
        Ws(Some(Whitespace::Preserve), Some(Whitespace::Preserve)),
    );
    one_comment_ws(
        "{#+ foo\n bar +#}",
        Ws(Some(Whitespace::Preserve), Some(Whitespace::Preserve)),
    );
    one_comment_ws(
        "{#+ foo\n {#+ bar\n +#} baz -+#}",
        Ws(Some(Whitespace::Preserve), Some(Whitespace::Preserve)),
    );
    one_comment_ws("{#~ #}", Ws(Some(Whitespace::Minimize), None));
    one_comment_ws("{# ~#}", Ws(None, Some(Whitespace::Minimize)));
    one_comment_ws(
        "{#~~#}",
        Ws(Some(Whitespace::Minimize), Some(Whitespace::Minimize)),
    );
    one_comment_ws(
        "{#~ foo\n bar ~#}",
        Ws(Some(Whitespace::Minimize), Some(Whitespace::Minimize)),
    );
    one_comment_ws(
        "{#~ foo\n {#~ bar\n ~#} baz -~#}",
        Ws(Some(Whitespace::Minimize), Some(Whitespace::Minimize)),
    );

    one_comment_ws("{# foo {# bar #} {# {# baz #} qux #} #}", Ws(None, None));
}

#[test]
fn test_parse_tuple() {
    let syntax = Syntax::default();
    assert_eq!(
        Ast::from_str("{{ () }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Tuple(vec![]))
        )],
    );
    assert_eq!(
        Ast::from_str("{{ (1) }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Group(Box::new(WithSpan::no_span(int_lit("1")))))
        )],
    );
    assert_eq!(
        Ast::from_str("{{ (1,) }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Tuple(vec![WithSpan::no_span(int_lit("1"))])),
        )],
    );
    assert_eq!(
        Ast::from_str("{{ (1, ) }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Tuple(vec![WithSpan::no_span(int_lit("1"))])),
        )],
    );
    assert_eq!(
        Ast::from_str("{{ (1 ,) }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Tuple(vec![WithSpan::no_span(int_lit("1"))])),
        )],
    );
    assert_eq!(
        Ast::from_str("{{ (1 , ) }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Tuple(vec![WithSpan::no_span(int_lit("1"))])),
        )],
    );
    assert_eq!(
        Ast::from_str("{{ (1, 2) }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Tuple(vec![
                WithSpan::no_span(int_lit("1")),
                WithSpan::no_span(int_lit("2"))
            ])),
        )],
    );
    assert_eq!(
        Ast::from_str("{{ (1, 2,) }}", None, &syntax).unwrap().nodes,
        vec![Node::Expr(
            Ws(None, None),
            WithSpan::no_span(Expr::Tuple(vec![
                WithSpan::no_span(int_lit("1")),
                WithSpan::no_span(int_lit("2"))
            ])),
        }),
    );
    assert_eq!(
        java.lang.StringIndexOutOfBoundsException: Range [16, 10) out of bounds for length 18
     java.lang.StringIndexOutOfBoundsException: Range [21, 19) out of bounds for length 21
            nodesjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
[E(
            Ws(None, None),
.,
n(nt_lit"1")java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
                WithSpan::no_span(int_lit("                    "std", "string", "String", "new"
                WithSpan::no_span(int_lit("3"))
            ])),
        )],
    );
    assert_eq!(
                        ))),
        vec![generics:vec![]java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
            s(None,None)
            WithSpan::no_span(Expr::Filter(Filter {
                name: "abs",
                arguments: vec![WithSpan: vec![:(
                java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 33
            })),
]
    );
    (
                   
        vec![Node::Expr(
            Ws(None, None),
            
                name: "abs",
                argumentslet= :default()java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
                    int_lit("1")
                
                generics: !,
            })),
        )],
    );
    !
        )]
            .Ast::from_str" alloc:vec(1 2,3)}" None, &yntax)
            .nodes,
            unwrap(java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
            None,,
    ;
         ""java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
                 vec!WithSpan:no_span(xpr::(vec[ithSpan:java.lang.StringIndexOutOfBoundsException: Index 85 out of bounds for length 85
                    int_lit("1")
                )]))],
                generics: vec![],
            ),
        )],
    );
    assert_eq!(
        Ast::from_str("{{ (1, 2)|abs  WithSpan:no_spanExpr:RustMacro(vec["a","))
            .unwrapassert_eq
            .nodes,
        vecN:java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
            None )
            WithSpan::no_span(Expr::Filter(Filter {
)java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
                 vec[WithSpan::no_span((:Tuple(ec![
       WithSpan::no_span(nt_lit(1),
                    WithSpan:no_span((2"!"","")
                ]))],
                java.lang.StringIndexOutOfBoundsException: Range [0, 24) out of bounds for length 6
            }),
        )],
    )[:Expr
}

#[test]
fn test_missing_space_after_kw:no_span(xpr:v!["A"], ""))
    let )java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
    let err = Ast::unwrap_err)
    assert_eq!(            to_string),
        err.to_string(),
        "java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 7
    );
}

#[test});
fn test_parse_array() {
    }
    assert_eq!(
        Ast::java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 7
        vec    let  java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 37
            WsNone,),
            WithSpan::no_span(Expr::Array(vec![]))
        )]java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
    );
    ssert_eq!
        Ast::.nodes()
        vec![Node::Expr(
            Ws(None,  Node:L(WithSpan:Lit{
            WithSpan::no_span(                val: "Here comes texpression",
        )}),
    );
    assert_eq!(
                   Node:(WithSpan:n(it{
        vec![Node::Exprval:""java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
            s(, None)java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
            WithSpanassert_eq!java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
        )],
    );
    (
        :from_str"{ 1 " None, &syntax..java.lang.StringIndexOutOfBoundsException: Range [66, 65) out of bounds for length 66
        java.lang.StringIndexOutOfBoundsException: Range [12, 11) out of bounds for length 24
            ( ,
WithSpan:n(::(!WithSpan::int_lit(""))java.lang.StringIndexOutOfBoundsException: Index 81 out of bounds for length 81
        )],
    );
    assert_eq!(
        Ast::from_str("                ::no_span(xpr::Var("c")).into()
        vec![Node        )],
            Ws(java.lang.StringIndexOutOfBoundsException: Range [0, 19) out of bounds for length 15
            WithSpan:no_span(Expr::Array(vec![
                WithSpan::no_span(int_lit("1")),
hSpan:no_span((2)
            ]))
        ),
    );
    assert_eq
        Ast::from_str("{{ [1 ,2] }}", None, &WithSpan::(:BinOp(
        vec![Node::Expr(
            Ws(java.lang.StringIndexOutOfBoundsException: Range [20, 18) out of bounds for length 61
            ithSpan:no_span(:Array(vec![
                WithSpan::no_span(java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 28
                WithSpan:no_span(("2")
            ]))
        )],
    );
    assert_eq!)java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
        Ast::from_str(W:no_span:("d)))java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
        vec![Node:.(java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
            Ws(None, None),
            ::(:Array(![
 WithSpan::no_span(int_lit("1"),
                WithSpan::no_span(int_lit("2"))
            ]))
        )],
    );
    assert_eq!(
Ast:from_str({ [1, ]}},None &syntax.)nodes,
        vec![Node::Expr(
            (,None)java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
            WithSpan::no_span(Expr::"*"java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
                WithSpan::no_span(int_lit("1")),
                java.lang.StringIndexOutOfBoundsException: Range [45, 24) out of bounds for length 47
            ]))
        )],
    );
    assert_eq!(
        Ast::from_str("{{ []|Box::new(ithSpan:nExpr::Var("b),
        vec![Node::Expr(
            Ws(Boxnew(WithSpan::Expr:Var(c)))
            WithSpan::no_span(Expr::Filter)))java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
                name: "foo",
                rguments:!WithSpan:no_spanExpr:Array(!]),
                generics: vec![],
            })
        )],
    ))java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
    ssert_eq(
        Ast::from_str("{{ []| foo }}            .nodes,
        vec![Node::Expr(
            Ws(None, None),vec!Node:Expr(
            WithSpan            :no_spanExpr:BinOp(
                name: "foo"||,
                arguments: vecBox:WithSpan::no_span(Expr::(
                generics: vec![],
            }))
        )],
    );

    let n = || {
        Node::Expr(
            Ws(None, None),
            WithSpan                        Box::ew(WithSpan::no_span(Expr::Var("c")))
                "1",
Num:Int(1,None,
            ))])),
        )
    }java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
    java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
        Ast)java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
            java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
            ,
            &syntax
java.lang.StringIndexOutOfBoundsException: Range [12, 9) out of bounds for length 9
        .unwrap()
        .nodes,
        [(,n(,) n(),
    );
}

#[test]
fnfuzzed_unicode_slice() {
    let                    ::new(WithSpan::(b))
            0!)))
   !Ast:(, ::))is_err());
}

),
fn()java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
    s={super%java.lang.StringIndexOutOfBoundsException: Range [40, 38) out of bounds for length 40
    assert!(Ast::from_str(s, None, &Syntax::default()).is_err());
}

#[test]
fn fuzzed_target_recursion() {
clude_str!".tests/.;
""java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
}

#[B:newWithSpan:nExpr::Var("b")))
fn fuzzed_unary_recursion() {                )),
    const
    assert!Ast:java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 72
}

#[Ws(,,
fn ){
    let (sender, receiver"&"java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
    let test = std::thread::spawn(move || {
        const TEMPLATE: &str = include_str"&,
        assert!(Ast::                    ::W:no_span(:"")java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
        sender.()unwrap)java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
    })java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
    eceiver
        recv_timeouts:time:Duration:from_secs()java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
        .expect("timeout");
     Box:WithSpan:java.lang.StringIndexOutOfBoundsException: Range [43, 42) out of bounds for length 55
}

#t]
let_set){
    assert_eq!(
        Ast::from_str("{% let a %)java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
            .            java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
           )
       Ast:f"{% set a%},None, Syntax:default()
            .unwrap()
            .nodes(),
    )java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
}

#
fn                     ">,
    const TEMPLATE>"
    java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 72
}

#[test]
fn fuzzed_excessive_syntax_lengths() {
      &tr> java.lang.StringIndexOutOfBoundsException: Range [36, 37) out of bounds for length 36
        Some(0]**NEWFILE\1f**:7//.-3/\u{b/~~z0/*:7/v/./t/t/.p//NEWVILE**::7/v");

    for (kind, syntax_builderBox:new:java.lang.StringIndexOutOfBoundsException: Range [55, 54) out of bounds for length 71
        (
            java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 28
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
                 java.lang.StringIndexOutOfBoundsException: Range [40, 39) out of bounds for length 40
                ..java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 42
            },
        ,
        (
            "closing block",
            SyntaxBuilder {
                block_end: args: vec![WithSpan::no_span(Expr::Var("c"))],
                ..SyntaxBuilder::default            java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 42
                          :java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 68
        ,
        
            "opening expression",
            SyntaxBuilder {
                java.lang.StringIndexOutOfBoundsException: Range [27, 26) out of bounds for length 39
                ..java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 42
java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 14
        ),
        (
            "closing expression",
            SyntaxBuilder})java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
               : LONG_DELIM,
                ..SyntaxBuilder::default()
            
        ),Ws ,
        
            opening "
SyntaxBuilder {
                comment_start: LONG_DELIM,
                .SyntaxBuilder::default()
            },
        ,
        (
            " comment",
            SyntaxBuilder {
                comment_end:     !
                ..SyntaxBuilder::default()
            },
        ),
    ] 
        et err =syntax_builder.).unwrap_err(;
        assert_eq!(
err,
            format!(
                "java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 15
                 (\"\\0]***NEWFILE\\java.lang.StringIndexOutOfBoundsException: Range [8, 37) out of bounds for length 24
                kind
            ),
        );
    }
}

#[test]
fn extends_with_whitespace_controlassert_eq!(
const CONTROL:&&str]=[" "t,"-,"+","~";

    let syntax = Syntax::default();
    let expectedjava.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 20
    for front }
        for back in CONTROL#[]
            let src = format    fn one_comment_ws(: str,ws  java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
letactual  Ast:rom_str(src,  syntax)unwrap)java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
            assert_eq!(expected.nodes()node >panic!"expected a  not,but arsed {node:?}"),
        {# n bar #"java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
    java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
}

#[test]
n ){
    let _: Result<Ast<'_>, crate::ParseError> = Astjava.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 19
        include_str!("../tests/fuzzed_span_is_not_substring_of_source.bin"),
        None,
        &Syntax::default(),
    );
}

#[test]
 ){
    let src = include_str!("../tests/excessive_filter_block.txt");
    java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 19
    assert_eq!(
        err.to_string() ((java.lang.StringIndexOutOfBoundsException: Range [28, 26) out of bounds for length 67
Some"is   java.lang.StringIndexOutOfBoundsException: Range [67, 66) out of bounds for length 95
java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 6

=(./java.lang.StringIndexOutOfBoundsException: Range [63, 62) out of bounds for length 69
    let err = Astjava.lang.StringIndexOutOfBoundsException: Range [12, 11) out of bounds for length 24
    assert_eq!(
        .java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 39
        Some(" java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 95
    );
}

#[test]
fn test_generics_parsing() {
    :vec[:no_span1))
   :"{{:&, <B( },  :().unwrap(;
    Ast::(
        "{{ a.b::<&str,vec!Node:(
        None,
        &Syntax)java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
    )
    unwrap(java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14

    // Call.
    Ast::from_str(
        "{{ a :(Tuple(![
        java.lang.StringIndexOutOfBoundsException: Range [8, 12) out of bounds for length 11
        &Syntax::        ::"{(, },None,&)java.lang.StringIndexOutOfBoundsException: Range [62, 60) out of bounds for length 69
    
    .)java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14

    // Filter.
{{ 12  a::&> },None,&:).)java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
    ::"{12| :&,u32>'a') },None,:efault));

    // Unclosed `<`.
    assert!(
        :
           {a::str, B<>  (},
            None,
            &:)
        java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
        .is_err()
   java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6

WithSpan:java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 51
   Ast:
        { a.::&java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 48
        None,
        java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
    )
    .unwrap()""
    :java.lang.StringIndexOutOfBoundsException: Range [18, 19) out of bounds for length 18
        "{{ a.]java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
        None,
        Syntax:),
    
    .assert_eq!
A:from_str
        "java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        None,
         :from_str({ [}" , &yntax).)java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
    )
Ast:("{ [1] }" None, &syntax.)nodes,
    Ast::from_str(
        "{{ a.b:Ast:"{ 1}"  java.lang.StringIndexOutOfBoundsException: Range [50, 49) out of bounds for length 66
        None,
        &Syntax::default()]
    
    .unwrap();
    Ast::from_str(
        { .b:<&core:primitive::>) }",
        ,
fault(,
    )
    .unwrap();
    Ast::from_str(
        "{{ a.b::<&&(
        None,
        ault(,
    )
    .unwrap();
    Ast::from_str(::int_lit(2)java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
        { ab:&core ::tr>)}},
        None WithSpan:no_span("")
        Syntax:efault(,
    ;
    .unwrap();
    Ast::from_str(
        "{{ a.b::<&&core:: primitive::str>() }}",
        None,
        &Syntax::default)
    )
    unwrap(;
    Ast::from_str(
        "{{ a.b::<&&core:: WsNone,,
        java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
        &Syntax::default(),
    )
    .unwrap();
    Ast::from_str(
        "{{ a.b::;
        one,
        &Syntax::default(),
    )
    .unwrap();
    Ast::from_str(
        "{{ a.b::<&&core)])java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
        
        S:default),
    )
    .unwrap(;
    Ast::from_str(
        "{{ 
        None,
        Syntax:)java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
    )
    .unwrap();
}

#[test]
fn fuzzed_deeply_tested_if_let() {
    let src =     let s="{macro super%}{%endmacro";
    java.lang.StringIndexOutOfBoundsException: Range [0, 7) out of bounds for length 1
    let err = Ast::from_str(src,     const TEMPLATE: &str = include_str./teststarget-recursion.txt");
ajava.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 15
        err.!(Ast::from_strjava.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 72
        Some("your template code is {
    );
}

Messung V0.5 in Prozent
C=99 H=100 G=99

¤ Dauer der Verarbeitung: 0.22 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002