Rollup merge of #62996 - petrochenkov:outest, r=Mark-Simulacrum
tidy: Add a check for inline unit tests As described in https://github.com/rust-lang/rust/issues/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
This commit is contained in:
commit
c3c03098d8
4 changed files with 97 additions and 30 deletions
|
|
@ -38,8 +38,8 @@ pub mod pal;
|
|||
pub mod deps;
|
||||
pub mod extdeps;
|
||||
pub mod ui_tests;
|
||||
pub mod unit_tests;
|
||||
pub mod unstable_book;
|
||||
pub mod libcoretest;
|
||||
|
||||
fn filter_dirs(path: &Path) -> bool {
|
||||
let skip = [
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
//! Tidy check to ensure `#[test]` is not used directly inside `libcore`.
|
||||
//!
|
||||
//! `#![no_core]` libraries cannot be tested directly due to duplicating lang
|
||||
//! item. All tests must be written externally in `libcore/tests`.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
pub fn check(path: &Path, bad: &mut bool) {
|
||||
let libcore_path = path.join("libcore");
|
||||
super::walk(
|
||||
&libcore_path,
|
||||
&mut |subpath| t!(subpath.strip_prefix(&libcore_path)).starts_with("tests"),
|
||||
&mut |entry, contents| {
|
||||
let subpath = entry.path();
|
||||
if let Some("rs") = subpath.extension().and_then(|e| e.to_str()) {
|
||||
let contents = contents.trim();
|
||||
if !contents.starts_with("//") && contents.contains("#[test]") {
|
||||
tidy_error!(
|
||||
bad,
|
||||
"`{}` contains `#[test]`; libcore tests must be placed inside \
|
||||
`src/libcore/tests/`",
|
||||
subpath.display()
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ fn main() {
|
|||
let collected = features::check(&path, &mut bad, verbose);
|
||||
pal::check(&path, &mut bad);
|
||||
unstable_book::check(&path, collected, &mut bad);
|
||||
libcoretest::check(&path, &mut bad);
|
||||
unit_tests::check(&path, &mut bad);
|
||||
if !args.iter().any(|s| *s == "--no-vendor") {
|
||||
deps::check(&path, &mut bad);
|
||||
}
|
||||
|
|
|
|||
95
src/tools/tidy/src/unit_tests.rs
Normal file
95
src/tools/tidy/src/unit_tests.rs
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
//! Tidy check to ensure `#[test]` and `#[bench]` are not used directly inside
|
||||
//! `libcore` or `liballoc`.
|
||||
//!
|
||||
//! `#![no_std]` libraries cannot be tested directly due to duplicating lang
|
||||
//! items. All tests and benchmarks must be written externally in `libcore/{tests,benches}`
|
||||
//! or `liballoc/{tests,benches}`.
|
||||
//!
|
||||
//! Outside of libcore and liballoc tests and benchmarks should be outlined into separate files
|
||||
//! named `tests.rs` or `benches.rs`, or directories named `tests` or `benches` unconfigured
|
||||
//! during normal build.
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
pub fn check(root_path: &Path, bad: &mut bool) {
|
||||
let libcore = &root_path.join("libcore");
|
||||
let liballoc = &root_path.join("liballoc");
|
||||
let libcore_tests = &root_path.join("libcore/tests");
|
||||
let liballoc_tests = &root_path.join("liballoc/tests");
|
||||
let libcore_benches = &root_path.join("libcore/benches");
|
||||
let liballoc_benches = &root_path.join("liballoc/benches");
|
||||
let is_core_or_alloc = |path: &Path| {
|
||||
let is_core = path.starts_with(libcore) &&
|
||||
!(path.starts_with(libcore_tests) || path.starts_with(libcore_benches));
|
||||
let is_alloc = path.starts_with(liballoc) &&
|
||||
!(path.starts_with(liballoc_tests) || path.starts_with(liballoc_benches));
|
||||
is_core || is_alloc
|
||||
};
|
||||
let fixme = [
|
||||
"liballoc",
|
||||
"libpanic_unwind/dwarf",
|
||||
"librustc",
|
||||
"librustc_data_structures",
|
||||
"librustc_incremental/persist",
|
||||
"librustc_lexer/src",
|
||||
"librustc_target/spec",
|
||||
"librustdoc",
|
||||
"libserialize",
|
||||
"libstd",
|
||||
"libsyntax",
|
||||
"libsyntax_pos",
|
||||
"libterm/terminfo",
|
||||
"libtest",
|
||||
"tools/compiletest/src",
|
||||
"tools/tidy/src",
|
||||
];
|
||||
|
||||
let mut skip = |path: &Path| {
|
||||
let file_name = path.file_name().unwrap_or_default();
|
||||
if path.is_dir() {
|
||||
super::filter_dirs(path) ||
|
||||
path.ends_with("src/test") ||
|
||||
path.ends_with("src/doc") ||
|
||||
(file_name == "tests" || file_name == "benches") && !is_core_or_alloc(path) ||
|
||||
fixme.iter().any(|p| path.ends_with(p))
|
||||
} else {
|
||||
let extension = path.extension().unwrap_or_default();
|
||||
extension != "rs" ||
|
||||
(file_name == "tests.rs" || file_name == "benches.rs") && !is_core_or_alloc(path)
|
||||
}
|
||||
};
|
||||
|
||||
super::walk(
|
||||
root_path,
|
||||
&mut skip,
|
||||
&mut |entry, contents| {
|
||||
let path = entry.path();
|
||||
let is_libcore = path.starts_with(libcore);
|
||||
let is_liballoc = path.starts_with(liballoc);
|
||||
for (i, line) in contents.lines().enumerate() {
|
||||
let line = line.trim();
|
||||
let is_test = || line.contains("#[test]") && !line.contains("`#[test]");
|
||||
let is_bench = || line.contains("#[bench]") && !line.contains("`#[bench]");
|
||||
if !line.starts_with("//") && (is_test() || is_bench()) {
|
||||
let explanation = if is_libcore {
|
||||
"libcore unit tests and benchmarks must be placed into \
|
||||
`libcore/tests` or `libcore/benches`"
|
||||
} else if is_liballoc {
|
||||
"liballoc unit tests and benchmarks must be placed into \
|
||||
`liballoc/tests` or `liballoc/benches`"
|
||||
} else {
|
||||
"unit tests and benchmarks must be placed into \
|
||||
separate files or directories named \
|
||||
`tests.rs`, `benches.rs`, `tests` or `benches`"
|
||||
};
|
||||
let name = if is_test() { "test" } else { "bench" };
|
||||
tidy_error!(
|
||||
bad, "`{}:{}` contains `#[{}]`; {}",
|
||||
path.display(), i + 1, name, explanation,
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue