2 use std::process::{Command, ExitStatus};
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"))
10 let stdout = String::from_utf8(output.stdout).unwrap();
11 let stderr = String::from_utf8(output.stderr).unwrap();
12 (output.status, stdout, stderr)
15 fn broken_test(dirname: &str, expected: &str) {
16 let (status, stdout, stderr) = run(dirname);
17 assert!(!status.success());
18 if !contains(expected, &stdout) {
20 "stdout did not contain expected text: {}\n\
25 expected, stdout, stderr
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) {
40 line = &line[j + part.len()..];
45 line.is_empty() || expected.ends_with("[..]")
49 fn valid_test(dirname: &str) {
50 let (status, stdout, stderr) = run(dirname);
51 if !status.success() {
53 "test did not succeed as expected\n\
65 valid_test("valid/inner");
70 broken_test("basic_broken", "foo.html:3: broken link - `bar.html`");
74 fn broken_fragment_local() {
76 "broken_fragment_local",
77 "foo.html:3: broken link fragment `#somefrag` pointing to `foo.html`",
82 fn broken_fragment_remote() {
84 "broken_fragment_remote/inner",
85 "foo.html:3: broken link fragment `#somefrag` pointing to \
86 `[..]/broken_fragment_remote/bar.html`",
94 "foo.html:3: broken redirect from `redir-bad.html` to `sometarget`",
102 "foo.html:3: directory link to `somedir` (directory links should use index.html instead)",
110 "foo.html:3: redirect from `redir-bad.html` to `[..]redirect_loop/redir-bad.html` \
111 which is also a redirect (not supported)",