use lex_core::lex::parsing::parse_document;
use proptest::prelude::*;
proptest! {
#![proptest_config(ProptestConfig::with_cases(250))]
#[test]
fn test_parse_document_never_panics_on_any_utf8(s in "\\PC*") {
let _ = parse_document(&s);
}
}
fn lex_text_strategy() -> impl Strategy<Value = String> {
prop::collection::vec(
prop_oneof![
"[a-zA-Z0-9]+",
"[a-zA-Z0-9]+ [a-zA-Z0-9]+",
"[a-zA-Z0-9]+[.,!?]",
"",
],
1..10,
)
.prop_map(|lines| lines.join("\n"))
}
fn list_item_strategy() -> impl Strategy<Value = String> {
prop_oneof![
"- [a-zA-Z0-9 ]+",
"[0-9]+\\. [a-zA-Z0-9 ]+",
"[a-z]\\. [a-zA-Z0-9 ]+",
"\\([0-9]+\\) [a-zA-Z0-9 ]+",
]
}
fn session_title_strategy() -> impl Strategy<Value = String> {
prop_oneof!["[0-9]+\\. [a-zA-Z0-9 ]+", "[a-zA-Z0-9 ]+:", "[a-zA-Z0-9 ]+",]
}
fn lex_document_strategy() -> impl Strategy<Value = String> {
prop::collection::vec(
prop_oneof![
lex_text_strategy(),
list_item_strategy(),
session_title_strategy(),
],
1..20,
)
.prop_map(|lines| lines.join("\n"))
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(250))]
#[test]
fn test_parse_document_never_panics_on_valid_looking_lex(input in lex_document_strategy()) {
let _ = parse_document(&input);
}
}
fn verbatim_block_strategy() -> impl Strategy<Value = String> {
(
"[A-Z][a-zA-Z0-9 ]{1,15}",
prop::collection::vec("[a-zA-Z0-9 ]+", 1..5),
"[a-z][a-z0-9_-]{0,8}",
)
.prop_map(|(subject, lines, label)| {
let subject = subject.trim_end().to_string();
let content = lines
.iter()
.map(|l| format!(" {l}"))
.collect::<Vec<_>>()
.join("\n");
format!("{subject}:\n{content}\n:: {label} ::")
})
}
fn annotation_strategy() -> impl Strategy<Value = String> {
prop_oneof![
"[a-z][a-z0-9_-]{0,8}".prop_map(|label| format!(":: {label} ::")),
("[a-z][a-z0-9_-]{0,8}", "[a-z][a-z0-9_]{0,6}", "[a-z0-9]+",)
.prop_map(|(label, key, value)| format!(":: {label} {key}={value} ::")),
]
}
fn inline_text_strategy() -> impl Strategy<Value = String> {
prop_oneof![
"This is *[a-z]+* text.",
"This is _[a-z]+_ text.",
"This is `[a-z]+` text.",
"This has #[a-z]+# math.",
"See \\[@[a-z]+\\] here.",
"Mixed *[a-z]+* and _[a-z]+_ text.",
"Reference \\[\\^[a-z]+\\] note.",
]
}
fn expanded_lex_document_strategy() -> impl Strategy<Value = String> {
prop::collection::vec(
prop_oneof![
lex_text_strategy(),
list_item_strategy(),
session_title_strategy(),
verbatim_block_strategy(),
annotation_strategy(),
inline_text_strategy(),
],
1..30,
)
.prop_map(|lines| lines.join("\n\n")) }
proptest! {
#![proptest_config(ProptestConfig::with_cases(250))]
#[test]
fn test_parse_document_never_panics_on_expanded_lex(input in expanded_lex_document_strategy()) {
let _ = parse_document(&input);
}
}