From 8471da62e64b3c143e2fea2ad4cf43732ff27c47 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 2 Mar 2021 16:38:51 +0300 Subject: Compress tests --- crates/ide_assists/src/tests.rs | 46 +- crates/ide_assists/src/utils/suggest_name.rs | 994 ++++++++++++--------------- 2 files changed, 424 insertions(+), 616 deletions(-) diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs index 66820058b..b7f616760 100644 --- a/crates/ide_assists/src/tests.rs +++ b/crates/ide_assists/src/tests.rs @@ -12,7 +12,7 @@ use ide_db::{ RootDatabase, }; use stdx::{format_to, trim_indent}; -use syntax::{ast, AstNode, TextRange}; +use syntax::TextRange; use test_utils::{assert_eq_text, extract_offset}; use crate::{handlers::Handler, Assist, AssistConfig, AssistContext, AssistKind, Assists}; @@ -180,50 +180,6 @@ fn labels(assists: &[Assist]) -> String { labels.into_iter().collect::() } -pub(crate) type NameSuggestion = fn(&ast::Expr, &Semantics<'_, RootDatabase>) -> Option; - -#[track_caller] -pub(crate) fn check_name_suggestion( - suggestion: NameSuggestion, - ra_fixture: &str, - suggested_name: &str, -) { - check_name(suggestion, ra_fixture, Some(suggested_name)); -} - -#[track_caller] -pub(crate) fn check_name_suggestion_not_applicable(suggestion: NameSuggestion, ra_fixture: &str) { - check_name(suggestion, ra_fixture, None); -} - -#[track_caller] -fn check_name(suggestion: NameSuggestion, ra_fixture: &str, expected: Option<&str>) { - let (db, file_with_carret_id, range_or_offset) = RootDatabase::with_range_or_offset(ra_fixture); - let frange = FileRange { file_id: file_with_carret_id, range: range_or_offset.into() }; - - let sema = Semantics::new(&db); - let source_file = sema.parse(frange.file_id); - let element = source_file.syntax().covering_element(frange.range); - let expr = - element.ancestors().find_map(ast::Expr::cast).expect("selection is not an expression"); - assert_eq!( - expr.syntax().text_range(), - frange.range, - "selection is not an expression(yet contained in one)" - ); - - let name = suggestion(&expr, &sema); - - match (name, expected) { - (Some(name), Some(expected_name)) => { - assert_eq_text!(&name, expected_name); - } - (Some(_), None) => panic!("name suggestion should not be applicable"), - (None, Some(_)) => panic!("name suggestion is not applicable"), - (None, None) => (), - } -} - #[test] fn assist_order_field_struct() { let before = "struct Foo { $0bar: u32 }"; diff --git a/crates/ide_assists/src/utils/suggest_name.rs b/crates/ide_assists/src/utils/suggest_name.rs index d37c62642..533624c1f 100644 --- a/crates/ide_assists/src/utils/suggest_name.rs +++ b/crates/ide_assists/src/utils/suggest_name.rs @@ -11,17 +11,20 @@ use syntax::{ /// Trait names, that will be ignored when in `impl Trait` and `dyn Trait` const USELESS_TRAITS: &[&str] = &["Send", "Sync", "Copy", "Clone", "Eq", "PartialEq"]; + /// Identifier names that won't be suggested, ever /// /// **NOTE**: they all must be snake lower case const USELESS_NAMES: &[&str] = &["new", "default", "option", "some", "none", "ok", "err", "str", "string"]; + /// Generic types replaced by their first argument /// /// # Examples /// `Option` -> `Name` /// `Result` -> `User` const WRAPPER_TYPES: &[&str] = &["Box", "Option", "Result"]; + /// Prefixes to strip from methods names /// /// # Examples @@ -29,6 +32,7 @@ const WRAPPER_TYPES: &[&str] = &["Box", "Option", "Result"]; /// `args.into_config()` -> `config` /// `bytes.to_vec()` -> `vec` const USELESS_METHOD_PREFIXES: &[&str] = &["into_", "as_", "to_"]; + /// Useless methods that are stripped from expression /// /// # Examples @@ -253,625 +257,473 @@ fn trait_name(trait_: &hir::Trait, db: &RootDatabase) -> Option { #[cfg(test)] mod tests { - use super::*; - - use crate::tests::check_name_suggestion; - - mod from_func_call { - use super::*; - - #[test] - fn no_args() { - check_name_suggestion( - |e, _| from_func_call(e), - r#" - fn foo() { - $0bar()$0 - }"#, - "bar", - ); - } + use ide_db::base_db::{fixture::WithFixture, FileRange}; - #[test] - fn single_arg() { - check_name_suggestion( - |e, _| from_func_call(e), - r#" - fn foo() { - $0bar(1)$0 - }"#, - "bar", - ); - } - - #[test] - fn many_args() { - check_name_suggestion( - |e, _| from_func_call(e), - r#" - fn foo() { - $0bar(1, 2, 3)$0 - }"#, - "bar", - ); - } - - #[test] - fn path() { - check_name_suggestion( - |e, _| from_func_call(e), - r#" - fn foo() { - $0i32::bar(1, 2, 3)$0 - }"#, - "bar", - ); - } + use super::*; - #[test] - fn generic_params() { - check_name_suggestion( - |e, _| from_func_call(e), - r#" - fn foo() { - $0bar::(1, 2, 3)$0 - }"#, - "bar", - ); - } + #[track_caller] + fn check(ra_fixture: &str, expected: &str) { + let (db, file_id, range_or_offset) = RootDatabase::with_range_or_offset(ra_fixture); + let frange = FileRange { file_id, range: range_or_offset.into() }; + + let sema = Semantics::new(&db); + let source_file = sema.parse(frange.file_id); + let element = source_file.syntax().covering_element(frange.range); + let expr = + element.ancestors().find_map(ast::Expr::cast).expect("selection is not an expression"); + assert_eq!( + expr.syntax().text_range(), + frange.range, + "selection is not an expression(yet contained in one)" + ); + let name = variable(&expr, &sema); + assert_eq!(&name, expected); } - mod from_method_call { - use super::*; - - #[test] - fn no_args() { - check_name_suggestion( - |e, _| from_method_call(e), - r#" - fn foo() { - $0bar.frobnicate()$0 - }"#, - "frobnicate", - ); - } - - #[test] - fn generic_params() { - check_name_suggestion( - |e, _| from_method_call(e), - r#" - fn foo() { - $0bar.frobnicate::()$0 - }"#, - "frobnicate", - ); - } - - #[test] - fn to_name() { - check_name_suggestion( - |e, _| from_method_call(e), - r#" - struct Args; - struct Config; - impl Args { - fn to_config(&self) -> Config {} - } - fn foo() { - $0Args.to_config()$0; - }"#, - "config", - ); - } + #[test] + fn no_args() { + check(r#"fn foo() { $0bar()$0 }"#, "bar"); + check(r#"fn foo() { $0bar.frobnicate()$0 }"#, "frobnicate"); } - mod from_param { - use crate::tests::check_name_suggestion_not_applicable; + #[test] + fn single_arg() { + check(r#"fn foo() { $0bar(1)$0 }"#, "bar"); + } - use super::*; + #[test] + fn many_args() { + check(r#"fn foo() { $0bar(1, 2, 3)$0 }"#, "bar"); + } - #[test] - fn plain_func() { - check_name_suggestion( - from_param, - r#" - fn bar(n: i32, m: u32); - fn foo() { - bar($01$0, 2) - }"#, - "n", - ); - } + #[test] + fn path() { + check(r#"fn foo() { $0i32::bar(1, 2, 3)$0 }"#, "bar"); + } - #[test] - fn mut_param() { - check_name_suggestion( - from_param, - r#" - fn bar(mut n: i32, m: u32); - fn foo() { - bar($01$0, 2) - }"#, - "n", - ); - } + #[test] + fn generic_params() { + check(r#"fn foo() { $0bar::(1, 2, 3)$0 }"#, "bar"); + check(r#"fn foo() { $0bar.frobnicate::()$0 }"#, "frobnicate"); + } - #[test] - fn func_does_not_exist() { - check_name_suggestion_not_applicable( - from_param, - r#" - fn foo() { - bar($01$0, 2) - }"#, - ); - } + #[test] + fn to_name() { + check( + r#" +struct Args; +struct Config; +impl Args { + fn to_config(&self) -> Config {} +} +fn foo() { + $0Args.to_config()$0; +} +"#, + "config", + ); + } - #[test] - fn unnamed_param() { - check_name_suggestion_not_applicable( - from_param, - r#" - fn bar(_: i32, m: u32); - fn foo() { - bar($01$0, 2) - }"#, - ); - } + #[test] + fn plain_func() { + check( + r#" +fn bar(n: i32, m: u32); +fn foo() { bar($01$0, 2) } +"#, + "n", + ); + } - #[test] - fn tuple_pat() { - check_name_suggestion_not_applicable( - from_param, - r#" - fn bar((n, k): (i32, i32), m: u32); - fn foo() { - bar($0(1, 2)$0, 3) - }"#, - ); - } + #[test] + fn mut_param() { + check( + r#" +fn bar(mut n: i32, m: u32); +fn foo() { bar($01$0, 2) } +"#, + "n", + ); + } - #[test] - fn ref_pat() { - check_name_suggestion( - from_param, - r#" - fn bar(&n: &i32, m: u32); - fn foo() { - bar($0&1$0, 3) - }"#, - "n", - ); - } + #[test] + fn func_does_not_exist() { + check(r#"fn foo() { bar($01$0, 2) }"#, "var_name"); + } - #[test] - fn box_pat() { - check_name_suggestion( - from_param, - r#" - fn bar(box n: &i32, m: u32); - fn foo() { - bar($01$0, 3) - }"#, - "n", - ); - } + #[test] + fn unnamed_param() { + check( + r#" +fn bar(_: i32, m: u32); +fn foo() { bar($01$0, 2) } +"#, + "var_name", + ); + } - #[test] - fn param_out_of_index() { - check_name_suggestion_not_applicable( - from_param, - r#" - fn bar(n: i32, m: u32); - fn foo() { - bar(1, 2, $03$0) - }"#, - ); - } + #[test] + fn tuple_pat() { + check( + r#" +fn bar((n, k): (i32, i32), m: u32); +fn foo() { + bar($0(1, 2)$0, 3) +} +"#, + "var_name", + ); + } - #[test] - fn generic_param_resolved() { - check_name_suggestion( - from_param, - r#" - fn bar(n: T, m: u32); - fn foo() { - bar($01$0, 2) - }"#, - "n", - ); - } + #[test] + fn ref_pat() { + check( + r#" +fn bar(&n: &i32, m: u32); +fn foo() { bar($0&1$0, 3) } +"#, + "n", + ); + } - #[test] - fn generic_param_unresolved() { - check_name_suggestion( - from_param, - r#" - fn bar(n: T, m: u32); - fn foo(x: T) { - bar($0x$0, 2) - }"#, - "n", - ); - } + #[test] + fn box_pat() { + check( + r#" +fn bar(box n: &i32, m: u32); +fn foo() { bar($01$0, 3) } +"#, + "n", + ); + } - #[test] - fn method() { - check_name_suggestion( - from_param, - r#" - struct S; - impl S { - fn bar(&self, n: i32, m: u32); - } - fn foo() { - S.bar($01$0, 2) - }"#, - "n", - ); - } + #[test] + fn param_out_of_index() { + check( + r#" +fn bar(n: i32, m: u32); +fn foo() { bar(1, 2, $03$0) } +"#, + "var_name", + ); + } - #[test] - fn method_ufcs() { - check_name_suggestion( - from_param, - r#" - struct S; - impl S { - fn bar(&self, n: i32, m: u32); - } - fn foo() { - S::bar(&S, $01$0, 2) - }"#, - "n", - ); - } + #[test] + fn generic_param_resolved() { + check( + r#" +fn bar(n: T, m: u32); +fn foo() { bar($01$0, 2) } +"#, + "n", + ); + } - #[test] - fn method_self() { - check_name_suggestion_not_applicable( - from_param, - r#" - struct S; - impl S { - fn bar(&self, n: i32, m: u32); - } - fn foo() { - S::bar($0&S$0, 1, 2) - }"#, - ); - } + #[test] + fn generic_param_unresolved() { + check( + r#" +fn bar(n: T, m: u32); +fn foo(x: T) { bar($0x$0, 2) } +"#, + "n", + ); + } - #[test] - fn method_self_named() { - check_name_suggestion( - from_param, - r#" - struct S; - impl S { - fn bar(strukt: &Self, n: i32, m: u32); - } - fn foo() { - S::bar($0&S$0, 1, 2) - }"#, - "strukt", - ); - } + #[test] + fn method() { + check( + r#" +struct S; +impl S { fn bar(&self, n: i32, m: u32); } +fn foo() { S.bar($01$0, 2) } +"#, + "n", + ); } - mod from_type { - use crate::tests::check_name_suggestion_not_applicable; + #[test] + fn method_ufcs() { + check( + r#" +struct S; +impl S { fn bar(&self, n: i32, m: u32); } +fn foo() { S::bar(&S, $01$0, 2) } +"#, + "n", + ); + } - use super::*; + #[test] + fn method_self() { + check( + r#" +struct S; +impl S { fn bar(&self, n: i32, m: u32); } +fn foo() { S::bar($0&S$0, 1, 2) } +"#, + "s", + ); + } - #[test] - fn i32() { - check_name_suggestion_not_applicable( - from_type, - r#" - fn foo() { - let _: i32 = $01$0; - }"#, - ); - } + #[test] + fn method_self_named() { + check( + r#" +struct S; +impl S { fn bar(strukt: &Self, n: i32, m: u32); } +fn foo() { S::bar($0&S$0, 1, 2) } +"#, + "strukt", + ); + } - #[test] - fn u64() { - check_name_suggestion_not_applicable( - from_type, - r#" - fn foo() { - let _: u64 = $01$0; - }"#, - ); - } + #[test] + fn i32() { + check(r#"fn foo() { let _: i32 = $01$0; }"#, "var_name"); + } - #[test] - fn bool() { - check_name_suggestion_not_applicable( - from_type, - r#" - fn foo() { - let _: bool = $0true$0; - }"#, - ); - } + #[test] + fn u64() { + check(r#"fn foo() { let _: u64 = $01$0; }"#, "var_name"); + } - #[test] - fn struct_unit() { - check_name_suggestion( - from_type, - r#" - struct Seed; - fn foo() { - let _ = $0Seed$0; - }"#, - "seed", - ); - } + #[test] + fn bool() { + check(r#"fn foo() { let _: bool = $0true$0; }"#, "var_name"); + } - #[test] - fn struct_unit_to_snake() { - check_name_suggestion( - from_type, - r#" - struct SeedState; - fn foo() { - let _ = $0SeedState$0; - }"#, - "seed_state", - ); - } + #[test] + fn struct_unit() { + check( + r#" +struct Seed; +fn foo() { let _ = $0Seed$0; } +"#, + "seed", + ); + } - #[test] - fn struct_single_arg() { - check_name_suggestion( - from_type, - r#" - struct Seed(u32); - fn foo() { - let _ = $0Seed(0)$0; - }"#, - "seed", - ); - } + #[test] + fn struct_unit_to_snake() { + check( + r#" +struct SeedState; +fn foo() { let _ = $0SeedState$0; } +"#, + "seed_state", + ); + } - #[test] - fn struct_with_fields() { - check_name_suggestion( - from_type, - r#" - struct Seed { value: u32 } - fn foo() { - let _ = $0Seed { value: 0 }$0; - }"#, - "seed", - ); - } + #[test] + fn struct_single_arg() { + check( + r#" +struct Seed(u32); +fn foo() { let _ = $0Seed(0)$0; } +"#, + "seed", + ); + } - #[test] - fn enum_() { - check_name_suggestion( - from_type, - r#" - enum Kind { A, B } - fn foo() { - let _ = $0Kind::A$0; - }"#, - "kind", - ); - } + #[test] + fn struct_with_fields() { + check( + r#" +struct Seed { value: u32 } +fn foo() { let _ = $0Seed { value: 0 }$0; } +"#, + "seed", + ); + } - #[test] - fn enum_generic_resolved() { - check_name_suggestion( - from_type, - r#" - enum Kind { A(T), B } - fn foo() { - let _ = $0Kind::A(1)$0; - }"#, - "kind", - ); - } + #[test] + fn enum_() { + check( + r#" +enum Kind { A, B } +fn foo() { let _ = $0Kind::A$0; } +"#, + "kind", + ); + } - #[test] - fn enum_generic_unresolved() { - check_name_suggestion( - from_type, - r#" - enum Kind { A(T), B } - fn foo(x: T) { - let _ = $0Kind::A(x)$0; - }"#, - "kind", - ); - } + #[test] + fn enum_generic_resolved() { + check( + r#" +enum Kind { A { x: T }, B } +fn foo() { let _ = $0Kind::A { x:1 }$0; } +"#, + "kind", + ); + } - #[test] - fn dyn_trait() { - check_name_suggestion( - from_type, - r#" - trait DynHandler {} - fn bar() -> dyn DynHandler {} - fn foo() { - $0bar()$0; - }"#, - "dyn_handler", - ); - } + #[test] + fn enum_generic_unresolved() { + check( + r#" +enum Kind { A { x: T }, B } +fn foo(x: T) { let _ = $0Kind::A { x }$0; } +"#, + "kind", + ); + } - #[test] - fn impl_trait() { - check_name_suggestion( - from_type, - r#" - trait StaticHandler {} - fn bar() -> impl StaticHandler {} - fn foo() { - $0bar()$0; - }"#, - "static_handler", - ); - } + #[test] + fn dyn_trait() { + check( + r#" +trait DynHandler {} +fn bar() -> dyn DynHandler {} +fn foo() { $0(bar())$0; } +"#, + "dyn_handler", + ); + } - #[test] - fn impl_trait_plus_clone() { - check_name_suggestion( - from_type, - r#" - trait StaticHandler {} - trait Clone {} - fn bar() -> impl StaticHandler + Clone {} - fn foo() { - $0bar()$0; - }"#, - "static_handler", - ); - } + #[test] + fn impl_trait() { + check( + r#" +trait StaticHandler {} +fn bar() -> impl StaticHandler {} +fn foo() { $0(bar())$0; } +"#, + "static_handler", + ); + } - #[test] - fn impl_trait_plus_lifetime() { - check_name_suggestion( - from_type, - r#" - trait StaticHandler {} - trait Clone {} - fn bar<'a>(&'a i32) -> impl StaticHandler + 'a {} - fn foo() { - $0bar(&1)$0; - }"#, - "static_handler", - ); - } + #[test] + fn impl_trait_plus_clone() { + check( + r#" +trait StaticHandler {} +trait Clone {} +fn bar() -> impl StaticHandler + Clone {} +fn foo() { $0(bar())$0; } +"#, + "static_handler", + ); + } - #[test] - fn impl_trait_plus_trait() { - check_name_suggestion_not_applicable( - from_type, - r#" - trait Handler {} - trait StaticHandler {} - fn bar() -> impl StaticHandler + Handler {} - fn foo() { - $0bar()$0; - }"#, - ); - } + #[test] + fn impl_trait_plus_lifetime() { + check( + r#" +trait StaticHandler {} +trait Clone {} +fn bar<'a>(&'a i32) -> impl StaticHandler + 'a {} +fn foo() { $0(bar(&1))$0; } +"#, + "static_handler", + ); + } - #[test] - fn ref_value() { - check_name_suggestion( - from_type, - r#" - struct Seed; - fn bar() -> &Seed {} - fn foo() { - $0bar()$0; - }"#, - "seed", - ); - } + #[test] + fn impl_trait_plus_trait() { + check( + r#" +trait Handler {} +trait StaticHandler {} +fn bar() -> impl StaticHandler + Handler {} +fn foo() { $0(bar())$0; } +"#, + "bar", + ); + } - #[test] - fn box_value() { - check_name_suggestion( - from_type, - r#" - struct Box(*const T); - struct Seed; - fn bar() -> Box {} - fn foo() { - $0bar()$0; - }"#, - "seed", - ); - } + #[test] + fn ref_value() { + check( + r#" +struct Seed; +fn bar() -> &Seed {} +fn foo() { $0(bar())$0; } +"#, + "seed", + ); + } - #[test] - fn box_generic() { - check_name_suggestion_not_applicable( - from_type, - r#" - struct Box(*const T); - fn bar() -> Box {} - fn foo() { - $0bar::()$0; - }"#, - ); - } + #[test] + fn box_value() { + check( + r#" +struct Box(*const T); +struct Seed; +fn bar() -> Box {} +fn foo() { $0(bar())$0; } +"#, + "seed", + ); + } - #[test] - fn option_value() { - check_name_suggestion( - from_type, - r#" - enum Option { Some(T) } - struct Seed; - fn bar() -> Option {} - fn foo() { - $0bar()$0; - }"#, - "seed", - ); - } + #[test] + fn box_generic() { + check( + r#" +struct Box(*const T); +fn bar() -> Box {} +fn foo() { $0(bar::())$0; } +"#, + "bar", + ); + } - #[test] - fn result_value() { - check_name_suggestion( - from_type, - r#" - enum Result { Ok(T), Err(E) } - struct Seed; - struct Error; - fn bar() -> Result {} - fn foo() { - $0bar()$0; - }"#, - "seed", - ); - } + #[test] + fn option_value() { + check( + r#" +enum Option { Some(T) } +struct Seed; +fn bar() -> Option {} +fn foo() { $0(bar())$0; } +"#, + "seed", + ); } - mod variable { - use super::*; + #[test] + fn result_value() { + check( + r#" +enum Result { Ok(T), Err(E) } +struct Seed; +struct Error; +fn bar() -> Result {} +fn foo() { $0(bar())$0; } +"#, + "seed", + ); + } - #[test] - fn ref_call() { - check_name_suggestion( - |e, c| Some(variable(e, c)), - r#" - fn foo() { - $0&bar(1, 3)$0 - }"#, - "bar", - ); - } + #[test] + fn ref_call() { + check( + r#" +fn foo() { $0&bar(1, 3)$0 } +"#, + "bar", + ); + } - #[test] - fn name_to_string() { - check_name_suggestion( - |e, c| Some(variable(e, c)), - r#" - fn foo() { - $0function.name().to_string()$0 - }"#, - "name", - ); - } + #[test] + fn name_to_string() { + check( + r#" +fn foo() { $0function.name().to_string()$0 } +"#, + "name", + ); + } - #[test] - fn nested_useless_method() { - check_name_suggestion( - |e, c| Some(variable(e, c)), - r#" - fn foo() { - $0function.name().as_ref().unwrap().to_string()$0 - }"#, - "name", - ); - } + #[test] + fn nested_useless_method() { + check( + r#" +fn foo() { $0function.name().as_ref().unwrap().to_string()$0 } +"#, + "name", + ); } } -- cgit v1.2.3