1use std::path::Path;
13
14use crate::walk::{filter_dirs, walk};
15
16pub fn check(root_path: &Path, stdlib: bool, bad: &mut bool) {
17 let skip = move |path: &Path, is_dir| {
18 let file_name = path.file_name().unwrap_or_default();
19
20 if is_dir {
22 if filter_dirs(path) || path.ends_with("src/doc") {
23 return true;
24 }
25 } else {
26 let extension = path.extension().unwrap_or_default();
27 if extension != "rs" {
28 return true;
29 }
30 }
31
32 if is_dir && file_name != "tests" && file_name.as_encoded_bytes().ends_with(b"tests") {
34 return true;
35 }
36
37 if !stdlib {
38 if is_dir {
40 if file_name == "tests" || file_name == "benches" {
41 return true;
42 }
43 } else {
44 if file_name == "tests.rs" || file_name == "benches.rs" {
45 return true;
46 }
47 }
48 }
49
50 if is_dir {
51 file_name == "std_detect" || file_name == "std" || file_name == "test"
53 } else {
54 path.ends_with("library/alloc/src/collections/btree/borrow/tests.rs")
58 || path.ends_with("library/alloc/src/collections/btree/map/tests.rs")
59 || path.ends_with("library/alloc/src/collections/btree/node/tests.rs")
60 || path.ends_with("library/alloc/src/collections/btree/set/tests.rs")
61 || path.ends_with("library/alloc/src/collections/linked_list/tests.rs")
62 || path.ends_with("library/alloc/src/collections/vec_deque/tests.rs")
63 || path.ends_with("library/alloc/src/raw_vec/tests.rs")
64 || path.ends_with("library/alloc/src/wtf8/tests.rs")
65 }
66 };
67
68 walk(root_path, skip, &mut |entry, contents| {
69 let path = entry.path();
70 let package = path
71 .strip_prefix(root_path)
72 .unwrap()
73 .components()
74 .next()
75 .unwrap()
76 .as_os_str()
77 .to_str()
78 .unwrap();
79 for (i, line) in contents.lines().enumerate() {
80 let line = line.trim();
81 let is_test = || line.contains("#[test]") && !line.contains("`#[test]");
82 let is_bench = || line.contains("#[bench]") && !line.contains("`#[bench]");
83 if !line.starts_with("//") && (is_test() || is_bench()) {
84 let explanation = if stdlib {
85 format!(
86 "`{package}` unit tests and benchmarks must be placed into `{package}tests`"
87 )
88 } else {
89 "unit tests and benchmarks must be placed into \
90 separate files or directories named \
91 `tests.rs`, `benches.rs`, `tests` or `benches`"
92 .to_owned()
93 };
94 let name = if is_test() { "test" } else { "bench" };
95 tidy_error!(
96 bad,
97 "`{}:{}` contains `#[{}]`; {}",
98 path.display(),
99 i + 1,
100 name,
101 explanation,
102 );
103 return;
104 }
105 }
106 });
107}