tidy/rustdoc_html_tests.rs
1//! Tidy check to ensure that rustdoc GUI tests start with a small description.
2
3use std::collections::BTreeSet;
4use std::path::Path;
5
6use crate::diagnostics::{CheckId, TidyCtx};
7
8pub fn check(path: &Path, tidy_ctx: TidyCtx) {
9 let path = path.join("rustdoc-html");
10 let mut check = tidy_ctx.start_check(CheckId::new("rustdoc_html_tests").path(&path));
11
12 // The list of subdirectories in rustdoc-html tests.
13 // Compare previous subdirectory with current subdirectory
14 // to sync with `tests/rustdoc-html/README.md`.
15 let mut prev_line = String::new();
16 let documented_subdirs: BTreeSet<_> = include_str!("../../../../tests/rustdoc-html/README.md")
17 .lines()
18 .filter_map(|line| {
19 static_regex!(r"^##.*?`(?<dir>[^`]+)`").captures(line).map(|cap| {
20 let dir = &cap["dir"];
21 // FIXME(reddevilmidzy) normalize subdirs title in tests/rustdoc-html/README.md
22 if dir.ends_with('/') {
23 dir.strip_suffix('/').unwrap().to_string()
24 } else {
25 dir.to_string()
26 }
27 })
28 })
29 .inspect(|line| {
30 if prev_line.as_str() > line.as_str() {
31 check.error(&format!(
32 "`tests/rustdoc-html/README.md` is not in order: {prev_line:?} should be after {line:?}"
33 ));
34 }
35
36 prev_line = line.clone();
37 })
38 .collect();
39
40 let filesystem_subdirs = collect_rustdoc_html_tests_subdirs(&path);
41 let is_modified = !filesystem_subdirs.eq(&documented_subdirs);
42
43 if is_modified {
44 for directory in documented_subdirs.symmetric_difference(&filesystem_subdirs) {
45 if documented_subdirs.contains(directory) {
46 check.error(format!(
47 "rustdoc-html subdirectory `{directory}` is listed in `tests/rustdoc-html/README.md` but does not exist in the filesystem"
48 ));
49 } else {
50 check.error(format!(
51 "rustdoc-html subdirectory `{directory}` exists in the filesystem but is not documented in `tests/rustdoc-html/README.md`"
52 ));
53 }
54 }
55 check.error(
56 "`tests/rustdoc-html/README.md` subdirectory listing is out of sync with the filesystem. \
57 Please add or remove subdirectory entries (## headers with backtick-wrapped names) to match the actual directories in `tests/rustdoc-html/`"
58 );
59 }
60}
61
62fn collect_rustdoc_html_tests_subdirs(path: &Path) -> BTreeSet<String> {
63 let entries = std::fs::read_dir(path).unwrap();
64
65 entries
66 .filter_map(|entry| entry.ok())
67 .map(|entry| entry.path())
68 .filter(|path| path.is_dir() && path.file_name().is_some_and(|name| name != "auxiliary"))
69 .map(|dir_path| {
70 let dir_path = dir_path.strip_prefix(path).unwrap();
71 format!(
72 "tests/rustdoc-html/{}",
73 dir_path.to_string_lossy().replace(std::path::MAIN_SEPARATOR_STR, "/")
74 )
75 })
76 .collect()
77}