]> git.lizzy.rs Git - rust.git/blob - src/librustdoc/html/markdown/tests.rs
Auto merge of #99292 - Aaron1011:stability-use-tree, r=cjgillot
[rust.git] / src / librustdoc / html / markdown / tests.rs
1 use super::{find_testable_code, plain_text_summary, short_markdown_summary};
2 use super::{ErrorCodes, HeadingOffset, IdMap, Ignore, LangString, Markdown, MarkdownItemInfo};
3 use rustc_span::edition::{Edition, DEFAULT_EDITION};
4
5 #[test]
6 fn test_unique_id() {
7     let input = [
8         "foo",
9         "examples",
10         "examples",
11         "method.into_iter",
12         "examples",
13         "method.into_iter",
14         "foo",
15         "main-content",
16         "search",
17         "methods",
18         "examples",
19         "method.into_iter",
20         "assoc_type.Item",
21         "assoc_type.Item",
22     ];
23     let expected = [
24         "foo",
25         "examples",
26         "examples-1",
27         "method.into_iter",
28         "examples-2",
29         "method.into_iter-1",
30         "foo-1",
31         "main-content-1",
32         "search-1",
33         "methods",
34         "examples-3",
35         "method.into_iter-2",
36         "assoc_type.Item",
37         "assoc_type.Item-1",
38     ];
39
40     let mut map = IdMap::new();
41     let actual: Vec<String> = input.iter().map(|s| map.derive(s.to_string())).collect();
42     assert_eq!(&actual[..], expected);
43 }
44
45 #[test]
46 fn test_lang_string_parse() {
47     fn t(lg: LangString) {
48         let s = &lg.original;
49         assert_eq!(LangString::parse(s, ErrorCodes::Yes, true, None), lg)
50     }
51
52     t(Default::default());
53     t(LangString { original: "rust".into(), ..Default::default() });
54     t(LangString { original: ".rust".into(), ..Default::default() });
55     t(LangString { original: "{rust}".into(), ..Default::default() });
56     t(LangString { original: "{.rust}".into(), ..Default::default() });
57     t(LangString { original: "sh".into(), rust: false, ..Default::default() });
58     t(LangString { original: "ignore".into(), ignore: Ignore::All, ..Default::default() });
59     t(LangString {
60         original: "ignore-foo".into(),
61         ignore: Ignore::Some(vec!["foo".to_string()]),
62         ..Default::default()
63     });
64     t(LangString { original: "should_panic".into(), should_panic: true, ..Default::default() });
65     t(LangString { original: "no_run".into(), no_run: true, ..Default::default() });
66     t(LangString { original: "test_harness".into(), test_harness: true, ..Default::default() });
67     t(LangString {
68         original: "compile_fail".into(),
69         no_run: true,
70         compile_fail: true,
71         ..Default::default()
72     });
73     t(LangString { original: "no_run,example".into(), no_run: true, ..Default::default() });
74     t(LangString {
75         original: "sh,should_panic".into(),
76         should_panic: true,
77         rust: false,
78         ..Default::default()
79     });
80     t(LangString { original: "example,rust".into(), ..Default::default() });
81     t(LangString {
82         original: "test_harness,.rust".into(),
83         test_harness: true,
84         ..Default::default()
85     });
86     t(LangString {
87         original: "text, no_run".into(),
88         no_run: true,
89         rust: false,
90         ..Default::default()
91     });
92     t(LangString {
93         original: "text,no_run".into(),
94         no_run: true,
95         rust: false,
96         ..Default::default()
97     });
98     t(LangString {
99         original: "text,no_run, ".into(),
100         no_run: true,
101         rust: false,
102         ..Default::default()
103     });
104     t(LangString {
105         original: "text,no_run,".into(),
106         no_run: true,
107         rust: false,
108         ..Default::default()
109     });
110     t(LangString {
111         original: "edition2015".into(),
112         edition: Some(Edition::Edition2015),
113         ..Default::default()
114     });
115     t(LangString {
116         original: "edition2018".into(),
117         edition: Some(Edition::Edition2018),
118         ..Default::default()
119     });
120 }
121
122 #[test]
123 fn test_lang_string_tokenizer() {
124     fn case(lang_string: &str, want: &[&str]) {
125         let have = LangString::tokens(lang_string).collect::<Vec<&str>>();
126         assert_eq!(have, want, "Unexpected lang string split for `{}`", lang_string);
127     }
128
129     case("", &[]);
130     case("foo", &["foo"]);
131     case("foo,bar", &["foo", "bar"]);
132     case(".foo,.bar", &["foo", "bar"]);
133     case("{.foo,.bar}", &["foo", "bar"]);
134     case("  {.foo,.bar}  ", &["foo", "bar"]);
135     case("foo bar", &["foo", "bar"]);
136     case("foo\tbar", &["foo", "bar"]);
137     case("foo\t, bar", &["foo", "bar"]);
138     case(" foo , bar ", &["foo", "bar"]);
139     case(",,foo,,bar,,", &["foo", "bar"]);
140     case("foo=bar", &["foo=bar"]);
141     case("a-b-c", &["a-b-c"]);
142     case("a_b_c", &["a_b_c"]);
143 }
144
145 #[test]
146 fn test_header() {
147     fn t(input: &str, expect: &str) {
148         let mut map = IdMap::new();
149         let output = Markdown {
150             content: input,
151             links: &[],
152             ids: &mut map,
153             error_codes: ErrorCodes::Yes,
154             edition: DEFAULT_EDITION,
155             playground: &None,
156             heading_offset: HeadingOffset::H2,
157         }
158         .into_string();
159         assert_eq!(output, expect, "original: {}", input);
160     }
161
162     t("# Foo bar", "<h2 id=\"foo-bar\"><a href=\"#foo-bar\">Foo bar</a></h2>");
163     t(
164         "## Foo-bar_baz qux",
165         "<h3 id=\"foo-bar_baz-qux\">\
166          <a href=\"#foo-bar_baz-qux\">Foo-bar_baz qux</a></h3>",
167     );
168     t(
169         "### **Foo** *bar* baz!?!& -_qux_-%",
170         "<h4 id=\"foo-bar-baz--qux-\">\
171             <a href=\"#foo-bar-baz--qux-\"><strong>Foo</strong> \
172             <em>bar</em> baz!?!&amp; -<em>qux</em>-%</a>\
173          </h4>",
174     );
175     t(
176         "#### **Foo?** & \\*bar?!*  _`baz`_ ❤ #qux",
177         "<h5 id=\"foo--bar--baz--qux\">\
178              <a href=\"#foo--bar--baz--qux\"><strong>Foo?</strong> &amp; *bar?!*  \
179              <em><code>baz</code></em> ❤ #qux</a>\
180          </h5>",
181     );
182 }
183
184 #[test]
185 fn test_header_ids_multiple_blocks() {
186     let mut map = IdMap::new();
187     fn t(map: &mut IdMap, input: &str, expect: &str) {
188         let output = Markdown {
189             content: input,
190             links: &[],
191             ids: map,
192             error_codes: ErrorCodes::Yes,
193             edition: DEFAULT_EDITION,
194             playground: &None,
195             heading_offset: HeadingOffset::H2,
196         }
197         .into_string();
198         assert_eq!(output, expect, "original: {}", input);
199     }
200
201     t(&mut map, "# Example", "<h2 id=\"example\"><a href=\"#example\">Example</a></h2>");
202     t(&mut map, "# Panics", "<h2 id=\"panics\"><a href=\"#panics\">Panics</a></h2>");
203     t(&mut map, "# Example", "<h2 id=\"example-1\"><a href=\"#example-1\">Example</a></h2>");
204     t(&mut map, "# Search", "<h2 id=\"search-1\"><a href=\"#search-1\">Search</a></h2>");
205     t(&mut map, "# Example", "<h2 id=\"example-2\"><a href=\"#example-2\">Example</a></h2>");
206     t(&mut map, "# Panics", "<h2 id=\"panics-1\"><a href=\"#panics-1\">Panics</a></h2>");
207 }
208
209 #[test]
210 fn test_short_markdown_summary() {
211     fn t(input: &str, expect: &str) {
212         let output = short_markdown_summary(input, &[][..]);
213         assert_eq!(output, expect, "original: {}", input);
214     }
215
216     t("", "");
217     t("hello [Rust](https://www.rust-lang.org) :)", "hello Rust :)");
218     t("*italic*", "<em>italic</em>");
219     t("**bold**", "<strong>bold</strong>");
220     t("Multi-line\nsummary", "Multi-line summary");
221     t("Hard-break  \nsummary", "Hard-break summary");
222     t("hello [Rust] :)\n\n[Rust]: https://www.rust-lang.org", "hello Rust :)");
223     t("hello [Rust](https://www.rust-lang.org \"Rust\") :)", "hello Rust :)");
224     t("dud [link]", "dud [link]");
225     t("code `let x = i32;` ...", "code <code>let x = i32;</code> …");
226     t("type `Type<'static>` ...", "type <code>Type&lt;&#39;static&gt;</code> …");
227     // Test to ensure escaping and length-limiting work well together.
228     // The output should be limited based on the input length,
229     // rather than the output, because escaped versions of characters
230     // are usually longer than how the character is actually displayed.
231     t(
232         "& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &",
233         "&amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; \
234          &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; \
235          &amp; &amp; &amp; &amp; &amp; …",
236     );
237     t("# top header", "top header");
238     t("# top header\n\nfollowed by a paragraph", "top header");
239     t("## header", "header");
240     t("first paragraph\n\nsecond paragraph", "first paragraph");
241     t("```\nfn main() {}\n```", "");
242     t("<div>hello</div>", "");
243     t(
244         "a *very*, **very** long first paragraph. it has lots of `inline code: Vec<T>`. and it has a [link](https://www.rust-lang.org).\nthat was a soft line break!  \nthat was a hard one\n\nsecond paragraph.",
245         "a <em>very</em>, <strong>very</strong> long first paragraph. it has lots of …",
246     );
247 }
248
249 #[test]
250 fn test_plain_text_summary() {
251     fn t(input: &str, expect: &str) {
252         let output = plain_text_summary(input);
253         assert_eq!(output, expect, "original: {}", input);
254     }
255
256     t("", "");
257     t("hello [Rust](https://www.rust-lang.org) :)", "hello Rust :)");
258     t("**bold**", "bold");
259     t("Multi-line\nsummary", "Multi-line summary");
260     t("Hard-break  \nsummary", "Hard-break summary");
261     t("hello [Rust] :)\n\n[Rust]: https://www.rust-lang.org", "hello Rust :)");
262     t("hello [Rust](https://www.rust-lang.org \"Rust\") :)", "hello Rust :)");
263     t("dud [link]", "dud [link]");
264     t("code `let x = i32;` ...", "code `let x = i32;` …");
265     t("type `Type<'static>` ...", "type `Type<'static>` …");
266     t("# top header", "top header");
267     t("# top header\n\nfollowed by some text", "top header");
268     t("## header", "header");
269     t("first paragraph\n\nsecond paragraph", "first paragraph");
270     t("```\nfn main() {}\n```", "");
271     t("<div>hello</div>", "");
272     t(
273         "a *very*, **very** long first paragraph. it has lots of `inline code: Vec<T>`. and it has a [link](https://www.rust-lang.org).\nthat was a soft line break!  \nthat was a hard one\n\nsecond paragraph.",
274         "a very, very long first paragraph. it has lots of `inline code: Vec<T>`. and it has a link. that was a soft line break! that was a hard one",
275     );
276 }
277
278 #[test]
279 fn test_markdown_html_escape() {
280     fn t(input: &str, expect: &str) {
281         let mut idmap = IdMap::new();
282         let output = MarkdownItemInfo(input, &mut idmap).into_string();
283         assert_eq!(output, expect, "original: {}", input);
284     }
285
286     t("`Struct<'a, T>`", "<code>Struct&lt;'a, T&gt;</code>");
287     t("Struct<'a, T>", "Struct&lt;’a, T&gt;");
288     t("Struct<br>", "Struct&lt;br&gt;");
289 }
290
291 #[test]
292 fn test_find_testable_code_line() {
293     fn t(input: &str, expect: &[usize]) {
294         impl crate::doctest::Tester for Vec<usize> {
295             fn add_test(&mut self, _test: String, _config: LangString, line: usize) {
296                 self.push(line);
297             }
298         }
299         let mut lines = Vec::<usize>::new();
300         find_testable_code(input, &mut lines, ErrorCodes::No, false, None);
301         assert_eq!(lines, expect);
302     }
303
304     t("", &[]);
305     t("```rust\n```", &[1]);
306     t(" ```rust\n```", &[1]);
307     t("\n```rust\n```", &[2]);
308     t("\n ```rust\n```", &[2]);
309     t("```rust\n```\n```rust\n```", &[1, 3]);
310     t("```rust\n```\n ```rust\n```", &[1, 3]);
311 }