]> git.lizzy.rs Git - rust.git/blob - src/tools/linkchecker/tests/checks.rs
Rollup merge of #101389 - lukaslueg:rcgetmutdocs, r=m-ou-se
[rust.git] / src / tools / linkchecker / tests / checks.rs
1 use std::path::Path;
2 use std::process::{Command, ExitStatus};
3
4 fn run(dirname: &str) -> (ExitStatus, String, String) {
5     let output = Command::new(env!("CARGO_BIN_EXE_linkchecker"))
6         .current_dir(Path::new(env!("CARGO_MANIFEST_DIR")).join("tests"))
7         .arg(dirname)
8         .output()
9         .unwrap();
10     let stdout = String::from_utf8(output.stdout).unwrap();
11     let stderr = String::from_utf8(output.stderr).unwrap();
12     (output.status, stdout, stderr)
13 }
14
15 fn broken_test(dirname: &str, expected: &str) {
16     let (status, stdout, stderr) = run(dirname);
17     assert!(!status.success());
18     if !contains(expected, &stdout) {
19         panic!(
20             "stdout did not contain expected text: {}\n\
21             --- stdout:\n\
22             {}\n\
23             --- stderr:\n\
24             {}\n",
25             expected, stdout, stderr
26         );
27     }
28 }
29
30 fn contains(expected: &str, actual: &str) -> bool {
31     // Normalize for Windows paths.
32     let actual = actual.replace('\\', "/");
33     actual.lines().any(|mut line| {
34         for (i, part) in expected.split("[..]").enumerate() {
35             match line.find(part) {
36                 Some(j) => {
37                     if i == 0 && j != 0 {
38                         return false;
39                     }
40                     line = &line[j + part.len()..];
41                 }
42                 None => return false,
43             }
44         }
45         line.is_empty() || expected.ends_with("[..]")
46     })
47 }
48
49 fn valid_test(dirname: &str) {
50     let (status, stdout, stderr) = run(dirname);
51     if !status.success() {
52         panic!(
53             "test did not succeed as expected\n\
54             --- stdout:\n\
55             {}\n\
56             --- stderr:\n\
57             {}\n",
58             stdout, stderr
59         );
60     }
61 }
62
63 #[test]
64 fn valid() {
65     valid_test("valid/inner");
66 }
67
68 #[test]
69 fn basic_broken() {
70     broken_test("basic_broken", "foo.html:3: broken link - `bar.html`");
71 }
72
73 #[test]
74 fn broken_fragment_local() {
75     broken_test(
76         "broken_fragment_local",
77         "foo.html:3: broken link fragment `#somefrag` pointing to `foo.html`",
78     );
79 }
80
81 #[test]
82 fn broken_fragment_remote() {
83     broken_test(
84         "broken_fragment_remote/inner",
85         "foo.html:3: broken link fragment `#somefrag` pointing to \
86          `[..]/broken_fragment_remote/bar.html`",
87     );
88 }
89
90 #[test]
91 fn broken_redir() {
92     broken_test(
93         "broken_redir",
94         "foo.html:3: broken redirect from `redir-bad.html` to `sometarget`",
95     );
96 }
97
98 #[test]
99 fn directory_link() {
100     broken_test(
101         "directory_link",
102         "foo.html:3: directory link to `somedir` (directory links should use index.html instead)",
103     );
104 }
105
106 #[test]
107 fn redirect_loop() {
108     broken_test(
109         "redirect_loop",
110         "foo.html:3: redirect from `redir-bad.html` to `[..]redirect_loop/redir-bad.html` \
111          which is also a redirect (not supported)",
112     );
113 }