wayver's git archive


an obsidian renderer
git clone https://git.wayver.dev/sable

sable-markdown/src/parser/inline/tests/consecutive_text_elements.rs@337ba67f65eaa17b44e371af7c0f0c761d6aa914

raw
Date Commit Message Author Files + -
2026-02-23 21:59 beginning on port over some of the changes from markdown-ppp since the f... wayverd 11 527 15
...

1//! Tests for verifying that parser correctly merges consecutive text elements
2//!
3//! These tests check cases where the parser might create multiple consecutive
4//! Text elements that should be merged into a single element.
5
6use crate::ast::*;
7use crate::parser::parse_markdown;
8
9/// Checks that there are no consecutive Text elements in the vec
10fn assert_no_consecutive_text_elements(inlines: &[Inline]) {
11    for window in inlines.windows(2) {
12        if let [Inline::Text(_), Inline::Text(_)] = window {
13            panic!("Found consecutive Text elements in {inlines:?}, which should be merged");
14        }
15    }
16
17    // Recursively check content of other elements
18    for inline in inlines {
19        match inline {
20            Inline::Emphasis(content)
21            | Inline::Strong(content)
22            | Inline::Strikethrough(content) => {
23                assert_no_consecutive_text_elements(content);
24            }
25            Inline::Link(link) => {
26                assert_no_consecutive_text_elements(&link.children);
27            }
28            Inline::LinkReference(link_ref) => {
29                assert_no_consecutive_text_elements(&link_ref.label);
30                assert_no_consecutive_text_elements(&link_ref.text);
31            }
32            _ => {}
33        }
34    }
35}
36
37/// Checks entire document for absence of consecutive Text elements
38fn assert_no_consecutive_text_in_document(doc: &Document) {
39    for block in &doc.blocks {
40        match block {
41            Block::Paragraph(inlines) => {
42                assert_no_consecutive_text_elements(inlines);
43            }
44            Block::Heading(heading) => {
45                assert_no_consecutive_text_elements(&heading.content);
46            }
47            Block::BlockQuote(blocks) => {
48                assert_no_consecutive_text_in_document(&Document {
49                    blocks: blocks.clone(),
50                });
51            }
52            Block::List(list) => {
53                for item in &list.items {
54                    assert_no_consecutive_text_in_document(&Document {
55                        blocks: item.blocks.clone(),
56                    });
57                }
58            }
59            Block::Table(table) => {
60                for row in &table.rows {
61                    for cell in row {
62                        assert_no_consecutive_text_elements(cell);
63                    }
64                }
65            }
66            Block::FootnoteDefinition(footnote) => {
67                assert_no_consecutive_text_in_document(&Document {
68                    blocks: footnote.blocks.clone(),
69                });
70            }
71            Block::Callout(callout) => {
72                assert_no_consecutive_text_in_document(&Document {
73                    blocks: callout.blocks.clone(),
74                });
75            }
76            // Other blocks don't contain inline elements
77            _ => {}
78        }
79    }
80}
81
82#[test]
83fn test_environment_variables_with_text() {
84    // Environment variables between regular text
85    let doc =
86        parse_markdown("Set PKG_CONFIG_PATH and CMAKE_BUILD_TYPE to debug for testing").unwrap();
87
88    assert_no_consecutive_text_in_document(&doc);
89}
90
91#[test]
92fn test_emphasis_with_surrounding_text() {
93    // Emphasis with surrounding text
94    let doc = parse_markdown("This is *emphasized* text with more content").unwrap();
95
96    assert_no_consecutive_text_in_document(&doc);
97}
98
99#[test]
100fn test_multiple_environment_variables() {
101    // Multiple environment variables
102    let doc = parse_markdown("Use PATH_TO_FILE and CMAKE_BUILD_TYPE and PKG_CONFIG_PATH variables")
103        .unwrap();
104
105    assert_no_consecutive_text_in_document(&doc);
106}
107
108#[test]
109fn test_mixed_inline_elements() {
110    // Mix of different inline elements
111    let doc =
112        parse_markdown("Text with ENV_VAR and *emphasis* and **strong** and `code` formatting")
113            .unwrap();
114
115    assert_no_consecutive_text_in_document(&doc);
116}
117
118#[test]
119fn test_escaped_characters_with_text() {
120    // Escaped characters with text
121    let doc =
122        parse_markdown("Text with \\* escaped asterisk \\_ underscore and more text").unwrap();
123
124    assert_no_consecutive_text_in_document(&doc);
125}
126
127#[test]
128fn test_autolinks_with_text() {
129    // Autolinks with text
130    let doc =
131        parse_markdown("Visit <https://example.com> for more information about ENV_VAR usage")
132            .unwrap();
133
134    assert_no_consecutive_text_in_document(&doc);
135}
136
137#[test]
138fn test_html_entities_with_text() {
139    // HTML entities with text
140    let doc = parse_markdown("Text &amp; more text &lt; even more text").unwrap();
141
142    assert_no_consecutive_text_in_document(&doc);
143}
144
145#[test]
146fn test_complex_paragraph() {
147    // Complex paragraph with multiple elements
148    let doc = parse_markdown(
149        "Configure CMAKE_BUILD_TYPE to *debug* mode using PKG_CONFIG_PATH variable and check <https://example.com> for &amp; documentation"
150    ).unwrap();
151
152    assert_no_consecutive_text_in_document(&doc);
153}
154
155#[test]
156fn test_nested_emphasis_with_env_vars() {
157    // Nested emphasis with environment variables
158    let doc = parse_markdown("Use **strong with *nested ENV_VAR emphasis* and more** formatting")
159        .unwrap();
160
161    assert_no_consecutive_text_in_document(&doc);
162}
163
164#[test]
165fn test_list_items_with_mixed_content() {
166    // List items with mixed content
167    let doc = parse_markdown(
168        "- Set ENV_VAR to *value* for testing\n- Use CMAKE_BUILD_TYPE in **production** mode\n- Check &amp; validate settings"
169    ).unwrap();
170
171    assert_no_consecutive_text_in_document(&doc);
172}
173
174#[test]
175fn test_table_cells_with_mixed_content() {
176    // Table cells with mixed content
177    let doc = parse_markdown(
178        "| Variable | Value | Description |\n|----------|-------|-------------|\n| ENV_VAR | *debug* | Test &amp; development |\n| PKG_CONFIG_PATH | `/usr/lib` | System **path** |"
179    ).unwrap();
180
181    assert_no_consecutive_text_in_document(&doc);
182}
183
184#[test]
185fn test_blockquote_with_mixed_content() {
186    // Blockquote with mixed content
187    let doc = parse_markdown("> Set ENV_VAR for *testing* and check PKG_CONFIG_PATH configuration")
188        .unwrap();
189
190    assert_no_consecutive_text_in_document(&doc);
191}
192
193#[test]
194fn test_heading_with_mixed_content() {
195    // Heading with mixed content
196    let doc = parse_markdown("# Configuration of ENV_VAR and *Other* Settings").unwrap();
197
198    assert_no_consecutive_text_in_document(&doc);
199}
200
201#[test]
202fn test_multiline_paragraph_with_mixed_content() {
203    // Multiline paragraph with mixed content
204    let doc = parse_markdown(
205        "First line with ENV_VAR variable\nSecond line with *emphasis* formatting\nThird line with PKG_CONFIG_PATH and more content"
206    ).unwrap();
207
208    assert_no_consecutive_text_in_document(&doc);
209}
210
211#[test]
212fn test_footnote_reference_with_text() {
213    // Footnote references with text
214    let doc = parse_markdown(
215        "Text with footnote[^1] and ENV_VAR variable\n\n[^1]: Footnote with PKG_CONFIG_PATH reference"
216    ).unwrap();
217
218    assert_no_consecutive_text_in_document(&doc);
219}
220