From 9a30707281d3a978741a549196b71a27284f7240 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 17 Nov 2020 14:22:04 +0100 Subject: Add **Ignore Test** assist --- crates/assists/src/handlers/ignore_test.rs | 34 ++++++++++++++++++++++++++++++ crates/assists/src/lib.rs | 2 ++ crates/assists/src/tests/generated.rs | 20 ++++++++++++++++++ crates/assists/src/utils.rs | 18 ++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 crates/assists/src/handlers/ignore_test.rs (limited to 'crates/assists') diff --git a/crates/assists/src/handlers/ignore_test.rs b/crates/assists/src/handlers/ignore_test.rs new file mode 100644 index 000000000..d2339184f --- /dev/null +++ b/crates/assists/src/handlers/ignore_test.rs @@ -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]")), + ) +} diff --git a/crates/assists/src/lib.rs b/crates/assists/src/lib.rs index e8d81b33d..17e9312db 100644 --- a/crates/assists/src/lib.rs +++ b/crates/assists/src/lib.rs @@ -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, diff --git a/crates/assists/src/tests/generated.rs b/crates/assists/src/tests/generated.rs index dbf4f21aa..5a9d1a01b 100644 --- a/crates/assists/src/tests/generated.rs +++ b/crates/assists/src/tests/generated.rs @@ -473,6 +473,26 @@ impl Ctx { ) } +#[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( diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index 7bd338e99..d1a0a99b1 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs @@ -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 { 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 { + 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, -- cgit v1.2.3