Skip to content

Commit 41dcba0

Browse files
authored
Rollup merge of rust-lang#62996 - petrochenkov:outest, r=Mark-Simulacrum
tidy: Add a check for inline unit tests As described in rust-lang#61097. There's a large whitelist right now, because in many crates the tests are not outlined yet. ~This PR only outlines tests in one crate (`rustc_lexer`) as an example.~ r? @Mark-Simulacrum
2 parents 7f74000 + aecaa03 commit 41dcba0

File tree

4 files changed

+97
-30
lines changed

4 files changed

+97
-30
lines changed

src/tools/tidy/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ pub mod pal;
3838
pub mod deps;
3939
pub mod extdeps;
4040
pub mod ui_tests;
41+
pub mod unit_tests;
4142
pub mod unstable_book;
42-
pub mod libcoretest;
4343

4444
fn filter_dirs(path: &Path) -> bool {
4545
let skip = [

src/tools/tidy/src/libcoretest.rs

-28
This file was deleted.

src/tools/tidy/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ fn main() {
2727
let collected = features::check(&path, &mut bad, verbose);
2828
pal::check(&path, &mut bad);
2929
unstable_book::check(&path, collected, &mut bad);
30-
libcoretest::check(&path, &mut bad);
30+
unit_tests::check(&path, &mut bad);
3131
if !args.iter().any(|s| *s == "--no-vendor") {
3232
deps::check(&path, &mut bad);
3333
}

src/tools/tidy/src/unit_tests.rs

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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

Comments
 (0)