mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-10 23:24:29 +00:00
Add **Ignore Test** assist
This commit is contained in:
parent
10e3a9879c
commit
9a30707281
6 changed files with 80 additions and 18 deletions
34
crates/assists/src/handlers/ignore_test.rs
Normal file
34
crates/assists/src/handlers/ignore_test.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
use syntax::{ast, AstNode};
|
||||
|
||||
use crate::{utils::test_related_attribute, AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: ignore_test
|
||||
//
|
||||
// Adds `#[ignore]` attribute to the test.
|
||||
//
|
||||
// ```
|
||||
// <|>#[test]
|
||||
// fn arithmetics {
|
||||
// assert_eq!(2 + 2, 5);
|
||||
// }
|
||||
// ```
|
||||
// ->
|
||||
// ```
|
||||
// #[test]
|
||||
// #[ignore]
|
||||
// fn arithmetics {
|
||||
// assert_eq!(2 + 2, 5);
|
||||
// }
|
||||
// ```
|
||||
pub(crate) fn ignore_test(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
let attr: ast::Attr = ctx.find_node_at_offset()?;
|
||||
let func = attr.syntax().parent().and_then(ast::Fn::cast)?;
|
||||
let attr = test_related_attribute(&func)?;
|
||||
|
||||
acc.add(
|
||||
AssistId("ignore_test", AssistKind::None),
|
||||
"Ignore this test",
|
||||
attr.syntax().text_range(),
|
||||
|builder| builder.insert(attr.syntax().text_range().end(), &format!("\n#[ignore]")),
|
||||
)
|
||||
}
|
|
@ -141,6 +141,7 @@ mod handlers {
|
|||
mod generate_function;
|
||||
mod generate_impl;
|
||||
mod generate_new;
|
||||
mod ignore_test;
|
||||
mod infer_function_return_type;
|
||||
mod inline_local_variable;
|
||||
mod introduce_named_lifetime;
|
||||
|
@ -189,6 +190,7 @@ mod handlers {
|
|||
generate_function::generate_function,
|
||||
generate_impl::generate_impl,
|
||||
generate_new::generate_new,
|
||||
ignore_test::ignore_test,
|
||||
infer_function_return_type::infer_function_return_type,
|
||||
inline_local_variable::inline_local_variable,
|
||||
introduce_named_lifetime::introduce_named_lifetime,
|
||||
|
|
|
@ -473,6 +473,26 @@ impl<T: Clone> Ctx<T> {
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doctest_ignore_test() {
|
||||
check_doc_test(
|
||||
"ignore_test",
|
||||
r#####"
|
||||
<|>#[test]
|
||||
fn arithmetics {
|
||||
assert_eq!(2 + 2, 5);
|
||||
}
|
||||
"#####,
|
||||
r#####"
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn arithmetics {
|
||||
assert_eq!(2 + 2, 5);
|
||||
}
|
||||
"#####,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doctest_infer_function_return_type() {
|
||||
check_doc_test(
|
||||
|
|
|
@ -9,6 +9,7 @@ use ide_db::RootDatabase;
|
|||
use itertools::Itertools;
|
||||
use syntax::{
|
||||
ast::edit::AstNodeEdit,
|
||||
ast::AttrsOwner,
|
||||
ast::NameOwner,
|
||||
ast::{self, edit, make, ArgListOwner},
|
||||
AstNode, Direction,
|
||||
|
@ -82,6 +83,23 @@ pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> {
|
|||
None
|
||||
}
|
||||
|
||||
/// This is a method with a heuristics to support test methods annotated with custom test annotations, such as
|
||||
/// `#[test_case(...)]`, `#[tokio::test]` and similar.
|
||||
/// Also a regular `#[test]` annotation is supported.
|
||||
///
|
||||
/// It may produce false positives, for example, `#[wasm_bindgen_test]` requires a different command to run the test,
|
||||
/// but it's better than not to have the runnables for the tests at all.
|
||||
pub fn test_related_attribute(fn_def: &ast::Fn) -> Option<ast::Attr> {
|
||||
fn_def.attrs().find_map(|attr| {
|
||||
let path = attr.path()?;
|
||||
if path.syntax().text().to_string().contains("test") {
|
||||
Some(attr)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum DefaultMethods {
|
||||
Only,
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
//! This module implements a methods and free functions search in the specified file.
|
||||
//! We have to skip tests, so cannot reuse file_structure module.
|
||||
|
||||
use assists::utils::test_related_attribute;
|
||||
use hir::Semantics;
|
||||
use ide_db::RootDatabase;
|
||||
use syntax::{ast, ast::NameOwner, AstNode, SyntaxNode};
|
||||
|
||||
use crate::{runnables::has_test_related_attribute, FileId, FileRange};
|
||||
use crate::{FileId, FileRange};
|
||||
|
||||
pub(crate) fn find_all_methods(db: &RootDatabase, file_id: FileId) -> Vec<FileRange> {
|
||||
let sema = Semantics::new(db);
|
||||
|
@ -15,7 +16,7 @@ pub(crate) fn find_all_methods(db: &RootDatabase, file_id: FileId) -> Vec<FileRa
|
|||
|
||||
fn method_range(item: SyntaxNode, file_id: FileId) -> Option<FileRange> {
|
||||
ast::Fn::cast(item).and_then(|fn_def| {
|
||||
if has_test_related_attribute(&fn_def) {
|
||||
if test_related_attribute(&fn_def).is_some() {
|
||||
None
|
||||
} else {
|
||||
fn_def.name().map(|name| FileRange { file_id, range: name.syntax().text_range() })
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::fmt;
|
||||
|
||||
use assists::utils::test_related_attribute;
|
||||
use cfg::CfgExpr;
|
||||
use hir::{AsAssocItem, Attrs, HirFileId, InFile, Semantics};
|
||||
use ide_db::RootDatabase;
|
||||
|
@ -156,7 +157,7 @@ fn runnable_fn(
|
|||
None => TestId::Name(name_string),
|
||||
};
|
||||
|
||||
if has_test_related_attribute(&fn_def) {
|
||||
if test_related_attribute(&fn_def).is_some() {
|
||||
let attr = TestAttr::from_fn(&fn_def);
|
||||
RunnableKind::Test { test_id, attr }
|
||||
} else if fn_def.has_atom_attr("bench") {
|
||||
|
@ -235,20 +236,6 @@ impl TestAttr {
|
|||
}
|
||||
}
|
||||
|
||||
/// This is a method with a heuristics to support test methods annotated with custom test annotations, such as
|
||||
/// `#[test_case(...)]`, `#[tokio::test]` and similar.
|
||||
/// Also a regular `#[test]` annotation is supported.
|
||||
///
|
||||
/// It may produce false positives, for example, `#[wasm_bindgen_test]` requires a different command to run the test,
|
||||
/// but it's better than not to have the runnables for the tests at all.
|
||||
pub(crate) fn has_test_related_attribute(fn_def: &ast::Fn) -> bool {
|
||||
fn_def
|
||||
.attrs()
|
||||
.filter_map(|attr| attr.path())
|
||||
.map(|path| path.syntax().to_string().to_lowercase())
|
||||
.any(|attribute_text| attribute_text.contains("test"))
|
||||
}
|
||||
|
||||
const RUSTDOC_FENCE: &str = "```";
|
||||
const RUSTDOC_CODE_BLOCK_ATTRIBUTES_RUNNABLE: &[&str] =
|
||||
&["", "rust", "should_panic", "edition2015", "edition2018"];
|
||||
|
@ -307,7 +294,7 @@ fn has_test_function_or_multiple_test_submodules(module: &ast::Module) -> bool {
|
|||
for item in item_list.items() {
|
||||
match item {
|
||||
ast::Item::Fn(f) => {
|
||||
if has_test_related_attribute(&f) {
|
||||
if test_related_attribute(&f).is_some() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue