use accent_proust::parse::{ParseOptions, PulldownTokenizer, parse, parse_with};
use proptest::prelude::*;
const FRAGMENTS: &[&str] = &[
"{%",
"%}",
"/%}",
"{% foo %}",
"{% /foo %}",
"{% $a.b[0] %}",
"{% #id .cls %}",
"```",
"~~~",
"<!--",
"-->",
"\n",
"\n\n",
" ",
"\t",
"*",
"**",
"_",
"`",
"[",
"](",
"|",
"---",
"===",
"#",
"> ",
"- ",
"1. ",
"\\",
"\"",
"\u{e9}",
"\u{1f600}",
];
fn document() -> impl Strategy<Value = String> {
prop::collection::vec(
prop_oneof![
2 => prop::sample::select(FRAGMENTS).prop_map(ToString::to_string),
1 => "[a-z ]{0,8}",
],
0..40,
)
.prop_map(|parts| parts.concat())
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(2048))]
#[test]
fn parsing_arbitrary_text_never_panics(source in "\\PC*") {
let _ = parse(&source);
}
#[test]
fn parsing_delimiter_soup_never_panics(source in document()) {
let _ = parse(&source);
}
#[test]
fn parsing_with_every_option_on_never_panics(source in document()) {
let options = ParseOptions::new()
.slots(true)
.allow_comments(true)
.validated_protocols(vec!["http".to_string(), "https".to_string()]);
let _ = parse_with(&source, &PulldownTokenizer::new(), &options);
}
#[test]
fn parsing_without_locations_never_panics(source in document()) {
let options = ParseOptions::new().location(false);
let _ = parse_with(&source, &PulldownTokenizer::new(), &options);
}
#[test]
fn every_location_borrows_its_own_span(source in document()) {
let document = parse(&source);
for node in document.walk() {
let Some(location) = node.location else { continue };
prop_assert!(location.start.offset <= location.end.offset);
prop_assert!(location.end.offset <= source.len());
prop_assert_eq!(source.get(location.span()), Some(location.text));
}
}
}