| 1 | // run it like this: |
| 2 | // cargo test --test pathological --jobs 1 -- --nocapture --test-threads=1 |
| 3 | use markdown_it::MarkdownIt; |
| 4 | use once_cell::sync::Lazy; |
| 5 | use std::time::SystemTime; |
| 6 | |
| 7 | static MD : Lazy<MarkdownIt> = Lazy::new(|| { |
| 8 | let mut parser = markdown_it::MarkdownIt::new(); |
| 9 | markdown_it::plugins::cmark::add(&mut parser); |
| 10 | markdown_it::plugins::html::add(&mut parser); |
| 11 | markdown_it::plugins::extra::add(&mut parser); |
| 12 | parser |
| 13 | }); |
| 14 | |
| 15 | fn run(src: &str) { |
| 16 | let now = SystemTime::now(); |
| 17 | MD.parse(src); |
| 18 | dbg!(now.elapsed().ok().unwrap()); |
| 19 | } |
| 20 | |
| 21 | |
| 22 | mod commonmark { |
| 23 | // Ported from cmark, https://github.com/commonmark/cmark/blob/master/test/pathological_tests.py |
| 24 | use super::run; |
| 25 | |
| 26 | #[test] |
| 27 | fn nested_inlines() { |
| 28 | run(&format!("{}{}{}", "*".repeat(100000), "a", "*".repeat(100000))); |
| 29 | } |
| 30 | |
| 31 | #[test] |
| 32 | fn nested_strong_emph() { |
| 33 | // suspiciously slow |
| 34 | run(&format!("{}{}{}", "*a **a".repeat(5000), "b", " a** a*".repeat(5000))); |
| 35 | } |
| 36 | |
| 37 | #[test] |
| 38 | fn many_emph_closers_with_no_openers() { |
| 39 | run(&"a_ ".repeat(100000)); |
| 40 | } |
| 41 | |
| 42 | #[test] |
| 43 | fn many_emph_openers_with_no_closers() { |
| 44 | run(&"_a ".repeat(100000)); |
| 45 | } |
| 46 | |
| 47 | #[test] |
| 48 | fn many_link_closers_with_no_openers() { |
| 49 | run(&"a]".repeat(100000)); |
| 50 | } |
| 51 | |
| 52 | #[test] |
| 53 | fn many_link_openers_with_no_closers() { |
| 54 | run(&"[a".repeat(50000)); |
| 55 | } |
| 56 | |
| 57 | #[test] |
| 58 | fn mismatched_openers_and_closers() { |
| 59 | // most probably a bug |
| 60 | run(&"*a_ ".repeat(50000)); |
| 61 | } |
| 62 | |
| 63 | #[test] |
| 64 | fn commonmark_cmark_389() { |
| 65 | run(&format!("{}{}", "*a ".repeat(2000), "_a*_ ".repeat(2000))); |
| 66 | } |
| 67 | |
| 68 | #[test] |
| 69 | fn openers_and_closers_multiple_of_3() { |
| 70 | run(&format!("{}{}", "a**b", "c* ".repeat(50000))); |
| 71 | } |
| 72 | |
| 73 | #[test] |
| 74 | fn link_openers_and_emph_closers() { |
| 75 | run(&"[ a_".repeat(50000)); |
| 76 | } |
| 77 | |
| 78 | #[test] |
| 79 | fn link_pattern_repeated() { |
| 80 | run(&"[ (](".repeat(100000)); |
| 81 | } |
| 82 | |
| 83 | #[test] |
| 84 | fn nested_brackets() { |
| 85 | run(&format!("{}{}{}", "[".repeat(50000), "a", "]".repeat(50000))); |
| 86 | } |
| 87 | |
| 88 | #[test] |
| 89 | fn nested_block_quotes() { |
| 90 | run(&format!("{}{}", "> ".repeat(50000), "a")); |
| 91 | } |
| 92 | |
| 93 | #[test] |
| 94 | fn deeply_nested_lists() { |
| 95 | let src = (0..5000).map(|x| format!("{}{}", " ".repeat(x), "* a\n")).collect::<Vec<_>>().join(""); |
| 96 | run(&src); |
| 97 | } |
| 98 | |
| 99 | #[test] |
| 100 | fn backticks() { |
| 101 | let src = (0..1000).map(|x| format!("{}{}", "e", "`".repeat(x))).collect::<Vec<_>>().join(""); |
| 102 | run(&src); |
| 103 | } |
| 104 | |
| 105 | #[test] |
| 106 | fn unclosed_links_a() { |
| 107 | run(&"[a](<b".repeat(30000)); |
| 108 | } |
| 109 | |
| 110 | #[test] |
| 111 | fn unclosed_links_b() { |
| 112 | run(&"[a](b".repeat(30000)); |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | mod markdownit { |
| 117 | // Ported from markdown-it.js |
| 118 | use super::run; |
| 119 | |
| 120 | #[test] |
| 121 | fn emphasis_pattern() { |
| 122 | run(&"**_* ".repeat(5000)); |
| 123 | } |
| 124 | |
| 125 | #[test] |
| 126 | fn backtick_pattern() { |
| 127 | run(&"``\\".repeat(50000)); |
| 128 | } |
| 129 | |
| 130 | #[test] |
| 131 | fn autolinks_pattern() { |
| 132 | run(&format!("{}{}", "<".repeat(100000), ">")); |
| 133 | } |
| 134 | |
| 135 | #[test] |
| 136 | fn hardbreak_whitespaces_pattern() { |
| 137 | run(&format!("{}{}{}", "x", " ".repeat(100000), "x \nx")); |
| 138 | } |
| 139 | } |
| 140 | |