Skip to content

Commit 0d1441f

Browse files
committed
feat: adds redundant_test_prefix clippy lint
Closes rust-lang#8931.
1 parent da4b212 commit 0d1441f

17 files changed

+192
-86
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5697,6 +5697,7 @@ Released 2018-09-13
56975697
[`redundant_pub_crate`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pub_crate
56985698
[`redundant_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_slicing
56995699
[`redundant_static_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes
5700+
[`redundant_test_prefix`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_test_prefix
57005701
[`redundant_type_annotations`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_type_annotations
57015702
[`ref_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_as_ptr
57025703
[`ref_binding_to_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_binding_to_reference

clippy_dev/src/new_lint.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ fn setup_mod_file(path: &Path, lint: &LintData<'_>) -> io::Result<&'static str>
581581
}
582582

583583
#[test]
584-
fn test_camel_case() {
584+
fn camel_case() {
585585
let s = "a_lint";
586586
let s2 = to_camel_case(s);
587587
assert_eq!(s2, "ALint");

clippy_dev/src/update_lints.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,7 @@ mod tests {
10421042
use super::*;
10431043

10441044
#[test]
1045-
fn test_parse_contents() {
1045+
fn parse_contents() {
10461046
static CONTENTS: &str = r#"
10471047
declare_clippy_lint! {
10481048
#[clippy::version = "Hello Clippy!"]
@@ -1060,7 +1060,7 @@ mod tests {
10601060
}
10611061
"#;
10621062
let mut result = Vec::new();
1063-
parse_contents(CONTENTS, "module_name", &mut result);
1063+
super::parse_contents(CONTENTS, "module_name", &mut result);
10641064
for r in &mut result {
10651065
r.declaration_range = Range::default();
10661066
}
@@ -1085,7 +1085,7 @@ mod tests {
10851085
}
10861086

10871087
#[test]
1088-
fn test_parse_deprecated_contents() {
1088+
fn parse_deprecated_contents() {
10891089
static DEPRECATED_CONTENTS: &str = r#"
10901090
/// some doc comment
10911091
declare_deprecated_lint! {
@@ -1096,7 +1096,7 @@ mod tests {
10961096
"#;
10971097

10981098
let mut result = Vec::new();
1099-
parse_deprecated_contents(DEPRECATED_CONTENTS, &mut result);
1099+
super::parse_deprecated_contents(DEPRECATED_CONTENTS, &mut result);
11001100
for r in &mut result {
11011101
r.declaration_range = Range::default();
11021102
}
@@ -1110,7 +1110,7 @@ mod tests {
11101110
}
11111111

11121112
#[test]
1113-
fn test_usable_lints() {
1113+
fn usable_lints() {
11141114
let lints = vec![
11151115
Lint::new(
11161116
"should_assert_eq2",
@@ -1145,7 +1145,7 @@ mod tests {
11451145
}
11461146

11471147
#[test]
1148-
fn test_by_lint_group() {
1148+
fn by_lint_group() {
11491149
let lints = vec![
11501150
Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()),
11511151
Lint::new(
@@ -1179,7 +1179,7 @@ mod tests {
11791179
}
11801180

11811181
#[test]
1182-
fn test_gen_deprecated() {
1182+
fn gen_deprecated() {
11831183
let lints = vec![
11841184
DeprecatedLint::new(
11851185
"should_assert_eq",
@@ -1205,6 +1205,6 @@ mod tests {
12051205
.join("\n")
12061206
+ "\n";
12071207

1208-
assert_eq!(expected, gen_deprecated(&lints));
1208+
assert_eq!(expected, super::gen_deprecated(&lints));
12091209
}
12101210
}

clippy_lints/src/cargo/feature_name.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ fn lint(cx: &LateContext<'_>, feature: &str, substring: &str, is_prefix: bool) {
8080
}
8181

8282
#[test]
83-
fn test_prefixes_sorted() {
83+
fn prefixes_sorted() {
8484
let mut sorted_prefixes = PREFIXES;
8585
sorted_prefixes.sort_unstable();
8686
assert_eq!(PREFIXES, sorted_prefixes);

clippy_lints/src/declared_lints.rs

+1
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
624624
crate::redundant_slicing::DEREF_BY_SLICING_INFO,
625625
crate::redundant_slicing::REDUNDANT_SLICING_INFO,
626626
crate::redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES_INFO,
627+
crate::redundant_test_prefix::REDUNDANT_TEST_PREFIX_INFO,
627628
crate::redundant_type_annotations::REDUNDANT_TYPE_ANNOTATIONS_INFO,
628629
crate::ref_option_ref::REF_OPTION_REF_INFO,
629630
crate::ref_patterns::REF_PATTERNS_INFO,

clippy_lints/src/doc/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ declare_clippy_lint! {
223223
/// /// assert_eq!(1_u8, 1);
224224
/// /// }
225225
/// /// ```
226-
/// fn test_attr_in_doctest() {
226+
/// fn attr_in_doctest() {
227227
/// unimplemented!();
228228
/// }
229229
/// ```

clippy_lints/src/empty_with_brackets.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -144,23 +144,22 @@ fn has_no_fields(cx: &EarlyContext<'_>, var_data: &VariantData, braces_span: Spa
144144

145145
#[cfg(test)]
146146
mod unit_test {
147-
use super::*;
148147

149148
#[test]
150-
fn test_has_no_ident_token() {
149+
fn has_no_ident_token() {
151150
let input = "{ field: u8 }";
152-
assert!(!has_no_ident_token(input));
151+
assert!(!super::has_no_ident_token(input));
153152

154153
let input = "(u8, String);";
155-
assert!(!has_no_ident_token(input));
154+
assert!(!super::has_no_ident_token(input));
156155

157156
let input = " {
158157
// test = 5
159158
}
160159
";
161-
assert!(has_no_ident_token(input));
160+
assert!(super::has_no_ident_token(input));
162161

163162
let input = " ();";
164-
assert!(has_no_ident_token(input));
163+
assert!(super::has_no_ident_token(input));
165164
}
166165
}

clippy_lints/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ mod redundant_locals;
301301
mod redundant_pub_crate;
302302
mod redundant_slicing;
303303
mod redundant_static_lifetimes;
304+
mod redundant_test_prefix;
304305
mod redundant_type_annotations;
305306
mod ref_option_ref;
306307
mod ref_patterns;
@@ -1165,6 +1166,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
11651166
..Default::default()
11661167
})
11671168
});
1169+
store.register_late_pass(|_| Box::new(redundant_test_prefix::RedundantTestPrefix));
11681170
// add lints here, do not remove this comment, it's used in `new_lint`
11691171
}
11701172

clippy_lints/src/matches/overlapping_arms.rs

+40-35
Original file line numberDiff line numberDiff line change
@@ -148,39 +148,44 @@ where
148148
None
149149
}
150150

151-
#[test]
152-
fn test_overlapping() {
153-
use rustc_span::DUMMY_SP;
154-
155-
let sp = |s, e| SpannedRange {
156-
span: DUMMY_SP,
157-
node: (s, e),
158-
};
159-
160-
assert_eq!(None, overlapping::<u8>(&[]));
161-
assert_eq!(None, overlapping(&[sp(1, EndBound::Included(4))]));
162-
assert_eq!(
163-
None,
164-
overlapping(&[sp(1, EndBound::Included(4)), sp(5, EndBound::Included(6))])
165-
);
166-
assert_eq!(
167-
None,
168-
overlapping(&[
169-
sp(1, EndBound::Included(4)),
170-
sp(5, EndBound::Included(6)),
171-
sp(10, EndBound::Included(11))
172-
],)
173-
);
174-
assert_eq!(
175-
Some((&sp(1, EndBound::Included(4)), &sp(3, EndBound::Included(6)))),
176-
overlapping(&[sp(1, EndBound::Included(4)), sp(3, EndBound::Included(6))])
177-
);
178-
assert_eq!(
179-
Some((&sp(5, EndBound::Included(6)), &sp(6, EndBound::Included(11)))),
180-
overlapping(&[
181-
sp(1, EndBound::Included(4)),
182-
sp(5, EndBound::Included(6)),
183-
sp(6, EndBound::Included(11))
184-
],)
185-
);
151+
#[cfg(test)]
152+
mod test {
153+
use super::{EndBound, SpannedRange};
154+
155+
#[test]
156+
fn overlapping() {
157+
use rustc_span::DUMMY_SP;
158+
159+
let sp = |s, e| SpannedRange {
160+
span: DUMMY_SP,
161+
node: (s, e),
162+
};
163+
164+
assert_eq!(None, super::overlapping::<u8>(&[]));
165+
assert_eq!(None, super::overlapping(&[sp(1, EndBound::Included(4))]));
166+
assert_eq!(
167+
None,
168+
super::overlapping(&[sp(1, EndBound::Included(4)), sp(5, EndBound::Included(6))])
169+
);
170+
assert_eq!(
171+
None,
172+
super::overlapping(&[
173+
sp(1, EndBound::Included(4)),
174+
sp(5, EndBound::Included(6)),
175+
sp(10, EndBound::Included(11))
176+
],)
177+
);
178+
assert_eq!(
179+
Some((&sp(1, EndBound::Included(4)), &sp(3, EndBound::Included(6)))),
180+
super::overlapping(&[sp(1, EndBound::Included(4)), sp(3, EndBound::Included(6))])
181+
);
182+
assert_eq!(
183+
Some((&sp(5, EndBound::Included(6)), &sp(6, EndBound::Included(11)))),
184+
super::overlapping(&[
185+
sp(1, EndBound::Included(4)),
186+
sp(5, EndBound::Included(6)),
187+
sp(6, EndBound::Included(11))
188+
],)
189+
);
190+
}
186191
}

clippy_lints/src/needless_continue.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -440,11 +440,10 @@ fn span_of_first_expr_in_block(block: &ast::Block) -> Option<Span> {
440440

441441
#[cfg(test)]
442442
mod test {
443-
use super::erode_from_back;
444443

445444
#[test]
446445
#[rustfmt::skip]
447-
fn test_erode_from_back() {
446+
fn erode_from_back() {
448447
let input = "\
449448
{
450449
let x = 5;
@@ -456,19 +455,19 @@ mod test {
456455
let x = 5;
457456
let y = format!(\"{}\", 42);";
458457

459-
let got = erode_from_back(input);
458+
let got = super::erode_from_back(input);
460459
assert_eq!(expected, got);
461460
}
462461

463462
#[test]
464463
#[rustfmt::skip]
465-
fn test_erode_from_back_no_brace() {
464+
fn erode_from_back_no_brace() {
466465
let input = "\
467466
let x = 5;
468467
let y = something();
469468
";
470469
let expected = input;
471-
let got = erode_from_back(input);
470+
let got = super::erode_from_back(input);
472471
assert_eq!(expected, got);
473472
}
474473
}
+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use clippy_utils::diagnostics::span_lint_and_help;
2+
use clippy_utils::{is_in_cfg_test, is_in_test_function};
3+
use rustc_hir::intravisit::FnKind;
4+
use rustc_hir::{Body, FnDecl};
5+
use rustc_lint::{LateContext, LateLintPass};
6+
use rustc_session::declare_lint_pass;
7+
use rustc_span::def_id::LocalDefId;
8+
use rustc_span::Span;
9+
10+
declare_clippy_lint! {
11+
/// ### What it does
12+
/// Triggers when a function annotated with the `#[test]` macro begins with `test_`
13+
/// ### Why is this bad?
14+
/// This is redundant, since the annotations already denotes the function a test.
15+
/// Tests are executed using `cargo test `module::test-name-here::`.
16+
/// It's clear that a test is a test, without prefixing `test_` to the test name.
17+
/// ### Example
18+
/// ```no_run
19+
/// #[test]
20+
/// fn my_test_case() {
21+
/// // test logic here...
22+
/// }
23+
/// ```
24+
/// Use instead:
25+
/// ```no_run
26+
/// #[test]
27+
/// fn my_test_case() {
28+
/// // test logic here...
29+
/// }
30+
/// ```
31+
#[clippy::version = "1.79.0"]
32+
pub REDUNDANT_TEST_PREFIX,
33+
pedantic,
34+
"A test name is prefixed with `test`"
35+
}
36+
37+
declare_lint_pass!(RedundantTestPrefix => [REDUNDANT_TEST_PREFIX]);
38+
39+
impl LateLintPass<'_> for RedundantTestPrefix {
40+
fn check_fn(
41+
&mut self,
42+
cx: &LateContext<'_>,
43+
fn_kind: FnKind<'_>,
44+
_: &FnDecl<'_>,
45+
body: &Body<'_>,
46+
span: Span,
47+
_: LocalDefId,
48+
) {
49+
if is_prefixed_with_test_fn(fn_kind)
50+
&& is_in_test_function(cx.tcx, body.id().hir_id)
51+
&& is_in_cfg_test(cx.tcx, body.id().hir_id)
52+
{
53+
span_lint_and_help(
54+
cx,
55+
REDUNDANT_TEST_PREFIX,
56+
span,
57+
"this test is prefixed redundantly with `test`",
58+
None,
59+
"consider removing the redundant `test` prefix from the test name",
60+
);
61+
}
62+
}
63+
}
64+
65+
fn is_prefixed_with_test_fn(fn_kind: FnKind<'_>) -> bool {
66+
match fn_kind {
67+
FnKind::ItemFn(ident, ..) => {
68+
// check if `fn` name is prefixed with `test_`
69+
ident.name.as_str().starts_with("test_")
70+
},
71+
// ignore closures
72+
_ => false,
73+
}
74+
}

0 commit comments

Comments
 (0)