|  | 
|  | 1 | +//! Tidy check to ensure `#[test]` and `#[bench]` are not used directly inside | 
|  | 2 | +//! `libcore` or `liballoc`. | 
|  | 3 | +//! | 
|  | 4 | +//! `#![no_std]` libraries cannot be tested directly due to duplicating lang | 
|  | 5 | +//! items. All tests and benchmarks must be written externally in `libcore/{tests,benches}` | 
|  | 6 | +//! or `liballoc/{tests,benches}`. | 
|  | 7 | +//! | 
|  | 8 | +//! Outside of libcore and liballoc tests and benchmarks should be outlined into separate files | 
|  | 9 | +//! named `tests.rs` or `benches.rs`, or directories named `tests` or `benches` unconfigured | 
|  | 10 | +//! during normal build. | 
|  | 11 | +
 | 
|  | 12 | +use std::path::Path; | 
|  | 13 | + | 
|  | 14 | +pub fn check(root_path: &Path, bad: &mut bool) { | 
|  | 15 | +    let libcore = &root_path.join("libcore"); | 
|  | 16 | +    let liballoc = &root_path.join("liballoc"); | 
|  | 17 | +    let libcore_tests = &root_path.join("libcore/tests"); | 
|  | 18 | +    let liballoc_tests = &root_path.join("liballoc/tests"); | 
|  | 19 | +    let libcore_benches = &root_path.join("libcore/benches"); | 
|  | 20 | +    let liballoc_benches = &root_path.join("liballoc/benches"); | 
|  | 21 | +    let is_core_or_alloc = |path: &Path| { | 
|  | 22 | +        let is_core = path.starts_with(libcore) && | 
|  | 23 | +                      !(path.starts_with(libcore_tests) || path.starts_with(libcore_benches)); | 
|  | 24 | +        let is_alloc = path.starts_with(liballoc) && | 
|  | 25 | +                       !(path.starts_with(liballoc_tests) || path.starts_with(liballoc_benches)); | 
|  | 26 | +        is_core || is_alloc | 
|  | 27 | +    }; | 
|  | 28 | +    let fixme = [ | 
|  | 29 | +        "liballoc", | 
|  | 30 | +        "libpanic_unwind/dwarf", | 
|  | 31 | +        "librustc", | 
|  | 32 | +        "librustc_data_structures", | 
|  | 33 | +        "librustc_incremental/persist", | 
|  | 34 | +        "librustc_lexer/src", | 
|  | 35 | +        "librustc_target/spec", | 
|  | 36 | +        "librustdoc", | 
|  | 37 | +        "libserialize", | 
|  | 38 | +        "libstd", | 
|  | 39 | +        "libsyntax", | 
|  | 40 | +        "libsyntax_pos", | 
|  | 41 | +        "libterm/terminfo", | 
|  | 42 | +        "libtest", | 
|  | 43 | +        "tools/compiletest/src", | 
|  | 44 | +        "tools/tidy/src", | 
|  | 45 | +    ]; | 
|  | 46 | + | 
|  | 47 | +    let mut skip = |path: &Path| { | 
|  | 48 | +        let file_name = path.file_name().unwrap_or_default(); | 
|  | 49 | +        if path.is_dir() { | 
|  | 50 | +            super::filter_dirs(path) || | 
|  | 51 | +            path.ends_with("src/test") || | 
|  | 52 | +            path.ends_with("src/doc") || | 
|  | 53 | +            (file_name == "tests" || file_name == "benches") && !is_core_or_alloc(path) || | 
|  | 54 | +            fixme.iter().any(|p| path.ends_with(p)) | 
|  | 55 | +        } else { | 
|  | 56 | +            let extension = path.extension().unwrap_or_default(); | 
|  | 57 | +            extension != "rs" || | 
|  | 58 | +            (file_name == "tests.rs" || file_name == "benches.rs") && !is_core_or_alloc(path) | 
|  | 59 | +        } | 
|  | 60 | +    }; | 
|  | 61 | + | 
|  | 62 | +    super::walk( | 
|  | 63 | +        root_path, | 
|  | 64 | +        &mut skip, | 
|  | 65 | +        &mut |entry, contents| { | 
|  | 66 | +            let path = entry.path(); | 
|  | 67 | +            let is_libcore = path.starts_with(libcore); | 
|  | 68 | +            let is_liballoc = path.starts_with(liballoc); | 
|  | 69 | +            for (i, line) in contents.lines().enumerate() { | 
|  | 70 | +                let line = line.trim(); | 
|  | 71 | +                let is_test = || line.contains("#[test]") && !line.contains("`#[test]"); | 
|  | 72 | +                let is_bench = || line.contains("#[bench]") && !line.contains("`#[bench]"); | 
|  | 73 | +                if !line.starts_with("//") && (is_test() || is_bench()) { | 
|  | 74 | +                    let explanation = if is_libcore { | 
|  | 75 | +                        "libcore unit tests and benchmarks must be placed into \ | 
|  | 76 | +                         `libcore/tests` or `libcore/benches`" | 
|  | 77 | +                    } else if is_liballoc { | 
|  | 78 | +                        "liballoc unit tests and benchmarks must be placed into \ | 
|  | 79 | +                         `liballoc/tests` or `liballoc/benches`" | 
|  | 80 | +                    } else { | 
|  | 81 | +                        "unit tests and benchmarks must be placed into \ | 
|  | 82 | +                         separate files or directories named \ | 
|  | 83 | +                         `tests.rs`, `benches.rs`, `tests` or `benches`" | 
|  | 84 | +                    }; | 
|  | 85 | +                    let name = if is_test() { "test" } else { "bench" }; | 
|  | 86 | +                    tidy_error!( | 
|  | 87 | +                        bad, "`{}:{}` contains `#[{}]`; {}", | 
|  | 88 | +                        path.display(), i + 1, name, explanation, | 
|  | 89 | +                    ); | 
|  | 90 | +                    return; | 
|  | 91 | +                } | 
|  | 92 | +            } | 
|  | 93 | +        }, | 
|  | 94 | +    ); | 
|  | 95 | +} | 
0 commit comments