Skip to content

Commit 5d149c5

Browse files
committed
Auto merge of rust-lang#10543 - blyxyas:tests_outside_test_module, r=flip1995
Add `tests_outside_test_module` lint Adds `tests_outside_test_module` from rust-lang#10506. This PR **doesn't** close the issue, just resolves task 1. changelog: [`tests_outside_test_module`]: The lint has been added
2 parents 73e412b + b2f9191 commit 5d149c5

6 files changed

+104
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4936,6 +4936,7 @@ Released 2018-09-13
49364936
[`tabs_in_doc_comments`]: https://rust-lang.github.io/rust-clippy/master/index.html#tabs_in_doc_comments
49374937
[`temporary_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_assignment
49384938
[`temporary_cstring_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_cstring_as_ptr
4939+
[`tests_outside_test_module`]: https://rust-lang.github.io/rust-clippy/master/index.html#tests_outside_test_module
49394940
[`to_digit_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_digit_is_some
49404941
[`to_string_in_display`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_in_display
49414942
[`to_string_in_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_in_format_args

clippy_lints/src/declared_lints.rs

+1
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
577577
crate::swap_ptr_to_ref::SWAP_PTR_TO_REF_INFO,
578578
crate::tabs_in_doc_comments::TABS_IN_DOC_COMMENTS_INFO,
579579
crate::temporary_assignment::TEMPORARY_ASSIGNMENT_INFO,
580+
crate::tests_outside_test_module::TESTS_OUTSIDE_TEST_MODULE_INFO,
580581
crate::to_digit_is_some::TO_DIGIT_IS_SOME_INFO,
581582
crate::trailing_empty_array::TRAILING_EMPTY_ARRAY_INFO,
582583
crate::trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS_INFO,

clippy_lints/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ mod swap;
291291
mod swap_ptr_to_ref;
292292
mod tabs_in_doc_comments;
293293
mod temporary_assignment;
294+
mod tests_outside_test_module;
294295
mod to_digit_is_some;
295296
mod trailing_empty_array;
296297
mod trait_bounds;
@@ -955,6 +956,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
955956
))
956957
});
957958
store.register_late_pass(|_| Box::new(lines_filter_map_ok::LinesFilterMapOk));
959+
store.register_late_pass(|_| Box::new(tests_outside_test_module::TestsOutsideTestModule));
958960
// add lints here, do not remove this comment, it's used in `new_lint`
959961
}
960962

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use clippy_utils::{diagnostics::span_lint_and_note, is_in_cfg_test, is_in_test_function};
2+
use rustc_hir::{intravisit::FnKind, Body, FnDecl};
3+
use rustc_lint::{LateContext, LateLintPass};
4+
use rustc_session::{declare_lint_pass, declare_tool_lint};
5+
use rustc_span::{def_id::LocalDefId, Span};
6+
7+
declare_clippy_lint! {
8+
/// ### What it does
9+
/// Triggers when a testing function (marked with the `#[test]` attribute) isn't inside a testing module
10+
/// (marked with `#[cfg(test)]`).
11+
/// ### Why is this bad?
12+
/// The idiomatic (and more performant) way of writing tests is inside a testing module (flagged with `#[cfg(test)]`),
13+
/// having test functions outside of this module is confusing and may lead to them being "hidden".
14+
/// ### Example
15+
/// ```rust
16+
/// #[test]
17+
/// fn my_cool_test() {
18+
/// // [...]
19+
/// }
20+
///
21+
/// #[cfg(test)]
22+
/// mod tests {
23+
/// // [...]
24+
/// }
25+
///
26+
/// ```
27+
/// Use instead:
28+
/// ```rust
29+
/// #[cfg(test)]
30+
/// mod tests {
31+
/// #[test]
32+
/// fn my_cool_test() {
33+
/// // [...]
34+
/// }
35+
/// }
36+
/// ```
37+
#[clippy::version = "1.70.0"]
38+
pub TESTS_OUTSIDE_TEST_MODULE,
39+
restriction,
40+
"A test function is outside the testing module."
41+
}
42+
43+
declare_lint_pass!(TestsOutsideTestModule => [TESTS_OUTSIDE_TEST_MODULE]);
44+
45+
impl LateLintPass<'_> for TestsOutsideTestModule {
46+
fn check_fn(
47+
&mut self,
48+
cx: &LateContext<'_>,
49+
kind: FnKind<'_>,
50+
_: &FnDecl<'_>,
51+
body: &Body<'_>,
52+
sp: Span,
53+
_: LocalDefId,
54+
) {
55+
if_chain! {
56+
if !matches!(kind, FnKind::Closure);
57+
if is_in_test_function(cx.tcx, body.id().hir_id);
58+
if !is_in_cfg_test(cx.tcx, body.id().hir_id);
59+
then {
60+
span_lint_and_note(
61+
cx,
62+
TESTS_OUTSIDE_TEST_MODULE,
63+
sp,
64+
"this function marked with #[test] is outside a #[cfg(test)] module",
65+
None,
66+
"move it to a testing module marked with #[cfg(test)]",
67+
);
68+
}
69+
}
70+
}
71+
}

tests/ui/tests_outside_test_module.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// compile-flags: --test
2+
#![allow(unused)]
3+
#![warn(clippy::tests_outside_test_module)]
4+
5+
fn main() {
6+
// test code goes here
7+
}
8+
9+
// Should lint
10+
#[test]
11+
fn my_test() {}
12+
13+
#[cfg(test)]
14+
mod tests {
15+
// Should not lint
16+
#[test]
17+
fn my_test() {}
18+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: this function marked with #[test] is outside a #[cfg(test)] module
2+
--> $DIR/tests_outside_test_module.rs:11:1
3+
|
4+
LL | fn my_test() {}
5+
| ^^^^^^^^^^^^^^^
6+
|
7+
= note: move it to a testing module marked with #[cfg(test)]
8+
= note: `-D clippy::tests-outside-test-module` implied by `-D warnings`
9+
10+
error: aborting due to previous error
11+

0 commit comments

Comments
 (0)