Add tests for dust parser

This commit is contained in:
Tom Alexander 2020-04-04 22:45:56 -04:00
parent bec69557fc
commit 87a7024bf0
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE

View File

@ -2,10 +2,13 @@ use nom::branch::alt;
use nom::bytes::complete::is_a;
use nom::bytes::complete::tag;
use nom::bytes::complete::take_until;
use nom::character::complete::one_of;
use nom::combinator::map;
use nom::combinator::opt;
use nom::combinator::recognize;
use nom::combinator::rest;
use nom::combinator::value;
use nom::combinator::verify;
use nom::multi::many0;
use nom::multi::separated_list;
use nom::sequence::delimited;
@ -20,7 +23,7 @@ enum DustTag<'a> {
DTReference(Reference<'a>),
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
enum Special {
Space,
NewLine,
@ -29,23 +32,23 @@ enum Special {
RightCurlyBrace,
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
struct Comment<'a> {
value: &'a str,
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
struct Path<'a> {
keys: Vec<&'a str>,
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
struct Reference<'a> {
path: Path<'a>,
filters: Vec<Filter>,
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
enum Filter {
HtmlEncode,
DisableHtmlEncode,
@ -56,6 +59,7 @@ enum Filter {
JsonParse,
}
#[derive(Clone, Debug, PartialEq)]
struct Span<'a> {
contents: &'a str,
}
@ -81,11 +85,11 @@ fn special(i: &str) -> IResult<&str, Special> {
delimited(
tag("{~"),
alt((
value(Special::LeftCurlyBrace, tag("lb")),
value(Special::RightCurlyBrace, tag("rb")),
value(Special::Space, tag("s")),
value(Special::NewLine, tag("s")),
value(Special::CarriageReturn, tag("s")),
value(Special::LeftCurlyBrace, tag("s")),
value(Special::RightCurlyBrace, tag("s")),
value(Special::NewLine, tag("n")),
value(Special::CarriageReturn, tag("r")),
)),
tag("}"),
)(i)
@ -102,8 +106,10 @@ fn path(i: &str) -> IResult<&str, Path> {
separated_list(
tag("."),
recognize(tuple((
is_a("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$"),
is_a("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$0123456789-"),
one_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$"),
opt(is_a(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$0123456789-",
)),
))),
),
|body| Path { keys: body },
@ -138,7 +144,7 @@ fn filter(i: &str) -> IResult<&str, Filter> {
/// Any text that is not a Dust element
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 }))
}
@ -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)))
);
}
}