60 lines
2.1 KiB
Rust
60 lines
2.1 KiB
Rust
use clippy_utils::diagnostics::span_lint_and_then;
|
|
use rustc_ast::MetaItemInner;
|
|
use rustc_lint::{EarlyContext, EarlyLintPass};
|
|
use rustc_session::declare_lint_pass;
|
|
|
|
declare_clippy_lint! {
|
|
/// ### What it does
|
|
/// Checks for usage of `cfg` that excludes code from `test` builds. (i.e., `#[cfg(not(test))]`)
|
|
///
|
|
/// ### Why is this bad?
|
|
/// This may give the false impression that a codebase has 100% coverage, yet actually has untested code.
|
|
/// Enabling this also guards against excessive mockery as well, which is an anti-pattern.
|
|
///
|
|
/// ### Example
|
|
/// ```rust
|
|
/// # fn important_check() {}
|
|
/// #[cfg(not(test))]
|
|
/// important_check(); // I'm not actually tested, but not including me will falsely increase coverage!
|
|
/// ```
|
|
/// Use instead:
|
|
/// ```rust
|
|
/// # fn important_check() {}
|
|
/// important_check();
|
|
/// ```
|
|
#[clippy::version = "1.81.0"]
|
|
pub CFG_NOT_TEST,
|
|
restriction,
|
|
"enforce against excluding code from test builds"
|
|
}
|
|
|
|
declare_lint_pass!(CfgNotTest => [CFG_NOT_TEST]);
|
|
|
|
impl EarlyLintPass for CfgNotTest {
|
|
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &rustc_ast::Attribute) {
|
|
if attr.has_name(rustc_span::sym::cfg) && contains_not_test(attr.meta_item_list().as_deref(), false) {
|
|
span_lint_and_then(
|
|
cx,
|
|
CFG_NOT_TEST,
|
|
attr.span,
|
|
"code is excluded from test builds",
|
|
|diag| {
|
|
diag.help("consider not excluding any code from test builds");
|
|
diag.note_once("this could increase code coverage despite not actually being tested");
|
|
},
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn contains_not_test(list: Option<&[MetaItemInner]>, not: bool) -> bool {
|
|
list.is_some_and(|list| {
|
|
list.iter().any(|item| {
|
|
item.ident().is_some_and(|ident| match ident.name {
|
|
rustc_span::sym::not => contains_not_test(item.meta_item_list(), !not),
|
|
rustc_span::sym::test => not,
|
|
_ => contains_not_test(item.meta_item_list(), not),
|
|
})
|
|
})
|
|
})
|
|
}
|