Add tests for dust parser
This commit is contained in:
parent
bec69557fc
commit
87a7024bf0
@ -2,10 +2,13 @@ use nom::branch::alt;
|
|||||||
use nom::bytes::complete::is_a;
|
use nom::bytes::complete::is_a;
|
||||||
use nom::bytes::complete::tag;
|
use nom::bytes::complete::tag;
|
||||||
use nom::bytes::complete::take_until;
|
use nom::bytes::complete::take_until;
|
||||||
|
use nom::character::complete::one_of;
|
||||||
use nom::combinator::map;
|
use nom::combinator::map;
|
||||||
|
use nom::combinator::opt;
|
||||||
use nom::combinator::recognize;
|
use nom::combinator::recognize;
|
||||||
use nom::combinator::rest;
|
use nom::combinator::rest;
|
||||||
use nom::combinator::value;
|
use nom::combinator::value;
|
||||||
|
use nom::combinator::verify;
|
||||||
use nom::multi::many0;
|
use nom::multi::many0;
|
||||||
use nom::multi::separated_list;
|
use nom::multi::separated_list;
|
||||||
use nom::sequence::delimited;
|
use nom::sequence::delimited;
|
||||||
@ -20,7 +23,7 @@ enum DustTag<'a> {
|
|||||||
DTReference(Reference<'a>),
|
DTReference(Reference<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
enum Special {
|
enum Special {
|
||||||
Space,
|
Space,
|
||||||
NewLine,
|
NewLine,
|
||||||
@ -29,23 +32,23 @@ enum Special {
|
|||||||
RightCurlyBrace,
|
RightCurlyBrace,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
struct Comment<'a> {
|
struct Comment<'a> {
|
||||||
value: &'a str,
|
value: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
struct Path<'a> {
|
struct Path<'a> {
|
||||||
keys: Vec<&'a str>,
|
keys: Vec<&'a str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
struct Reference<'a> {
|
struct Reference<'a> {
|
||||||
path: Path<'a>,
|
path: Path<'a>,
|
||||||
filters: Vec<Filter>,
|
filters: Vec<Filter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
enum Filter {
|
enum Filter {
|
||||||
HtmlEncode,
|
HtmlEncode,
|
||||||
DisableHtmlEncode,
|
DisableHtmlEncode,
|
||||||
@ -56,6 +59,7 @@ enum Filter {
|
|||||||
JsonParse,
|
JsonParse,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
struct Span<'a> {
|
struct Span<'a> {
|
||||||
contents: &'a str,
|
contents: &'a str,
|
||||||
}
|
}
|
||||||
@ -81,11 +85,11 @@ fn special(i: &str) -> IResult<&str, Special> {
|
|||||||
delimited(
|
delimited(
|
||||||
tag("{~"),
|
tag("{~"),
|
||||||
alt((
|
alt((
|
||||||
|
value(Special::LeftCurlyBrace, tag("lb")),
|
||||||
|
value(Special::RightCurlyBrace, tag("rb")),
|
||||||
value(Special::Space, tag("s")),
|
value(Special::Space, tag("s")),
|
||||||
value(Special::NewLine, tag("s")),
|
value(Special::NewLine, tag("n")),
|
||||||
value(Special::CarriageReturn, tag("s")),
|
value(Special::CarriageReturn, tag("r")),
|
||||||
value(Special::LeftCurlyBrace, tag("s")),
|
|
||||||
value(Special::RightCurlyBrace, tag("s")),
|
|
||||||
)),
|
)),
|
||||||
tag("}"),
|
tag("}"),
|
||||||
)(i)
|
)(i)
|
||||||
@ -102,8 +106,10 @@ fn path(i: &str) -> IResult<&str, Path> {
|
|||||||
separated_list(
|
separated_list(
|
||||||
tag("."),
|
tag("."),
|
||||||
recognize(tuple((
|
recognize(tuple((
|
||||||
is_a("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$"),
|
one_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$"),
|
||||||
is_a("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$0123456789-"),
|
opt(is_a(
|
||||||
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$0123456789-",
|
||||||
|
)),
|
||||||
))),
|
))),
|
||||||
),
|
),
|
||||||
|body| Path { keys: body },
|
|body| Path { keys: body },
|
||||||
@ -138,7 +144,7 @@ fn filter(i: &str) -> IResult<&str, Filter> {
|
|||||||
|
|
||||||
/// Any text that is not a Dust element
|
/// Any text that is not a Dust element
|
||||||
fn span(i: &str) -> IResult<&str, Span> {
|
fn span(i: &str) -> IResult<&str, Span> {
|
||||||
let (remaining, body) = alt((take_until("{"), rest))(i)?;
|
let (remaining, body) = verify(alt((take_until("{"), rest)), |s: &str| s.len() > 0)(i)?;
|
||||||
Ok((remaining, Span { contents: body }))
|
Ok((remaining, Span { contents: body }))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,3 +160,106 @@ pub fn template(i: &str) -> IResult<&str, Template> {
|
|||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use nom::bytes::complete::is_a;
|
||||||
|
use nom::error::ErrorKind;
|
||||||
|
use nom::Err::Error;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_reference() {
|
||||||
|
assert_eq!(
|
||||||
|
super::reference("{foo.bar.baz|js|s}"),
|
||||||
|
Ok((
|
||||||
|
"",
|
||||||
|
Reference {
|
||||||
|
path: Path {
|
||||||
|
keys: vec!["foo", "bar", "baz"]
|
||||||
|
},
|
||||||
|
filters: vec![Filter::JsonStringify, Filter::DisableHtmlEncode],
|
||||||
|
}
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_path() {
|
||||||
|
assert_eq!(
|
||||||
|
is_a::<_, _, (_, ErrorKind)>("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$")(
|
||||||
|
"foo"
|
||||||
|
),
|
||||||
|
Ok(("", "foo"))
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
super::path("foo.bar.baz"),
|
||||||
|
Ok((
|
||||||
|
"",
|
||||||
|
Path {
|
||||||
|
keys: vec!["foo", "bar", "baz"]
|
||||||
|
}
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_special() {
|
||||||
|
assert_eq!(super::special("{~s}"), Ok(("", Special::Space)));
|
||||||
|
assert_eq!(super::special("{~n}"), Ok(("", Special::NewLine)));
|
||||||
|
assert_eq!(super::special("{~r}"), Ok(("", Special::CarriageReturn)));
|
||||||
|
assert_eq!(super::special("{~lb}"), Ok(("", Special::LeftCurlyBrace)));
|
||||||
|
assert_eq!(super::special("{~rb}"), Ok(("", Special::RightCurlyBrace)));
|
||||||
|
assert_eq!(
|
||||||
|
super::special("{~zzz}"),
|
||||||
|
Err(Error(("zzz}", ErrorKind::Tag)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_comment() {
|
||||||
|
assert_eq!(
|
||||||
|
super::comment("{! yo dawg} this is a comment !}"),
|
||||||
|
Ok((
|
||||||
|
"",
|
||||||
|
Comment {
|
||||||
|
value: " yo dawg} this is a comment "
|
||||||
|
}
|
||||||
|
))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
super::special("{! this is a comment without a close"),
|
||||||
|
Err(Error((
|
||||||
|
"{! this is a comment without a close",
|
||||||
|
ErrorKind::Tag
|
||||||
|
)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_span() {
|
||||||
|
assert_eq!(
|
||||||
|
super::span("this is just some text"),
|
||||||
|
Ok((
|
||||||
|
"",
|
||||||
|
Span {
|
||||||
|
contents: "this is just some text"
|
||||||
|
}
|
||||||
|
))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
super::span("this is just some text {~lb}"),
|
||||||
|
Ok((
|
||||||
|
"{~lb}",
|
||||||
|
Span {
|
||||||
|
contents: "this is just some text "
|
||||||
|
}
|
||||||
|
))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
super::span("{~lb}"),
|
||||||
|
Err(Error(("{~lb}", ErrorKind::Verify)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user