Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_text/tests/markdown.rs

3.9 KiB, 1 run

created by r1870400018:22716, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1use oxedyne_fe2o3_text::doc::{
2 Block,
3 Doc,
4 Inline,
5 markdown,
6};
7
8use oxedyne_fe2o3_core::{
9 prelude::*,
10 test::test_it,
11};
12
13/// Prose using every construct the tree has a node for.
14const SOURCE: &str = "\
15# A title
16
17A paragraph with **strong**, *emphasis*, `code`, a [link](https://example.com) and an
18![image](pic.png).
19
20## Second
21
22- One
23- Two
24 - Nested
25 - Also nested
26- Three
27
281. First
292. Second
30
31> Quoted, and it goes on.
32
33| Name | Count |
34| :-- | --: |
35| Widget | 12 |
36
37```rust
38fn main() {}
39```
40
41---
42
43The end.
44";
45
46pub fn test_markdown(filter: &'static str) -> Outcome<()> {
47
48 res!(test_it(filter, &["A tree written and read back is the same tree 000", "all", "markdown"], || {
49 // The writer's oracle is the reader, which is tested on its own terms elsewhere. This says the
50 // two AGREE; it says nothing about either matching CommonMark, and is not offered as if it did.
51 // What it does catch, and catches nothing else in this crate does, is an escape that changes
52 // the meaning of a character and an indent that changes what a list is nested inside.
53 let once = res!(markdown::parse(SOURCE));
54 let out = markdown::write::render(&once);
55 let twice = res!(markdown::parse(&out));
56 assert_eq!(once, twice, "written as:\n{}", out);
57 // And it is stable: writing the tree again gives the same text.
58 assert_eq!(markdown::write::render(&twice), out);
59 Ok(())
60 }));
61
62 res!(test_it(filter, &["A nested list nests under its parent's text 001", "all", "markdown"], || {
63 let doc = res!(markdown::parse(SOURCE));
64 let out = markdown::write::render(&doc);
65 assert!(out.contains("- Two\n - Nested\n"), "got:\n{}", out);
66 // Which is to say the indent is the width of the marker above it, and not a fixed depth that
67 // doubles at every level.
68 assert!(!out.contains(" - Nested"), "the indent compounded:\n{}", out);
69 Ok(())
70 }));
71
72 res!(test_it(filter, &["An escape goes where it changes the meaning 002", "all", "markdown"], || {
73 // A hyphen opening a line opens a list; one in the middle of a sentence is a hyphen. A writer
74 // that escaped both would fill the document with backslashes, and one that escaped neither
75 // would turn a sentence into a bullet the next time it was read.
76 let doc = Doc {
77 blocks: vec![
78 Block::Para(vec![Inline::Text("- not a list".to_string())]),
79 Block::Para(vec![Inline::Text("a - b - c".to_string())]),
80 Block::Para(vec![Inline::Text("1. not a list".to_string())]),
81 Block::Table {
82 head: None,
83 rows: vec![oxedyne_fe2o3_text::doc::Row(vec![
84 oxedyne_fe2o3_text::doc::Cell(vec![Inline::Text("3.40".to_string())]),
85 oxedyne_fe2o3_text::doc::Cell(vec![Inline::Text("a | b".to_string())]),
86 ])],
87 cols: vec![],
88 },
89 ],
90 };
91 let out = markdown::write::render(&doc);
92 assert!(out.contains("\\- not a list"), "got:\n{}", out);
93 assert!(out.contains("a - b - c"), "a hyphen mid-sentence is left alone:\n{}", out);
94 assert!(out.contains("1\\. not a list"), "got:\n{}", out);
95 // A price in a cell is not the start of a line, whatever it looks like.
96 assert!(out.contains("| 3.40 |"), "a cell got a spurious escape:\n{}", out);
97 assert!(out.contains("a \\| b"), "a pipe in a cell would end it:\n{}", out);
98 // And all of it reads back as what it said.
99 let back = res!(markdown::parse(&out));
100 assert_eq!(back.blocks[0], doc.blocks[0]);
101 assert_eq!(back.blocks[1], doc.blocks[1]);
102 assert_eq!(back.blocks[2], doc.blocks[2]);
103 Ok(())
104 }));
105
106 res!(test_it(filter, &["A fence is longer than anything inside it 003", "all", "markdown"], || {
107 // A listing about Markdown holds a fence, and a writer that always used three backticks would
108 // close its own block at the first one.
109 let doc = Doc {
110 blocks: vec![Block::Code {
111 lang: None,
112 text: "```\nnot the end\n```\n".to_string(),
113 }],
114 };
115 let out = markdown::write::render(&doc);
116 assert!(out.starts_with("````\n"), "got:\n{}", out);
117 let back = res!(markdown::parse(&out));
118 assert_eq!(back.blocks, doc.blocks);
119 Ok(())
120 }));
121
122 Ok(())
123}