From abbb539f973ee4558f6ea7922794887962128987 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 9 Jul 2020 00:07:32 +0200 Subject: [PATCH] Refactor hover tests --- crates/ra_ide/src/hover.rs | 3233 ++++++++++++++++++------------------ 1 file changed, 1633 insertions(+), 1600 deletions(-) diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index 933e9b7148..a18c430030 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs @@ -10,7 +10,7 @@ use ra_ide_db::{ defs::{classify_name, classify_name_ref, Definition}, RootDatabase, }; -use ra_syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset}; +use ra_syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T}; use crate::{ display::{ @@ -360,7 +360,7 @@ fn pick_best(tokens: TokenAtOffset) -> Option { fn priority(n: &SyntaxToken) -> usize { match n.kind() { IDENT | INT_NUMBER => 3, - L_PAREN | R_PAREN => 2, + T!['('] | T![')'] => 2, kind if kind.is_trivia() => 0, _ => 1, } @@ -369,44 +369,38 @@ fn pick_best(tokens: TokenAtOffset) -> Option { #[cfg(test)] mod tests { - use super::*; - use insta::assert_debug_snapshot; - + use expect::{expect, Expect}; use ra_db::FileLoader; - use ra_syntax::TextRange; use crate::mock_analysis::analysis_and_position; - fn trim_markup(s: &str) -> &str { - s.trim_start_matches("```rust\n").trim_end_matches("\n```") - } - - fn assert_impl_action(action: &HoverAction, position: u32) { - let offset = match action { - HoverAction::Implementaion(pos) => pos.offset, - it => panic!("Unexpected hover action: {:#?}", it), - }; - assert_eq!(offset, position.into()); - } - - fn check_hover_result(ra_fixture: &str, expected: &str) -> (String, Vec) { - let (analysis, position) = analysis_and_position(ra_fixture); - let hover = analysis.hover(position).unwrap().unwrap(); - let actual = trim_markup(hover.info.markup.as_str()); - assert_eq!(expected, actual); - - let content = analysis.db.file_text(position.file_id); - (content[hover.range].to_string(), hover.info.actions.clone()) - } + use super::*; fn check_hover_no_result(ra_fixture: &str) { let (analysis, position) = analysis_and_position(ra_fixture); assert!(analysis.hover(position).unwrap().is_none()); } + fn check(ra_fixture: &str, expect: Expect) { + let (analysis, position) = analysis_and_position(ra_fixture); + let hover = analysis.hover(position).unwrap().unwrap(); + + let content = analysis.db.file_text(position.file_id); + let hovered_element = &content[hover.range]; + + let actual = format!("{}:\n{}\n", hovered_element, hover.info.markup); + expect.assert_eq(&actual) + } + + fn check_actions(ra_fixture: &str, expect: Expect) { + let (analysis, position) = analysis_and_position(ra_fixture); + let hover = analysis.hover(position).unwrap().unwrap(); + expect.assert_debug_eq(&hover.info.actions) + } + #[test] fn hover_shows_type_of_an_expression() { - let (analysis, position) = analysis_and_position( + check( r#" pub fn foo() -> u32 { 1 } @@ -414,600 +408,643 @@ fn main() { let foo_test = foo()<|>; } "#, + expect![[r#" + foo(): + ```rust + u32 + ``` + "#]], ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(hover.range, TextRange::new(58.into(), 63.into())); - assert_eq!(trim_markup(&hover.info.markup.as_str()), ("u32")); } #[test] fn hover_shows_long_type_of_an_expression() { - check_hover_result(r#" - //- /main.rs - struct Scan { - a: A, - b: B, - c: C, - } + check( + r#" +struct Scan { a: A, b: B, c: C } +struct Iter { inner: I } +enum Option { Some(T), None } - struct FakeIter { - inner: I, - } +struct OtherStruct { i: T } - struct OtherStruct { - i: T, - } +fn scan(a: A, b: B, c: C) -> Iter, B, C>> { + Iter { inner: Scan { a, b, c } } +} - enum FakeOption { - Some(T), - None, - } - - fn scan(a: A, b: B, c: C) -> FakeIter, B, C>> { - FakeIter { inner: Scan { a, b, c } } - } - - fn main() { - let num: i32 = 55; - let closure = |memo: &mut u32, value: &u32, _another: &mut u32| -> FakeOption { - FakeOption::Some(*memo + value) - }; - let number = 5u32; - let mut iter<|> = scan(OtherStruct { i: num }, closure, number); - } - "#, "FakeIter>, |&mut u32, &u32, &mut u32| -> FakeOption, u32>>"); +fn main() { + let num: i32 = 55; + let closure = |memo: &mut u32, value: &u32, _another: &mut u32| -> Option { + Option::Some(*memo + value) + }; + let number = 5u32; + let mut iter<|> = scan(OtherStruct { i: num }, closure, number); +} +"#, + expect![[r#" + iter: + ```rust + Iter>, |&mut u32, &u32, &mut u32| -> Option, u32>> + ``` + "#]], + ); } #[test] fn hover_shows_fn_signature() { // Single file with result - check_hover_result( + check( r#" - //- /main.rs - pub fn foo() -> u32 { 1 } +pub fn foo() -> u32 { 1 } - fn main() { - let foo_test = fo<|>o(); - } - "#, - "pub fn foo() -> u32", +fn main() { let foo_test = fo<|>o(); } +"#, + expect![[r#" + foo: + ```rust + pub fn foo() -> u32 + ``` + "#]], ); // Multiple candidates but results are ambiguous. - check_hover_result( + check( r#" - //- /a.rs - pub fn foo() -> u32 { 1 } +//- /a.rs +pub fn foo() -> u32 { 1 } - //- /b.rs - pub fn foo() -> &str { "" } +//- /b.rs +pub fn foo() -> &str { "" } - //- /c.rs - pub fn foo(a: u32, b: u32) {} +//- /c.rs +pub fn foo(a: u32, b: u32) {} - //- /main.rs - mod a; - mod b; - mod c; +//- /main.rs +mod a; +mod b; +mod c; - fn main() { - let foo_test = fo<|>o(); - } +fn main() { let foo_test = fo<|>o(); } "#, - "{unknown}", + expect![[r#" + foo: + ```rust + {unknown} + ``` + "#]], ); } #[test] fn hover_shows_fn_signature_with_type_params() { - check_hover_result( + check( r#" - //- /main.rs - pub fn foo<'a, T: AsRef>(b: &'a T) -> &'a str { } +pub fn foo<'a, T: AsRef>(b: &'a T) -> &'a str { } - fn main() { - let foo_test = fo<|>o(); - } +fn main() { let foo_test = fo<|>o(); } "#, - "pub fn foo<'a, T: AsRef>(b: &'a T) -> &'a str", + expect![[r#" + foo: + ```rust + pub fn foo<'a, T: AsRef>(b: &'a T) -> &'a str + ``` + "#]], ); } #[test] fn hover_shows_fn_signature_on_fn_name() { - check_hover_result( + check( r#" - //- /main.rs - pub fn foo<|>(a: u32, b: u32) -> u32 {} +pub fn foo<|>(a: u32, b: u32) -> u32 {} - fn main() { - } - "#, - "pub fn foo(a: u32, b: u32) -> u32", +fn main() { } +"#, + expect![[r#" + foo: + ```rust + pub fn foo(a: u32, b: u32) -> u32 + ``` + "#]], ); } #[test] fn hover_shows_struct_field_info() { // Hovering over the field when instantiating - check_hover_result( + check( r#" - //- /main.rs - struct Foo { - field_a: u32, - } +struct Foo { field_a: u32 } - fn main() { - let foo = Foo { - field_a<|>: 0, - }; - } - "#, - "Foo\n```\n\n```rust\nfield_a: u32", +fn main() { + let foo = Foo { field_a<|>: 0, }; +} +"#, + expect![[r#" + field_a: + ```rust + Foo + ``` + + ```rust + field_a: u32 + ``` + "#]], ); // Hovering over the field in the definition - check_hover_result( + check( r#" - //- /main.rs - struct Foo { - field_a<|>: u32, - } +struct Foo { field_a<|>: u32 } - fn main() { - let foo = Foo { - field_a: 0, - }; - } - "#, - "Foo\n```\n\n```rust\nfield_a: u32", +fn main() { + let foo = Foo { field_a: 0 }; +} +"#, + expect![[r#" + field_a: + ```rust + Foo + ``` + + ```rust + field_a: u32 + ``` + "#]], ); } #[test] fn hover_const_static() { - check_hover_result( - r#" - //- /main.rs - const foo<|>: u32 = 0; - "#, - "const foo: u32", + check( + r#"const foo<|>: u32 = 0;"#, + expect![[r#" + foo: + ```rust + const foo: u32 + ``` + "#]], ); - - check_hover_result( - r#" - //- /main.rs - static foo<|>: u32 = 0; - "#, - "static foo: u32", + check( + r#"static foo<|>: u32 = 0;"#, + expect![[r#" + foo: + ```rust + static foo: u32 + ``` + "#]], ); } #[test] fn hover_default_generic_types() { - check_hover_result( + check( r#" -//- /main.rs -struct Test { - k: K, - t: T, -} +struct Test { k: K, t: T } fn main() { let zz<|> = Test { t: 23u8, k: 33 }; }"#, - "Test", + expect![[r#" + zz: + ```rust + Test + ``` + "#]], ); } #[test] fn hover_some() { - let (analysis, position) = analysis_and_position( - " - enum Option { Some(T) } - use Option::Some; + check( + r#" +enum Option { Some(T) } +use Option::Some; - fn main() { - So<|>me(12); - } - ", +fn main() { So<|>me(12); } +"#, + expect![[r#" + Some: + ```rust + Option + ``` + + ```rust + Some + ``` + "#]], ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), ("Option\n```\n\n```rust\nSome")); - let (analysis, position) = analysis_and_position( - " - enum Option { Some(T) } - use Option::Some; + check( + r#" +enum Option { Some(T) } +use Option::Some; - fn main() { - let b<|>ar = Some(12); - } - ", +fn main() { let b<|>ar = Some(12); } +"#, + expect![[r#" + bar: + ```rust + Option + ``` + "#]], ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), ("Option")); } #[test] fn hover_enum_variant() { - check_hover_result( + check( r#" - //- /main.rs - enum Option { - /// The None variant - Non<|>e - } - "#, - " -Option -``` +enum Option { + /// The None variant + Non<|>e +} +"#, + expect![[r#" + None: + ```rust + Option + ``` -```rust -None -``` -___ + ```rust + None + ``` + ___ -The None variant - " - .trim(), + The None variant + "#]], ); - check_hover_result( + check( r#" - //- /main.rs - enum Option { - /// The Some variant - Some(T) - } - fn main() { - let s = Option::Som<|>e(12); - } - "#, - " -Option -``` +enum Option { + /// The Some variant + Some(T) +} +fn main() { + let s = Option::Som<|>e(12); +} +"#, + expect![[r#" + Some: + ```rust + Option + ``` -```rust -Some -``` -___ + ```rust + Some + ``` + ___ -The Some variant - " - .trim(), + The Some variant + "#]], ); } #[test] fn hover_for_local_variable() { - let (analysis, position) = analysis_and_position("fn func(foo: i32) { fo<|>o; }"); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), "i32"); + check( + r#"fn func(foo: i32) { fo<|>o; }"#, + expect![[r#" + foo: + ```rust + i32 + ``` + "#]], + ) } #[test] fn hover_for_local_variable_pat() { - let (analysis, position) = analysis_and_position("fn func(fo<|>o: i32) {}"); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), "i32"); + check( + r#"fn func(fo<|>o: i32) {}"#, + expect![[r#" + foo: + ```rust + i32 + ``` + "#]], + ) } #[test] fn hover_local_var_edge() { - let (analysis, position) = analysis_and_position( - " -fn func(foo: i32) { if true { <|>foo; }; } -", - ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), "i32"); + check( + r#"fn func(foo: i32) { if true { <|>foo; }; }"#, + expect![[r#" + foo: + ```rust + i32 + ``` + "#]], + ) } #[test] fn hover_for_param_edge() { - let (analysis, position) = analysis_and_position("fn func(<|>foo: i32) {}"); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), "i32"); + check( + r#"fn func(<|>foo: i32) {}"#, + expect![[r#" + foo: + ```rust + i32 + ``` + "#]], + ) } #[test] fn test_hover_infer_associated_method_result() { - let (analysis, position) = analysis_and_position( - " - struct Thing { x: u32 } + check( + r#" +struct Thing { x: u32 } - impl Thing { - fn new() -> Thing { - Thing { x: 0 } - } - } +impl Thing { + fn new() -> Thing { Thing { x: 0 } } +} - fn main() { - let foo_<|>test = Thing::new(); - } - ", - ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), ("Thing")); +fn main() { let foo_<|>test = Thing::new(); } + "#, + expect![[r#" + foo_test: + ```rust + Thing + ``` + "#]], + ) } #[test] fn test_hover_infer_associated_method_exact() { - let (analysis, position) = analysis_and_position( - " - mod wrapper { - struct Thing { x: u32 } + check( + r#" +mod wrapper { + struct Thing { x: u32 } - impl Thing { - fn new() -> Thing { - Thing { x: 0 } - } - } - } + impl Thing { + fn new() -> Thing { Thing { x: 0 } } + } +} - fn main() { - let foo_test = wrapper::Thing::new<|>(); - } - ", - ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!( - trim_markup(&hover.info.markup.as_str()), - ("wrapper::Thing\n```\n\n```rust\nfn new() -> Thing") - ); +fn main() { let foo_test = wrapper::Thing::new<|>(); } +"#, + expect![[r#" + new: + ```rust + wrapper::Thing + ``` + + ```rust + fn new() -> Thing + ``` + "#]], + ) } #[test] fn test_hover_infer_associated_const_in_pattern() { - let (analysis, position) = analysis_and_position( - " - struct X; - impl X { - const C: u32 = 1; - } + check( + r#" +struct X; +impl X { + const C: u32 = 1; +} - fn main() { - match 1 { - X::C<|> => {}, - 2 => {}, - _ => {} - }; - } - ", - ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), ("const C: u32")); +fn main() { + match 1 { + X::C<|> => {}, + 2 => {}, + _ => {} + }; +} +"#, + expect![[r#" + C: + ```rust + const C: u32 + ``` + "#]], + ) } #[test] fn test_hover_self() { - let (analysis, position) = analysis_and_position( - " - struct Thing { x: u32 } - impl Thing { - fn new() -> Self { - Self<|> { x: 0 } - } - } - ", - ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), ("Thing")); + check( + r#" +struct Thing { x: u32 } +impl Thing { + fn new() -> Self { Self<|> { x: 0 } } +} +"#, + expect![[r#" + Self { x: 0 }: + ```rust + Thing + ``` + "#]], + ) + } /* FIXME: revive these tests + let (analysis, position) = analysis_and_position( + " + struct Thing { x: u32 } + impl Thing { + fn new() -> Self<|> { + Self { x: 0 } + } + } + ", + ); - /* FIXME: revive these tests - let (analysis, position) = analysis_and_position( - " - struct Thing { x: u32 } - impl Thing { - fn new() -> Self<|> { - Self { x: 0 } - } - } - ", - ); + let hover = analysis.hover(position).unwrap().unwrap(); + assert_eq!(trim_markup(&hover.info.markup.as_str()), ("Thing")); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), ("Thing")); + let (analysis, position) = analysis_and_position( + " + enum Thing { A } + impl Thing { + pub fn new() -> Self<|> { + Thing::A + } + } + ", + ); + let hover = analysis.hover(position).unwrap().unwrap(); + assert_eq!(trim_markup(&hover.info.markup.as_str()), ("enum Thing")); - let (analysis, position) = analysis_and_position( - " - enum Thing { A } - impl Thing { - pub fn new() -> Self<|> { - Thing::A - } - } - ", - ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), ("enum Thing")); - - let (analysis, position) = analysis_and_position( - " - enum Thing { A } - impl Thing { - pub fn thing(a: Self<|>) { - } - } - ", - ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), ("enum Thing")); - */ - } + let (analysis, position) = analysis_and_position( + " + enum Thing { A } + impl Thing { + pub fn thing(a: Self<|>) { + } + } + ", + ); + let hover = analysis.hover(position).unwrap().unwrap(); + assert_eq!(trim_markup(&hover.info.markup.as_str()), ("enum Thing")); + */ #[test] fn test_hover_shadowing_pat() { - let (analysis, position) = analysis_and_position( - " - fn x() {} + check( + r#" +fn x() {} - fn y() { - let x = 0i32; - x<|>; - } - ", - ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), "i32"); +fn y() { + let x = 0i32; + x<|>; +} +"#, + expect![[r#" + x: + ```rust + i32 + ``` + "#]], + ) } #[test] fn test_hover_macro_invocation() { - let (analysis, position) = analysis_and_position( - " - macro_rules! foo { - () => {} - } + check( + r#" +macro_rules! foo { () => {} } - fn f() { - fo<|>o!(); - } - ", - ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), ("macro_rules! foo")); +fn f() { fo<|>o!(); } +"#, + expect![[r#" + foo: + ```rust + macro_rules! foo + ``` + "#]], + ) } #[test] fn test_hover_tuple_field() { - let (analysis, position) = analysis_and_position( - " - struct TS(String, i32<|>); - ", - ); - let hover = analysis.hover(position).unwrap().unwrap(); - assert_eq!(trim_markup(&hover.info.markup.as_str()), "i32"); + check( + r#"struct TS(String, i32<|>);"#, + expect![[r#" + i32: + i32 + "#]], + ) } #[test] fn test_hover_through_macro() { - let (hover_on, _) = check_hover_result( - r" - //- /lib.rs - macro_rules! id { - ($($tt:tt)*) => { $($tt)* } - } - fn foo() {} - id! { - fn bar() { - fo<|>o(); - } - } - ", - "fn foo()", + check( + r#" +macro_rules! id { ($($tt:tt)*) => { $($tt)* } } +fn foo() {} +id! { + fn bar() { fo<|>o(); } +} +"#, + expect![[r#" + foo: + ```rust + fn foo() + ``` + "#]], ); - - assert_eq!(hover_on, "foo") } #[test] fn test_hover_through_expr_in_macro() { - let (hover_on, _) = check_hover_result( - r" - //- /lib.rs - macro_rules! id { - ($($tt:tt)*) => { $($tt)* } - } - fn foo(bar:u32) { - let a = id!(ba<|>r); - } - ", - "u32", + check( + r#" +macro_rules! id { ($($tt:tt)*) => { $($tt)* } } +fn foo(bar:u32) { let a = id!(ba<|>r); } +"#, + expect![[r#" + bar: + ```rust + u32 + ``` + "#]], ); - - assert_eq!(hover_on, "bar") } #[test] fn test_hover_through_expr_in_macro_recursive() { - let (hover_on, _) = check_hover_result( - r" - //- /lib.rs - macro_rules! id_deep { - ($($tt:tt)*) => { $($tt)* } - } - macro_rules! id { - ($($tt:tt)*) => { id_deep!($($tt)*) } - } - fn foo(bar:u32) { - let a = id!(ba<|>r); - } - ", - "u32", + check( + r#" +macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } } +macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } } +fn foo(bar:u32) { let a = id!(ba<|>r); } +"#, + expect![[r#" + bar: + ```rust + u32 + ``` + "#]], ); - - assert_eq!(hover_on, "bar") } #[test] fn test_hover_through_func_in_macro_recursive() { - let (hover_on, _) = check_hover_result( - r" - //- /lib.rs - macro_rules! id_deep { - ($($tt:tt)*) => { $($tt)* } - } - macro_rules! id { - ($($tt:tt)*) => { id_deep!($($tt)*) } - } - fn bar() -> u32 { - 0 - } - fn foo() { - let a = id!([0u32, bar(<|>)] ); - } - ", - "u32", + check( + r#" +macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } } +macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } } +fn bar() -> u32 { 0 } +fn foo() { let a = id!([0u32, bar(<|>)] ); } +"#, + expect![[r#" + bar(): + ```rust + u32 + ``` + "#]], ); - - assert_eq!(hover_on, "bar()") } #[test] fn test_hover_through_literal_string_in_macro() { - let (hover_on, _) = check_hover_result( + check( r#" - //- /lib.rs - macro_rules! arr { - ($($tt:tt)*) => { [$($tt)*)] } - } - fn foo() { - let mastered_for_itunes = ""; - let _ = arr!("Tr<|>acks", &mastered_for_itunes); - } - "#, - "&str", +macro_rules! arr { ($($tt:tt)*) => { [$($tt)*)] } } +fn foo() { + let mastered_for_itunes = ""; + let _ = arr!("Tr<|>acks", &mastered_for_itunes); +} +"#, + expect![[r#" + "Tracks": + ```rust + &str + ``` + "#]], ); - - assert_eq!(hover_on, "\"Tracks\""); } #[test] fn test_hover_through_assert_macro() { - let (hover_on, _) = check_hover_result( - r" - //- /lib.rs - #[rustc_builtin_macro] - macro_rules! assert {} + check( + r#" +#[rustc_builtin_macro] +macro_rules! assert {} - fn bar() -> bool { true } - fn foo() { - assert!(ba<|>r()); - } - ", - "fn bar() -> bool", +fn bar() -> bool { true } +fn foo() { + assert!(ba<|>r()); +} +"#, + expect![[r#" + bar: + ```rust + fn bar() -> bool + ``` + "#]], ); - - assert_eq!(hover_on, "bar"); } #[test] fn test_hover_through_literal_string_in_builtin_macro() { check_hover_no_result( r#" - //- /lib.rs #[rustc_builtin_macro] macro_rules! format {} @@ -1020,122 +1057,159 @@ fn func(foo: i32) { if true { <|>foo; }; } #[test] fn test_hover_non_ascii_space_doc() { - check_hover_result( + check( " - //- /lib.rs - /// <- `\u{3000}` here - fn foo() { - } +/// <- `\u{3000}` here +fn foo() { } - fn bar() { - fo<|>o(); - } - ", - "fn foo()\n```\n___\n\n<- `\u{3000}` here", +fn bar() { fo<|>o(); } +", + expect![[r#" + foo: + ```rust + fn foo() + ``` + ___ + + <- ` ` here + "#]], ); } #[test] fn test_hover_function_show_qualifiers() { - check_hover_result( - r" - //- /lib.rs - async fn foo<|>() {} - ", - "async fn foo()", + check( + r#"async fn foo<|>() {}"#, + expect![[r#" + foo: + ```rust + async fn foo() + ``` + "#]], ); - check_hover_result( - r" - //- /lib.rs - pub const unsafe fn foo<|>() {} - ", - "pub const unsafe fn foo()", + check( + r#"pub const unsafe fn foo<|>() {}"#, + expect![[r#" + foo: + ```rust + pub const unsafe fn foo() + ``` + "#]], ); - check_hover_result( - r#" - //- /lib.rs - pub(crate) async unsafe extern "C" fn foo<|>() {} - "#, - r#"pub(crate) async unsafe extern "C" fn foo()"#, + check( + r#"pub(crate) async unsafe extern "C" fn foo<|>() {}"#, + expect![[r#" + foo: + ```rust + pub(crate) async unsafe extern "C" fn foo() + ``` + "#]], ); } #[test] fn test_hover_trait_show_qualifiers() { - let (_, actions) = check_hover_result( - r" - //- /lib.rs - unsafe trait foo<|>() {} - ", - "unsafe trait foo", + check_actions( + r"unsafe trait foo<|>() {}", + expect![[r#" + [ + Implementaion( + FilePosition { + file_id: FileId( + 1, + ), + offset: 13, + }, + ), + ] + "#]], ); - assert_impl_action(&actions[0], 13); } #[test] fn test_hover_mod_with_same_name_as_function() { - check_hover_result( - r" - //- /lib.rs - use self::m<|>y::Bar; + check( + r#" +use self::m<|>y::Bar; +mod my { pub struct Bar; } - mod my { - pub struct Bar; - } - - fn my() {} - ", - "mod my", +fn my() {} +"#, + expect![[r#" + my: + ```rust + mod my + ``` + "#]], ); } #[test] fn test_hover_struct_doc_comment() { - check_hover_result( + check( r#" - //- /lib.rs - /// bar docs - struct Bar; +/// bar docs +struct Bar; - fn foo() { - let bar = Ba<|>r; - } - "#, - "struct Bar\n```\n___\n\nbar docs", +fn foo() { let bar = Ba<|>r; } +"#, + expect![[r#" + Bar: + ```rust + struct Bar + ``` + ___ + + bar docs + "#]], ); } #[test] fn test_hover_struct_doc_attr() { - check_hover_result( + check( r#" - //- /lib.rs - #[doc = "bar docs"] - struct Bar; +#[doc = "bar docs"] +struct Bar; - fn foo() { - let bar = Ba<|>r; - } - "#, - "struct Bar\n```\n___\n\nbar docs", +fn foo() { let bar = Ba<|>r; } +"#, + expect![[r#" + Bar: + ```rust + struct Bar + ``` + ___ + + bar docs + "#]], ); } #[test] fn test_hover_struct_doc_attr_multiple_and_mixed() { - check_hover_result( + check( r#" - //- /lib.rs - /// bar docs 0 - #[doc = "bar docs 1"] - #[doc = "bar docs 2"] - struct Bar; +/// bar docs 0 +#[doc = "bar docs 1"] +#[doc = "bar docs 2"] +struct Bar; - fn foo() { - let bar = Ba<|>r; - } - "#, - "struct Bar\n```\n___\n\nbar docs 0\n\nbar docs 1\n\nbar docs 2", +fn foo() { let bar = Ba<|>r; } +"#, + expect![[r#" + Bar: + ```rust + struct Bar + ``` + ___ + + bar docs 0 + + bar docs 1 + + bar docs 2 + "#]], ); } @@ -1143,27 +1217,35 @@ fn func(foo: i32) { if true { <|>foo; }; } fn test_hover_macro_generated_struct_fn_doc_comment() { mark::check!(hover_macro_generated_struct_fn_doc_comment); - check_hover_result( + check( r#" - //- /lib.rs - macro_rules! bar { - () => { - struct Bar; - impl Bar { - /// Do the foo - fn foo(&self) {} - } - } - } +macro_rules! bar { + () => { + struct Bar; + impl Bar { + /// Do the foo + fn foo(&self) {} + } + } +} - bar!(); +bar!(); - fn foo() { - let bar = Bar; - bar.fo<|>o(); - } - "#, - "Bar\n```\n\n```rust\nfn foo(&self)\n```\n___\n\n Do the foo", +fn foo() { let bar = Bar; bar.fo<|>o(); } +"#, + expect![[r#" + foo: + ```rust + Bar + ``` + + ```rust + fn foo(&self) + ``` + ___ + + Do the foo + "#]], ); } @@ -1171,1204 +1253,1155 @@ fn func(foo: i32) { if true { <|>foo; }; } fn test_hover_macro_generated_struct_fn_doc_attr() { mark::check!(hover_macro_generated_struct_fn_doc_attr); - check_hover_result( + check( r#" - //- /lib.rs - macro_rules! bar { - () => { - struct Bar; - impl Bar { - #[doc = "Do the foo"] - fn foo(&self) {} - } - } - } +macro_rules! bar { + () => { + struct Bar; + impl Bar { + #[doc = "Do the foo"] + fn foo(&self) {} + } + } +} - bar!(); +bar!(); - fn foo() { - let bar = Bar; - bar.fo<|>o(); - } - "#, - "Bar\n```\n\n```rust\nfn foo(&self)\n```\n___\n\nDo the foo", +fn foo() { let bar = Bar; bar.fo<|>o(); } +"#, + expect![[r#" + foo: + ```rust + Bar + ``` + + ```rust + fn foo(&self) + ``` + ___ + + Do the foo + "#]], ); } #[test] fn test_hover_trait_has_impl_action() { - let (_, actions) = check_hover_result( - r" - //- /lib.rs - trait foo<|>() {} - ", - "trait foo", + check_actions( + r#"trait foo<|>() {}"#, + expect![[r#" + [ + Implementaion( + FilePosition { + file_id: FileId( + 1, + ), + offset: 6, + }, + ), + ] + "#]], ); - assert_impl_action(&actions[0], 6); } #[test] fn test_hover_struct_has_impl_action() { - let (_, actions) = check_hover_result( - r" - //- /lib.rs - struct foo<|>() {} - ", - "struct foo", + check_actions( + r"struct foo<|>() {}", + expect![[r#" + [ + Implementaion( + FilePosition { + file_id: FileId( + 1, + ), + offset: 7, + }, + ), + ] + "#]], ); - assert_impl_action(&actions[0], 7); } #[test] fn test_hover_union_has_impl_action() { - let (_, actions) = check_hover_result( - r" - //- /lib.rs - union foo<|>() {} - ", - "union foo", + check_actions( + r#"union foo<|>() {}"#, + expect![[r#" + [ + Implementaion( + FilePosition { + file_id: FileId( + 1, + ), + offset: 6, + }, + ), + ] + "#]], ); - assert_impl_action(&actions[0], 6); } #[test] fn test_hover_enum_has_impl_action() { - let (_, actions) = check_hover_result( - r" - //- /lib.rs - enum foo<|>() { - A, - B - } - ", - "enum foo", + check_actions( + r"enum foo<|>() { A, B }", + expect![[r#" + [ + Implementaion( + FilePosition { + file_id: FileId( + 1, + ), + offset: 5, + }, + ), + ] + "#]], ); - assert_impl_action(&actions[0], 5); } #[test] fn test_hover_test_has_action() { - let (_, actions) = check_hover_result( - r" - //- /lib.rs - #[test] - fn foo_<|>test() {} - ", - "fn foo_test()", - ); - assert_debug_snapshot!(actions, - @r###" - [ - Runnable( - Runnable { - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..24, - name: "foo_test", - kind: FN_DEF, - focus_range: Some( - 11..19, - ), - container_name: None, - description: None, - docs: None, - }, - kind: Test { - test_id: Path( - "foo_test", - ), - attr: TestAttr { - ignore: false, + check_actions( + r#" +#[test] +fn foo_<|>test() {} +"#, + expect![[r#" + [ + Runnable( + Runnable { + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..24, + name: "foo_test", + kind: FN_DEF, + focus_range: Some( + 11..19, + ), + container_name: None, + description: None, + docs: None, }, + kind: Test { + test_id: Path( + "foo_test", + ), + attr: TestAttr { + ignore: false, + }, + }, + cfg_exprs: [], }, - cfg_exprs: [], - }, - ), - ] - "###); + ), + ] + "#]], + ); } #[test] fn test_hover_test_mod_has_action() { - let (_, actions) = check_hover_result( - r" - //- /lib.rs - mod tests<|> { - #[test] - fn foo_test() {} - } - ", - "mod tests", + check_actions( + r#" +mod tests<|> { + #[test] + fn foo_test() {} +} +"#, + expect![[r#" + [ + Runnable( + Runnable { + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..46, + name: "tests", + kind: MODULE, + focus_range: Some( + 4..9, + ), + container_name: None, + description: None, + docs: None, + }, + kind: TestMod { + path: "tests", + }, + cfg_exprs: [], + }, + ), + ] + "#]], ); - assert_debug_snapshot!(actions, - @r###" - [ - Runnable( - Runnable { - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..46, - name: "tests", - kind: MODULE, - focus_range: Some( - 4..9, - ), - container_name: None, - description: None, - docs: None, - }, - kind: TestMod { - path: "tests", - }, - cfg_exprs: [], - }, - ), - ] - "###); } #[test] fn test_hover_struct_has_goto_type_action() { - let (_, actions) = check_hover_result( - r" - //- /main.rs - struct S{ f1: u32 } + check_actions( + r#" +struct S{ f1: u32 } - fn main() { - let s<|>t = S{ f1:0 }; - } - ", - "S", - ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "S", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..19, - name: "S", - kind: STRUCT_DEF, - focus_range: Some( - 7..8, - ), - container_name: None, - description: Some( - "struct S", - ), - docs: None, +fn main() { let s<|>t = S{ f1:0 }; } + "#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "S", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..19, + name: "S", + kind: STRUCT_DEF, + focus_range: Some( + 7..8, + ), + container_name: None, + description: Some( + "struct S", + ), + docs: None, + }, }, - }, - ], - ), - ] - "###); + ], + ), + ] + "#]], + ); } #[test] fn test_hover_generic_struct_has_goto_type_actions() { - let (_, actions) = check_hover_result( - r" - //- /main.rs - struct Arg(u32); - struct S{ f1: T } + check_actions( + r#" +struct Arg(u32); +struct S{ f1: T } - fn main() { - let s<|>t = S{ f1:Arg(0) }; - } - ", - "S", +fn main() { let s<|>t = S{ f1:Arg(0) }; } +"#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "S", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 17..37, + name: "S", + kind: STRUCT_DEF, + focus_range: Some( + 24..25, + ), + container_name: None, + description: Some( + "struct S", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "Arg", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..16, + name: "Arg", + kind: STRUCT_DEF, + focus_range: Some( + 7..10, + ), + container_name: None, + description: Some( + "struct Arg", + ), + docs: None, + }, + }, + ], + ), + ] + "#]], ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "S", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 17..37, - name: "S", - kind: STRUCT_DEF, - focus_range: Some( - 24..25, - ), - container_name: None, - description: Some( - "struct S", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "Arg", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..16, - name: "Arg", - kind: STRUCT_DEF, - focus_range: Some( - 7..10, - ), - container_name: None, - description: Some( - "struct Arg", - ), - docs: None, - }, - }, - ], - ), - ] - "###); } #[test] fn test_hover_generic_struct_has_flattened_goto_type_actions() { - let (_, actions) = check_hover_result( - r" - //- /main.rs - struct Arg(u32); - struct S{ f1: T } + check_actions( + r#" +struct Arg(u32); +struct S{ f1: T } - fn main() { - let s<|>t = S{ f1: S{ f1: Arg(0) } }; - } - ", - "S>", +fn main() { let s<|>t = S{ f1: S{ f1: Arg(0) } }; } + "#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "S", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 17..37, + name: "S", + kind: STRUCT_DEF, + focus_range: Some( + 24..25, + ), + container_name: None, + description: Some( + "struct S", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "Arg", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..16, + name: "Arg", + kind: STRUCT_DEF, + focus_range: Some( + 7..10, + ), + container_name: None, + description: Some( + "struct Arg", + ), + docs: None, + }, + }, + ], + ), + ] + "#]], ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "S", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 17..37, - name: "S", - kind: STRUCT_DEF, - focus_range: Some( - 24..25, - ), - container_name: None, - description: Some( - "struct S", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "Arg", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..16, - name: "Arg", - kind: STRUCT_DEF, - focus_range: Some( - 7..10, - ), - container_name: None, - description: Some( - "struct Arg", - ), - docs: None, - }, - }, - ], - ), - ] - "###); } #[test] fn test_hover_tuple_has_goto_type_actions() { - let (_, actions) = check_hover_result( - r" - //- /main.rs - struct A(u32); - struct B(u32); - mod M { - pub struct C(u32); - } + check_actions( + r#" +struct A(u32); +struct B(u32); +mod M { + pub struct C(u32); +} - fn main() { - let s<|>t = (A(1), B(2), M::C(3) ); - } - ", - "(A, B, C)", +fn main() { let s<|>t = (A(1), B(2), M::C(3) ); } +"#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "A", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..14, + name: "A", + kind: STRUCT_DEF, + focus_range: Some( + 7..8, + ), + container_name: None, + description: Some( + "struct A", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "B", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 15..29, + name: "B", + kind: STRUCT_DEF, + focus_range: Some( + 22..23, + ), + container_name: None, + description: Some( + "struct B", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "M::C", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 42..60, + name: "C", + kind: STRUCT_DEF, + focus_range: Some( + 53..54, + ), + container_name: None, + description: Some( + "pub struct C", + ), + docs: None, + }, + }, + ], + ), + ] + "#]], ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "A", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..14, - name: "A", - kind: STRUCT_DEF, - focus_range: Some( - 7..8, - ), - container_name: None, - description: Some( - "struct A", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "B", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 15..29, - name: "B", - kind: STRUCT_DEF, - focus_range: Some( - 22..23, - ), - container_name: None, - description: Some( - "struct B", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "M::C", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 42..60, - name: "C", - kind: STRUCT_DEF, - focus_range: Some( - 53..54, - ), - container_name: None, - description: Some( - "pub struct C", - ), - docs: None, - }, - }, - ], - ), - ] - "###); } #[test] fn test_hover_return_impl_trait_has_goto_type_action() { - let (_, actions) = check_hover_result( - r" - //- /main.rs - trait Foo {} + check_actions( + r#" +trait Foo {} +fn foo() -> impl Foo {} - fn foo() -> impl Foo {} - - fn main() { - let s<|>t = foo(); - } - ", - "impl Foo", - ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "Foo", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..12, - name: "Foo", - kind: TRAIT_DEF, - focus_range: Some( - 6..9, - ), - container_name: None, - description: Some( - "trait Foo", - ), - docs: None, +fn main() { let s<|>t = foo(); } +"#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "Foo", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..12, + name: "Foo", + kind: TRAIT_DEF, + focus_range: Some( + 6..9, + ), + container_name: None, + description: Some( + "trait Foo", + ), + docs: None, + }, }, - }, - ], - ), - ] - "###); + ], + ), + ] + "#]], + ); } #[test] fn test_hover_generic_return_impl_trait_has_goto_type_action() { - let (_, actions) = check_hover_result( - r" - //- /main.rs - trait Foo {} - struct S; + check_actions( + r#" +trait Foo {} +struct S; +fn foo() -> impl Foo {} - fn foo() -> impl Foo {} - - fn main() { - let s<|>t = foo(); - } - ", - "impl Foo", +fn main() { let s<|>t = foo(); } +"#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "Foo", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..15, + name: "Foo", + kind: TRAIT_DEF, + focus_range: Some( + 6..9, + ), + container_name: None, + description: Some( + "trait Foo", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "S", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 16..25, + name: "S", + kind: STRUCT_DEF, + focus_range: Some( + 23..24, + ), + container_name: None, + description: Some( + "struct S", + ), + docs: None, + }, + }, + ], + ), + ] + "#]], ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "Foo", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..15, - name: "Foo", - kind: TRAIT_DEF, - focus_range: Some( - 6..9, - ), - container_name: None, - description: Some( - "trait Foo", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "S", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 16..25, - name: "S", - kind: STRUCT_DEF, - focus_range: Some( - 23..24, - ), - container_name: None, - description: Some( - "struct S", - ), - docs: None, - }, - }, - ], - ), - ] - "###); } #[test] fn test_hover_return_impl_traits_has_goto_type_action() { - let (_, actions) = check_hover_result( - r" - //- /main.rs - trait Foo {} - trait Bar {} + check_actions( + r#" +trait Foo {} +trait Bar {} +fn foo() -> impl Foo + Bar {} - fn foo() -> impl Foo + Bar {} - - fn main() { - let s<|>t = foo(); - } - ", - "impl Foo + Bar", +fn main() { let s<|>t = foo(); } + "#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "Foo", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..12, + name: "Foo", + kind: TRAIT_DEF, + focus_range: Some( + 6..9, + ), + container_name: None, + description: Some( + "trait Foo", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "Bar", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 13..25, + name: "Bar", + kind: TRAIT_DEF, + focus_range: Some( + 19..22, + ), + container_name: None, + description: Some( + "trait Bar", + ), + docs: None, + }, + }, + ], + ), + ] + "#]], ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "Foo", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..12, - name: "Foo", - kind: TRAIT_DEF, - focus_range: Some( - 6..9, - ), - container_name: None, - description: Some( - "trait Foo", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "Bar", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 13..25, - name: "Bar", - kind: TRAIT_DEF, - focus_range: Some( - 19..22, - ), - container_name: None, - description: Some( - "trait Bar", - ), - docs: None, - }, - }, - ], - ), - ] - "###); } #[test] fn test_hover_generic_return_impl_traits_has_goto_type_action() { - let (_, actions) = check_hover_result( - r" - //- /main.rs - trait Foo {} - trait Bar {} - struct S1 {} - struct S2 {} + check_actions( + r#" +trait Foo {} +trait Bar {} +struct S1 {} +struct S2 {} - fn foo() -> impl Foo + Bar {} +fn foo() -> impl Foo + Bar {} - fn main() { - let s<|>t = foo(); - } - ", - "impl Foo + Bar", +fn main() { let s<|>t = foo(); } +"#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "Foo", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..15, + name: "Foo", + kind: TRAIT_DEF, + focus_range: Some( + 6..9, + ), + container_name: None, + description: Some( + "trait Foo", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "Bar", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 16..31, + name: "Bar", + kind: TRAIT_DEF, + focus_range: Some( + 22..25, + ), + container_name: None, + description: Some( + "trait Bar", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "S1", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 32..44, + name: "S1", + kind: STRUCT_DEF, + focus_range: Some( + 39..41, + ), + container_name: None, + description: Some( + "struct S1", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "S2", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 45..57, + name: "S2", + kind: STRUCT_DEF, + focus_range: Some( + 52..54, + ), + container_name: None, + description: Some( + "struct S2", + ), + docs: None, + }, + }, + ], + ), + ] + "#]], ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "Foo", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..15, - name: "Foo", - kind: TRAIT_DEF, - focus_range: Some( - 6..9, - ), - container_name: None, - description: Some( - "trait Foo", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "Bar", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 16..31, - name: "Bar", - kind: TRAIT_DEF, - focus_range: Some( - 22..25, - ), - container_name: None, - description: Some( - "trait Bar", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "S1", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 32..44, - name: "S1", - kind: STRUCT_DEF, - focus_range: Some( - 39..41, - ), - container_name: None, - description: Some( - "struct S1", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "S2", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 45..57, - name: "S2", - kind: STRUCT_DEF, - focus_range: Some( - 52..54, - ), - container_name: None, - description: Some( - "struct S2", - ), - docs: None, - }, - }, - ], - ), - ] - "###); } #[test] fn test_hover_arg_impl_trait_has_goto_type_action() { - let (_, actions) = check_hover_result( - r" - //- /lib.rs - trait Foo {} - fn foo(ar<|>g: &impl Foo) {} - ", - "&impl Foo", - ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "Foo", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..12, - name: "Foo", - kind: TRAIT_DEF, - focus_range: Some( - 6..9, - ), - container_name: None, - description: Some( - "trait Foo", - ), - docs: None, + check_actions( + r#" +trait Foo {} +fn foo(ar<|>g: &impl Foo) {} +"#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "Foo", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..12, + name: "Foo", + kind: TRAIT_DEF, + focus_range: Some( + 6..9, + ), + container_name: None, + description: Some( + "trait Foo", + ), + docs: None, + }, }, - }, - ], - ), - ] - "###); + ], + ), + ] + "#]], + ); } #[test] fn test_hover_arg_impl_traits_has_goto_type_action() { - let (_, actions) = check_hover_result( - r" - //- /lib.rs - trait Foo {} - trait Bar {} - struct S{} + check_actions( + r#" +trait Foo {} +trait Bar {} +struct S{} - fn foo(ar<|>g: &impl Foo + Bar) {} - ", - "&impl Foo + Bar", +fn foo(ar<|>g: &impl Foo + Bar) {} +"#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "Foo", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..12, + name: "Foo", + kind: TRAIT_DEF, + focus_range: Some( + 6..9, + ), + container_name: None, + description: Some( + "trait Foo", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "Bar", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 13..28, + name: "Bar", + kind: TRAIT_DEF, + focus_range: Some( + 19..22, + ), + container_name: None, + description: Some( + "trait Bar", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "S", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 29..39, + name: "S", + kind: STRUCT_DEF, + focus_range: Some( + 36..37, + ), + container_name: None, + description: Some( + "struct S", + ), + docs: None, + }, + }, + ], + ), + ] + "#]], ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "Foo", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..12, - name: "Foo", - kind: TRAIT_DEF, - focus_range: Some( - 6..9, - ), - container_name: None, - description: Some( - "trait Foo", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "Bar", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 13..28, - name: "Bar", - kind: TRAIT_DEF, - focus_range: Some( - 19..22, - ), - container_name: None, - description: Some( - "trait Bar", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "S", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 29..39, - name: "S", - kind: STRUCT_DEF, - focus_range: Some( - 36..37, - ), - container_name: None, - description: Some( - "struct S", - ), - docs: None, - }, - }, - ], - ), - ] - "###); } #[test] fn test_hover_arg_generic_impl_trait_has_goto_type_action() { - let (_, actions) = check_hover_result( - r" - //- /lib.rs - trait Foo {} - struct S {} - fn foo(ar<|>g: &impl Foo) {} - ", - "&impl Foo", + check_actions( + r#" +trait Foo {} +struct S {} +fn foo(ar<|>g: &impl Foo) {} +"#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "Foo", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..15, + name: "Foo", + kind: TRAIT_DEF, + focus_range: Some( + 6..9, + ), + container_name: None, + description: Some( + "trait Foo", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "S", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 16..27, + name: "S", + kind: STRUCT_DEF, + focus_range: Some( + 23..24, + ), + container_name: None, + description: Some( + "struct S", + ), + docs: None, + }, + }, + ], + ), + ] + "#]], ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "Foo", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..15, - name: "Foo", - kind: TRAIT_DEF, - focus_range: Some( - 6..9, - ), - container_name: None, - description: Some( - "trait Foo", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "S", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 16..27, - name: "S", - kind: STRUCT_DEF, - focus_range: Some( - 23..24, - ), - container_name: None, - description: Some( - "struct S", - ), - docs: None, - }, - }, - ], - ), - ] - "###); } #[test] fn test_hover_dyn_return_has_goto_type_action() { - let (_, actions) = check_hover_result( - r" - //- /main.rs - trait Foo {} - struct S; - impl Foo for S {} + check_actions( + r#" +trait Foo {} +struct S; +impl Foo for S {} - struct B{} +struct B{} +fn foo() -> B {} - fn foo() -> B {} - - fn main() { - let s<|>t = foo(); - } - ", - "B", - ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( +fn main() { let s<|>t = foo(); } +"#, + expect![[r#" [ - HoverGotoTypeData { - mod_path: "B", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 42..55, - name: "B", - kind: STRUCT_DEF, - focus_range: Some( - 49..50, - ), - container_name: None, - description: Some( - "struct B", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "Foo", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..12, - name: "Foo", - kind: TRAIT_DEF, - focus_range: Some( - 6..9, - ), - container_name: None, - description: Some( - "trait Foo", - ), - docs: None, - }, - }, - ], - ), - ] - "###); + GoToType( + [ + HoverGotoTypeData { + mod_path: "B", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 42..55, + name: "B", + kind: STRUCT_DEF, + focus_range: Some( + 49..50, + ), + container_name: None, + description: Some( + "struct B", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "Foo", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..12, + name: "Foo", + kind: TRAIT_DEF, + focus_range: Some( + 6..9, + ), + container_name: None, + description: Some( + "trait Foo", + ), + docs: None, + }, + }, + ], + ), + ] + "#]], + ); } #[test] fn test_hover_dyn_arg_has_goto_type_action() { - let (_, actions) = check_hover_result( - r" - //- /lib.rs - trait Foo {} - fn foo(ar<|>g: &dyn Foo) {} - ", - "&dyn Foo", - ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "Foo", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..12, - name: "Foo", - kind: TRAIT_DEF, - focus_range: Some( - 6..9, - ), - container_name: None, - description: Some( - "trait Foo", - ), - docs: None, + check_actions( + r#" +trait Foo {} +fn foo(ar<|>g: &dyn Foo) {} +"#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "Foo", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..12, + name: "Foo", + kind: TRAIT_DEF, + focus_range: Some( + 6..9, + ), + container_name: None, + description: Some( + "trait Foo", + ), + docs: None, + }, }, - }, - ], - ), - ] - "###); + ], + ), + ] + "#]], + ); } #[test] fn test_hover_generic_dyn_arg_has_goto_type_action() { - let (_, actions) = check_hover_result( - r" - //- /lib.rs - trait Foo {} - struct S {} - fn foo(ar<|>g: &dyn Foo) {} - ", - "&dyn Foo", + check_actions( + r#" +trait Foo {} +struct S {} +fn foo(ar<|>g: &dyn Foo) {} +"#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "Foo", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..15, + name: "Foo", + kind: TRAIT_DEF, + focus_range: Some( + 6..9, + ), + container_name: None, + description: Some( + "trait Foo", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "S", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 16..27, + name: "S", + kind: STRUCT_DEF, + focus_range: Some( + 23..24, + ), + container_name: None, + description: Some( + "struct S", + ), + docs: None, + }, + }, + ], + ), + ] + "#]], ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "Foo", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..15, - name: "Foo", - kind: TRAIT_DEF, - focus_range: Some( - 6..9, - ), - container_name: None, - description: Some( - "trait Foo", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "S", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 16..27, - name: "S", - kind: STRUCT_DEF, - focus_range: Some( - 23..24, - ), - container_name: None, - description: Some( - "struct S", - ), - docs: None, - }, - }, - ], - ), - ] - "###); } #[test] fn test_hover_goto_type_action_links_order() { - let (_, actions) = check_hover_result( - r" - //- /lib.rs - trait ImplTrait {} - trait DynTrait {} - struct B {} - struct S {} + check_actions( + r#" +trait ImplTrait {} +trait DynTrait {} +struct B {} +struct S {} - fn foo(a<|>rg: &impl ImplTrait>>>) {} - ", - "&impl ImplTrait>>>", +fn foo(a<|>rg: &impl ImplTrait>>>) {} + "#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "ImplTrait", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..21, + name: "ImplTrait", + kind: TRAIT_DEF, + focus_range: Some( + 6..15, + ), + container_name: None, + description: Some( + "trait ImplTrait", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "B", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 43..57, + name: "B", + kind: STRUCT_DEF, + focus_range: Some( + 50..51, + ), + container_name: None, + description: Some( + "struct B", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "DynTrait", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 22..42, + name: "DynTrait", + kind: TRAIT_DEF, + focus_range: Some( + 28..36, + ), + container_name: None, + description: Some( + "trait DynTrait", + ), + docs: None, + }, + }, + HoverGotoTypeData { + mod_path: "S", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 58..69, + name: "S", + kind: STRUCT_DEF, + focus_range: Some( + 65..66, + ), + container_name: None, + description: Some( + "struct S", + ), + docs: None, + }, + }, + ], + ), + ] + "#]], ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "ImplTrait", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..21, - name: "ImplTrait", - kind: TRAIT_DEF, - focus_range: Some( - 6..15, - ), - container_name: None, - description: Some( - "trait ImplTrait", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "B", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 43..57, - name: "B", - kind: STRUCT_DEF, - focus_range: Some( - 50..51, - ), - container_name: None, - description: Some( - "struct B", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "DynTrait", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 22..42, - name: "DynTrait", - kind: TRAIT_DEF, - focus_range: Some( - 28..36, - ), - container_name: None, - description: Some( - "trait DynTrait", - ), - docs: None, - }, - }, - HoverGotoTypeData { - mod_path: "S", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 58..69, - name: "S", - kind: STRUCT_DEF, - focus_range: Some( - 65..66, - ), - container_name: None, - description: Some( - "struct S", - ), - docs: None, - }, - }, - ], - ), - ] - "###); } #[test] fn test_hover_associated_type_has_goto_type_action() { - let (_, actions) = check_hover_result( - r" - //- /main.rs - trait Foo { - type Item; - fn get(self) -> Self::Item {} - } + check_actions( + r#" +trait Foo { + type Item; + fn get(self) -> Self::Item {} +} - struct Bar{} - struct S{} +struct Bar{} +struct S{} - impl Foo for S{ - type Item = Bar; - } +impl Foo for S { type Item = Bar; } - fn test() -> impl Foo { - S{} - } +fn test() -> impl Foo { S {} } - fn main() { - let s<|>t = test().get(); - } - ", - "Foo::Item", - ); - assert_debug_snapshot!(actions, - @r###" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "Foo", - nav: NavigationTarget { - file_id: FileId( - 1, - ), - full_range: 0..62, - name: "Foo", - kind: TRAIT_DEF, - focus_range: Some( - 6..9, - ), - container_name: None, - description: Some( - "trait Foo", - ), - docs: None, +fn main() { let s<|>t = test().get(); } +"#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "Foo", + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..62, + name: "Foo", + kind: TRAIT_DEF, + focus_range: Some( + 6..9, + ), + container_name: None, + description: Some( + "trait Foo", + ), + docs: None, + }, }, - }, - ], - ), - ] - "###); + ], + ), + ] + "#]], + ); } }