use proptest::prelude::*; // Strategy: generate arbitrary HTML-like strings fn html_fragment() -> impl Strategy { let tags = prop::sample::select(vec![ "p", "div", "span", "strong", "em", "a", "h1", "h2", "h3", "ul", "ol", "li", "blockquote", "pre", "code", "br", "hr", "img", "table", "tr", "td", "th", "b", "i", "del", "sup", "sub", ]); let text = "[a-zA-Z0-9 .,!?]{0,100}"; prop::collection::vec( prop_oneof![ // Plain text text.prop_map(|s| s), // Opening + closing tag with text (tags.clone(), text).prop_map(|(tag, content)| { format!("<{tag}>{content}") }), // Self-closing tag tags.clone().prop_map(|tag| format!("<{tag}/>")), // Nested tags (tags.clone(), tags.clone(), text).prop_map(|(outer, inner, content)| { format!("<{outer}><{inner}>{content}") }), ], 1..10, ) .prop_map(|parts| parts.join("")) } proptest! { #[test] fn never_panics(html in html_fragment()) { let _ = pter::convert(&html); } #[test] fn never_panics_on_arbitrary_bytes(s in "\\PC{0,500}") { let _ = pter::convert(&s); } #[test] fn output_contains_no_html_tags(html in html_fragment()) { let md = pter::convert(&html); // Output should never contain raw HTML tags // (except inside code blocks, which we skip checking) let without_code_blocks: String = md .split("```") .enumerate() .filter(|(i, _)| i % 2 == 0) // only outside code blocks .map(|(_, s)| s) .collect(); // No