tidy/
unit_tests.rs
1use std::path::Path;
11
12use crate::walk::{filter_dirs, walk};
13
14pub fn check(root_path: &Path, bad: &mut bool) {
15 let core = root_path.join("core");
16 let core_copy = core.clone();
17 let core_tests = core.join("tests");
18 let core_benches = core.join("benches");
19 let is_core = move |path: &Path| {
20 path.starts_with(&core)
21 && !(path.starts_with(&core_tests) || path.starts_with(&core_benches))
22 };
23
24 let skip = move |path: &Path, is_dir| {
25 let file_name = path.file_name().unwrap_or_default();
26 if is_dir {
27 filter_dirs(path)
28 || path.ends_with("src/doc")
29 || (file_name == "tests" || file_name == "benches") && !is_core(path)
30 } else {
31 let extension = path.extension().unwrap_or_default();
32 extension != "rs"
33 || (file_name == "tests.rs" || file_name == "benches.rs") && !is_core(path)
34 || path.ends_with("src/thread/local/dynamic_tests.rs")
36 || path.ends_with("src/sync/mpsc/sync_tests.rs")
37 }
38 };
39
40 walk(root_path, skip, &mut |entry, contents| {
41 let path = entry.path();
42 let is_core = path.starts_with(&core_copy);
43 for (i, line) in contents.lines().enumerate() {
44 let line = line.trim();
45 let is_test = || line.contains("#[test]") && !line.contains("`#[test]");
46 let is_bench = || line.contains("#[bench]") && !line.contains("`#[bench]");
47 if !line.starts_with("//") && (is_test() || is_bench()) {
48 let explanation = if is_core {
49 "core unit tests and benchmarks must be placed into \
50 `core/tests` or `core/benches`"
51 } else {
52 "unit tests and benchmarks must be placed into \
53 separate files or directories named \
54 `tests.rs`, `benches.rs`, `tests` or `benches`"
55 };
56 let name = if is_test() { "test" } else { "bench" };
57 tidy_error!(
58 bad,
59 "`{}:{}` contains `#[{}]`; {}",
60 path.display(),
61 i + 1,
62 name,
63 explanation,
64 );
65 return;
66 }
67 }
68 });
69}