diff --git a/CHANGELOG.md b/CHANGELOG.md index d5115f70f662..02f550c93d71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5697,6 +5697,7 @@ Released 2018-09-13 [`redundant_pub_crate`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pub_crate [`redundant_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_slicing [`redundant_static_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes +[`redundant_test_prefix`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_test_prefix [`redundant_type_annotations`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_type_annotations [`ref_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_as_ptr [`ref_binding_to_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_binding_to_reference diff --git a/clippy_dev/src/new_lint.rs b/clippy_dev/src/new_lint.rs index 2e56eb8ec15f..b94c8c93a7a6 100644 --- a/clippy_dev/src/new_lint.rs +++ b/clippy_dev/src/new_lint.rs @@ -581,7 +581,7 @@ fn setup_mod_file(path: &Path, lint: &LintData<'_>) -> io::Result<&'static str> } #[test] -fn test_camel_case() { +fn camel_case() { let s = "a_lint"; let s2 = to_camel_case(s); assert_eq!(s2, "ALint"); diff --git a/clippy_dev/src/update_lints.rs b/clippy_dev/src/update_lints.rs index 45353901c98f..5278db081512 100644 --- a/clippy_dev/src/update_lints.rs +++ b/clippy_dev/src/update_lints.rs @@ -1042,7 +1042,7 @@ mod tests { use super::*; #[test] - fn test_parse_contents() { + fn parse_contents() { static CONTENTS: &str = r#" declare_clippy_lint! { #[clippy::version = "Hello Clippy!"] @@ -1060,7 +1060,7 @@ mod tests { } "#; let mut result = Vec::new(); - parse_contents(CONTENTS, "module_name", &mut result); + super::parse_contents(CONTENTS, "module_name", &mut result); for r in &mut result { r.declaration_range = Range::default(); } @@ -1085,7 +1085,7 @@ mod tests { } #[test] - fn test_parse_deprecated_contents() { + fn parse_deprecated_contents() { static DEPRECATED_CONTENTS: &str = r#" /// some doc comment declare_deprecated_lint! { @@ -1096,7 +1096,7 @@ mod tests { "#; let mut result = Vec::new(); - parse_deprecated_contents(DEPRECATED_CONTENTS, &mut result); + super::parse_deprecated_contents(DEPRECATED_CONTENTS, &mut result); for r in &mut result { r.declaration_range = Range::default(); } @@ -1110,7 +1110,7 @@ mod tests { } #[test] - fn test_usable_lints() { + fn usable_lints() { let lints = vec![ Lint::new( "should_assert_eq2", @@ -1145,7 +1145,7 @@ mod tests { } #[test] - fn test_by_lint_group() { + fn by_lint_group() { let lints = vec![ Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()), Lint::new( @@ -1179,7 +1179,7 @@ mod tests { } #[test] - fn test_gen_deprecated() { + fn gen_deprecated() { let lints = vec![ DeprecatedLint::new( "should_assert_eq", @@ -1205,6 +1205,6 @@ mod tests { .join("\n") + "\n"; - assert_eq!(expected, gen_deprecated(&lints)); + assert_eq!(expected, super::gen_deprecated(&lints)); } } diff --git a/clippy_lints/src/cargo/feature_name.rs b/clippy_lints/src/cargo/feature_name.rs index 6982b96dd3b3..12a6717faf42 100644 --- a/clippy_lints/src/cargo/feature_name.rs +++ b/clippy_lints/src/cargo/feature_name.rs @@ -80,7 +80,7 @@ fn lint(cx: &LateContext<'_>, feature: &str, substring: &str, is_prefix: bool) { } #[test] -fn test_prefixes_sorted() { +fn prefixes_sorted() { let mut sorted_prefixes = PREFIXES; sorted_prefixes.sort_unstable(); assert_eq!(PREFIXES, sorted_prefixes); diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index df2ef465700d..9dfe081e3e9e 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -624,6 +624,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::redundant_slicing::DEREF_BY_SLICING_INFO, crate::redundant_slicing::REDUNDANT_SLICING_INFO, crate::redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES_INFO, + crate::redundant_test_prefix::REDUNDANT_TEST_PREFIX_INFO, crate::redundant_type_annotations::REDUNDANT_TYPE_ANNOTATIONS_INFO, crate::ref_option_ref::REF_OPTION_REF_INFO, crate::ref_patterns::REF_PATTERNS_INFO, diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index e9c4559ff4d2..fb3ed04dc5ef 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -223,7 +223,7 @@ declare_clippy_lint! { /// /// assert_eq!(1_u8, 1); /// /// } /// /// ``` - /// fn test_attr_in_doctest() { + /// fn attr_in_doctest() { /// unimplemented!(); /// } /// ``` diff --git a/clippy_lints/src/empty_with_brackets.rs b/clippy_lints/src/empty_with_brackets.rs index 745599b0e57a..37714dfc3d69 100644 --- a/clippy_lints/src/empty_with_brackets.rs +++ b/clippy_lints/src/empty_with_brackets.rs @@ -144,23 +144,22 @@ fn has_no_fields(cx: &EarlyContext<'_>, var_data: &VariantData, braces_span: Spa #[cfg(test)] mod unit_test { - use super::*; #[test] - fn test_has_no_ident_token() { + fn has_no_ident_token() { let input = "{ field: u8 }"; - assert!(!has_no_ident_token(input)); + assert!(!super::has_no_ident_token(input)); let input = "(u8, String);"; - assert!(!has_no_ident_token(input)); + assert!(!super::has_no_ident_token(input)); let input = " { // test = 5 } "; - assert!(has_no_ident_token(input)); + assert!(super::has_no_ident_token(input)); let input = " ();"; - assert!(has_no_ident_token(input)); + assert!(super::has_no_ident_token(input)); } } diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 3328d642bd85..42a7a87b201c 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -301,6 +301,7 @@ mod redundant_locals; mod redundant_pub_crate; mod redundant_slicing; mod redundant_static_lifetimes; +mod redundant_test_prefix; mod redundant_type_annotations; mod ref_option_ref; mod ref_patterns; @@ -1165,6 +1166,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { ..Default::default() }) }); + store.register_late_pass(|_| Box::new(redundant_test_prefix::RedundantTestPrefix)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_lints/src/matches/overlapping_arms.rs b/clippy_lints/src/matches/overlapping_arms.rs index 8199366d175f..40811eba03c3 100644 --- a/clippy_lints/src/matches/overlapping_arms.rs +++ b/clippy_lints/src/matches/overlapping_arms.rs @@ -148,39 +148,44 @@ where None } -#[test] -fn test_overlapping() { - use rustc_span::DUMMY_SP; - - let sp = |s, e| SpannedRange { - span: DUMMY_SP, - node: (s, e), - }; - - assert_eq!(None, overlapping::(&[])); - assert_eq!(None, overlapping(&[sp(1, EndBound::Included(4))])); - assert_eq!( - None, - overlapping(&[sp(1, EndBound::Included(4)), sp(5, EndBound::Included(6))]) - ); - assert_eq!( - None, - overlapping(&[ - sp(1, EndBound::Included(4)), - sp(5, EndBound::Included(6)), - sp(10, EndBound::Included(11)) - ],) - ); - assert_eq!( - Some((&sp(1, EndBound::Included(4)), &sp(3, EndBound::Included(6)))), - overlapping(&[sp(1, EndBound::Included(4)), sp(3, EndBound::Included(6))]) - ); - assert_eq!( - Some((&sp(5, EndBound::Included(6)), &sp(6, EndBound::Included(11)))), - overlapping(&[ - sp(1, EndBound::Included(4)), - sp(5, EndBound::Included(6)), - sp(6, EndBound::Included(11)) - ],) - ); +#[cfg(test)] +mod test { + use super::{EndBound, SpannedRange}; + + #[test] + fn overlapping() { + use rustc_span::DUMMY_SP; + + let sp = |s, e| SpannedRange { + span: DUMMY_SP, + node: (s, e), + }; + + assert_eq!(None, super::overlapping::(&[])); + assert_eq!(None, super::overlapping(&[sp(1, EndBound::Included(4))])); + assert_eq!( + None, + super::overlapping(&[sp(1, EndBound::Included(4)), sp(5, EndBound::Included(6))]) + ); + assert_eq!( + None, + super::overlapping(&[ + sp(1, EndBound::Included(4)), + sp(5, EndBound::Included(6)), + sp(10, EndBound::Included(11)) + ],) + ); + assert_eq!( + Some((&sp(1, EndBound::Included(4)), &sp(3, EndBound::Included(6)))), + super::overlapping(&[sp(1, EndBound::Included(4)), sp(3, EndBound::Included(6))]) + ); + assert_eq!( + Some((&sp(5, EndBound::Included(6)), &sp(6, EndBound::Included(11)))), + super::overlapping(&[ + sp(1, EndBound::Included(4)), + sp(5, EndBound::Included(6)), + sp(6, EndBound::Included(11)) + ],) + ); + } } diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs index b97cb4579ca7..7cf5e75e7107 100644 --- a/clippy_lints/src/needless_continue.rs +++ b/clippy_lints/src/needless_continue.rs @@ -440,11 +440,10 @@ fn span_of_first_expr_in_block(block: &ast::Block) -> Option { #[cfg(test)] mod test { - use super::erode_from_back; #[test] #[rustfmt::skip] - fn test_erode_from_back() { + fn erode_from_back() { let input = "\ { let x = 5; @@ -456,19 +455,19 @@ mod test { let x = 5; let y = format!(\"{}\", 42);"; - let got = erode_from_back(input); + let got = super::erode_from_back(input); assert_eq!(expected, got); } #[test] #[rustfmt::skip] - fn test_erode_from_back_no_brace() { + fn erode_from_back_no_brace() { let input = "\ let x = 5; let y = something(); "; let expected = input; - let got = erode_from_back(input); + let got = super::erode_from_back(input); assert_eq!(expected, got); } } diff --git a/clippy_lints/src/redundant_test_prefix.rs b/clippy_lints/src/redundant_test_prefix.rs new file mode 100644 index 000000000000..14c2f1f2e65c --- /dev/null +++ b/clippy_lints/src/redundant_test_prefix.rs @@ -0,0 +1,74 @@ +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::{is_in_cfg_test, is_in_test_function}; +use rustc_hir::intravisit::FnKind; +use rustc_hir::{Body, FnDecl}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::declare_lint_pass; +use rustc_span::def_id::LocalDefId; +use rustc_span::Span; + +declare_clippy_lint! { + /// ### What it does + /// Triggers when a function annotated with the `#[test]` macro begins with `test_` + /// ### Why is this bad? + /// This is redundant, since the annotations already denotes the function a test. + /// Tests are executed using `cargo test `module::test-name-here::`. + /// It's clear that a test is a test, without prefixing `test_` to the test name. + /// ### Example + /// ```no_run + /// #[test] + /// fn my_test_case() { + /// // test logic here... + /// } + /// ``` + /// Use instead: + /// ```no_run + /// #[test] + /// fn my_test_case() { + /// // test logic here... + /// } + /// ``` + #[clippy::version = "1.79.0"] + pub REDUNDANT_TEST_PREFIX, + pedantic, + "A test name is prefixed with `test`" +} + +declare_lint_pass!(RedundantTestPrefix => [REDUNDANT_TEST_PREFIX]); + +impl LateLintPass<'_> for RedundantTestPrefix { + fn check_fn( + &mut self, + cx: &LateContext<'_>, + fn_kind: FnKind<'_>, + _: &FnDecl<'_>, + body: &Body<'_>, + span: Span, + _: LocalDefId, + ) { + if is_prefixed_with_test_fn(fn_kind) + && is_in_test_function(cx.tcx, body.id().hir_id) + && is_in_cfg_test(cx.tcx, body.id().hir_id) + { + span_lint_and_help( + cx, + REDUNDANT_TEST_PREFIX, + span, + "this test is prefixed redundantly with `test`", + None, + "consider removing the redundant `test` prefix from the test name", + ); + } + } +} + +fn is_prefixed_with_test_fn(fn_kind: FnKind<'_>) -> bool { + match fn_kind { + FnKind::ItemFn(ident, ..) => { + // check if `fn` name is prefixed with `test_` + ident.name.as_str().starts_with("test_") + }, + // ignore closures + _ => false, + } +} diff --git a/clippy_lints/src/tabs_in_doc_comments.rs b/clippy_lints/src/tabs_in_doc_comments.rs index af9e13dba36e..2b1fc43c1e72 100644 --- a/clippy_lints/src/tabs_in_doc_comments.rs +++ b/clippy_lints/src/tabs_in_doc_comments.rs @@ -152,77 +152,77 @@ mod tests_for_get_chunks_of_tabs { use super::get_chunks_of_tabs; #[test] - fn test_unicode_han_string() { + fn unicode_han_string() { let res = get_chunks_of_tabs(" \u{4f4d}\t"); assert_eq!(res, vec![(4, 5)]); } #[test] - fn test_empty_string() { + fn empty_string() { let res = get_chunks_of_tabs(""); assert_eq!(res, vec![]); } #[test] - fn test_simple() { + fn simple() { let res = get_chunks_of_tabs("sd\t\t\taa"); assert_eq!(res, vec![(2, 5)]); } #[test] - fn test_only_t() { + fn only_t() { let res = get_chunks_of_tabs("\t\t"); assert_eq!(res, vec![(0, 2)]); } #[test] - fn test_only_one_t() { + fn only_one_t() { let res = get_chunks_of_tabs("\t"); assert_eq!(res, vec![(0, 1)]); } #[test] - fn test_double() { + fn double() { let res = get_chunks_of_tabs("sd\tasd\t\taa"); assert_eq!(res, vec![(2, 3), (6, 8)]); } #[test] - fn test_start() { + fn start() { let res = get_chunks_of_tabs("\t\taa"); assert_eq!(res, vec![(0, 2)]); } #[test] - fn test_end() { + fn end() { let res = get_chunks_of_tabs("aa\t\t"); assert_eq!(res, vec![(2, 4)]); } #[test] - fn test_start_single() { + fn start_single() { let res = get_chunks_of_tabs("\taa"); assert_eq!(res, vec![(0, 1)]); } #[test] - fn test_end_single() { + fn end_single() { let res = get_chunks_of_tabs("aa\t"); assert_eq!(res, vec![(2, 3)]); } #[test] - fn test_no_tabs() { + fn no_tabs() { let res = get_chunks_of_tabs("dsfs"); assert_eq!(res, vec![]); diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index 69f593fe04ac..e1762c38c526 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -505,7 +505,7 @@ mod test { use super::{reindent_multiline, without_block_comments}; #[test] - fn test_reindent_multiline_single_line() { + fn reindent_multiline_single_line() { assert_eq!("", reindent_multiline("".into(), false, None)); assert_eq!("...", reindent_multiline("...".into(), false, None)); assert_eq!("...", reindent_multiline(" ...".into(), false, None)); @@ -515,7 +515,7 @@ mod test { #[test] #[rustfmt::skip] - fn test_reindent_multiline_block() { + fn reindent_multiline_block() { assert_eq!("\ if x { y @@ -540,7 +540,7 @@ mod test { #[test] #[rustfmt::skip] - fn test_reindent_multiline_empty_line() { + fn reindent_multiline_empty_line() { assert_eq!("\ if x { y @@ -557,7 +557,7 @@ mod test { #[test] #[rustfmt::skip] - fn test_reindent_multiline_lines_deeper() { + fn reindent_multiline_lines_deeper() { assert_eq!("\ if x { y @@ -572,7 +572,7 @@ mod test { } #[test] - fn test_without_block_comments_lines_without_block_comments() { + fn without_block_comments_lines_without_block_comments() { let result = without_block_comments(vec!["/*", "", "*/"]); println!("result: {result:?}"); assert!(result.is_empty()); diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index 6319c7bfa6b8..1f664e48f68c 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -1097,22 +1097,22 @@ mod test { fn not_op() { use AssocOp::{Add, Equal, Greater, GreaterEqual, LAnd, LOr, Less, LessEqual, NotEqual}; - fn test_not(op: AssocOp, correct: &str) { + fn not(op: AssocOp, correct: &str) { let sugg = Sugg::BinOp(op, "x".into(), "y".into()); assert_eq!((!sugg).to_string(), correct); } // Invert the comparison operator. - test_not(Equal, "x != y"); - test_not(NotEqual, "x == y"); - test_not(Less, "x >= y"); - test_not(LessEqual, "x > y"); - test_not(Greater, "x <= y"); - test_not(GreaterEqual, "x < y"); + not(Equal, "x != y"); + not(NotEqual, "x == y"); + not(Less, "x >= y"); + not(LessEqual, "x > y"); + not(Greater, "x <= y"); + not(GreaterEqual, "x < y"); // Other operators are inverted like !(..). - test_not(Add, "!(x + y)"); - test_not(LAnd, "!(x && y)"); - test_not(LOr, "!(x || y)"); + not(Add, "!(x + y)"); + not(LAnd, "!(x && y)"); + not(LOr, "!(x || y)"); } } diff --git a/rustc_tools_util/src/lib.rs b/rustc_tools_util/src/lib.rs index 4c1d8c3733df..0a70e2af4e82 100644 --- a/rustc_tools_util/src/lib.rs +++ b/rustc_tools_util/src/lib.rs @@ -151,7 +151,7 @@ mod test { use super::*; #[test] - fn test_struct_local() { + fn struct_local() { let vi = get_version_info!(); assert_eq!(vi.major, 0); assert_eq!(vi.minor, 3); @@ -163,13 +163,13 @@ mod test { } #[test] - fn test_display_local() { + fn display_local() { let vi = get_version_info!(); assert_eq!(vi.to_string(), "rustc_tools_util 0.3.0"); } #[test] - fn test_debug_local() { + fn debug_local() { let vi = get_version_info!(); let s = format!("{vi:?}"); assert_eq!( diff --git a/tests/ui/redundant_test_prefix.rs b/tests/ui/redundant_test_prefix.rs new file mode 100644 index 000000000000..ed5c032c4e79 --- /dev/null +++ b/tests/ui/redundant_test_prefix.rs @@ -0,0 +1,11 @@ +#![warn(clippy::redundant_test_prefix)] + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_redundant_name() { + // + } +} diff --git a/tests/ui/redundant_test_prefix.stderr b/tests/ui/redundant_test_prefix.stderr new file mode 100644 index 000000000000..789da75fad4f --- /dev/null +++ b/tests/ui/redundant_test_prefix.stderr @@ -0,0 +1,14 @@ +error: this test is prefixed redundantly with `test` + --> tests/ui/redundant_test_prefix.rs:8:5 + | +LL | / fn test_redundant_name() { +LL | | // +LL | | } + | |_____^ + | + = help: consider removing the redundant `test` prefix from the test name + = note: `-D clippy::redundant-test-prefix` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::redundant_test_prefix)]` + +error: aborting due to 1 previous error +