diff --git a/crates/ra_analysis/src/call_info.rs b/crates/ra_analysis/src/call_info.rs index 8da19a648adf..2fcd03c9be8d 100644 --- a/crates/ra_analysis/src/call_info.rs +++ b/crates/ra_analysis/src/call_info.rs @@ -128,3 +128,252 @@ impl<'a> FnCallNode<'a> { } } } + +#[cfg(test)] +mod tests { + use super::*; + + use crate::mock_analysis::single_file_with_position; + + fn call_info(text: &str) -> CallInfo { + let (analysis, position) = single_file_with_position(text); + analysis.call_info(position).unwrap().unwrap() + } + + #[test] + fn test_fn_signature_two_args_first() { + let info = call_info( + r#"fn foo(x: u32, y: u32) -> u32 {x + y} +fn bar() { foo(<|>3, ); }"#, + ); + + assert_eq!(info.parameters, vec!("x".to_string(), "y".to_string())); + assert_eq!(info.active_parameter, Some(0)); + } + + #[test] + fn test_fn_signature_two_args_second() { + let info = call_info( + r#"fn foo(x: u32, y: u32) -> u32 {x + y} +fn bar() { foo(3, <|>); }"#, + ); + + assert_eq!(info.parameters, vec!("x".to_string(), "y".to_string())); + assert_eq!(info.active_parameter, Some(1)); + } + + #[test] + fn test_fn_signature_for_impl() { + let info = call_info( + r#"struct F; impl F { pub fn new() { F{}} } +fn bar() {let _ : F = F::new(<|>);}"#, + ); + + assert_eq!(info.parameters, Vec::::new()); + assert_eq!(info.active_parameter, None); + } + + #[test] + fn test_fn_signature_for_method_self() { + let info = call_info( + r#"struct F; +impl F { + pub fn new() -> F{ + F{} + } + + pub fn do_it(&self) {} +} + +fn bar() { + let f : F = F::new(); + f.do_it(<|>); +}"#, + ); + + assert_eq!(info.parameters, vec!["&self".to_string()]); + assert_eq!(info.active_parameter, None); + } + + #[test] + fn test_fn_signature_for_method_with_arg() { + let info = call_info( + r#"struct F; +impl F { + pub fn new() -> F{ + F{} + } + + pub fn do_it(&self, x: i32) {} +} + +fn bar() { + let f : F = F::new(); + f.do_it(<|>); +}"#, + ); + + assert_eq!(info.parameters, vec!["&self".to_string(), "x".to_string()]); + assert_eq!(info.active_parameter, Some(1)); + } + + #[test] + fn test_fn_signature_with_docs_simple() { + let info = call_info( + r#" +/// test +// non-doc-comment +fn foo(j: u32) -> u32 { + j +} + +fn bar() { + let _ = foo(<|>); +} +"#, + ); + + assert_eq!(info.parameters, vec!["j".to_string()]); + assert_eq!(info.active_parameter, Some(0)); + assert_eq!(info.label, "fn foo(j: u32) -> u32".to_string()); + assert_eq!(info.doc, Some("test".into())); + } + + #[test] + fn test_fn_signature_with_docs() { + let info = call_info( + r#" +/// Adds one to the number given. +/// +/// # Examples +/// +/// ``` +/// let five = 5; +/// +/// assert_eq!(6, my_crate::add_one(5)); +/// ``` +pub fn add_one(x: i32) -> i32 { + x + 1 +} + +pub fn do() { + add_one(<|> +}"#, + ); + + assert_eq!(info.parameters, vec!["x".to_string()]); + assert_eq!(info.active_parameter, Some(0)); + assert_eq!(info.label, "pub fn add_one(x: i32) -> i32".to_string()); + assert_eq!( + info.doc, + Some( + r#"Adds one to the number given. + +# Examples + +```rust +let five = 5; + +assert_eq!(6, my_crate::add_one(5)); +```"# + .into() + ) + ); + } + + #[test] + fn test_fn_signature_with_docs_impl() { + let info = call_info( + r#" +struct addr; +impl addr { + /// Adds one to the number given. + /// + /// # Examples + /// + /// ``` + /// let five = 5; + /// + /// assert_eq!(6, my_crate::add_one(5)); + /// ``` + pub fn add_one(x: i32) -> i32 { + x + 1 + } +} + +pub fn do_it() { + addr {}; + addr::add_one(<|>); +}"#, + ); + + assert_eq!(info.parameters, vec!["x".to_string()]); + assert_eq!(info.active_parameter, Some(0)); + assert_eq!(info.label, "pub fn add_one(x: i32) -> i32".to_string()); + assert_eq!( + info.doc, + Some( + r#"Adds one to the number given. + +# Examples + +```rust +let five = 5; + +assert_eq!(6, my_crate::add_one(5)); +```"# + .into() + ) + ); + } + + #[test] + fn test_fn_signature_with_docs_from_actix() { + let info = call_info( + r#" +pub trait WriteHandler +where + Self: Actor, + Self::Context: ActorContext, +{ + /// Method is called when writer emits error. + /// + /// If this method returns `ErrorAction::Continue` writer processing + /// continues otherwise stream processing stops. + fn error(&mut self, err: E, ctx: &mut Self::Context) -> Running { + Running::Stop + } + + /// Method is called when writer finishes. + /// + /// By default this method stops actor's `Context`. + fn finished(&mut self, ctx: &mut Self::Context) { + ctx.stop() + } +} + +pub fn foo() { + WriteHandler r; + r.finished(<|>); +} + +"#, + ); + + assert_eq!( + info.parameters, + vec!["&mut self".to_string(), "ctx".to_string()] + ); + assert_eq!(info.active_parameter, Some(1)); + assert_eq!( + info.doc, + Some( + r#"Method is called when writer finishes. + +By default this method stops actor's `Context`."# + .into() + ) + ); + } + +} diff --git a/crates/ra_analysis/tests/test/main.rs b/crates/ra_analysis/tests/test/main.rs index 1f70af12aa67..2c0735cb50cf 100644 --- a/crates/ra_analysis/tests/test/main.rs +++ b/crates/ra_analysis/tests/test/main.rs @@ -5,14 +5,9 @@ use test_utils::{assert_eq_dbg, assert_eq_text}; use ra_analysis::{ mock_analysis::{analysis_and_position, single_file, single_file_with_position, MockAnalysis}, - AnalysisChange, CrateGraph, FileId, FnSignatureInfo, Query + AnalysisChange, CrateGraph, FileId, Query }; -fn get_signature(text: &str) -> (FnSignatureInfo, Option) { - let (analysis, position) = single_file_with_position(text); - analysis.resolve_callable(position).unwrap().unwrap() -} - #[test] fn test_unresolved_module_diagnostic() { let (analysis, file_id) = single_file("mod foo;"); @@ -99,260 +94,6 @@ fn test_resolve_crate_root() { assert_eq!(host.analysis().crate_for(mod_file).unwrap(), vec![crate_id]); } -#[test] -fn test_fn_signature_two_args_first() { - let (desc, param) = get_signature( - r#"fn foo(x: u32, y: u32) -> u32 {x + y} -fn bar() { foo(<|>3, ); }"#, - ); - - assert_eq!(desc.name, "foo".to_string()); - assert_eq!(desc.params, vec!("x".to_string(), "y".to_string())); - assert_eq!(desc.ret_type, Some("-> u32".into())); - assert_eq!(param, Some(0)); -} - -#[test] -fn test_fn_signature_two_args_second() { - let (desc, param) = get_signature( - r#"fn foo(x: u32, y: u32) -> u32 {x + y} -fn bar() { foo(3, <|>); }"#, - ); - - assert_eq!(desc.name, "foo".to_string()); - assert_eq!(desc.params, vec!("x".to_string(), "y".to_string())); - assert_eq!(desc.ret_type, Some("-> u32".into())); - assert_eq!(param, Some(1)); -} - -#[test] -fn test_fn_signature_for_impl() { - let (desc, param) = get_signature( - r#"struct F; impl F { pub fn new() { F{}} } -fn bar() {let _ : F = F::new(<|>);}"#, - ); - - assert_eq!(desc.name, "new".to_string()); - assert_eq!(desc.params, Vec::::new()); - assert_eq!(desc.ret_type, None); - assert_eq!(param, None); -} - -#[test] -fn test_fn_signature_for_method_self() { - let (desc, param) = get_signature( - r#"struct F; -impl F { - pub fn new() -> F{ - F{} - } - - pub fn do_it(&self) {} -} - -fn bar() { - let f : F = F::new(); - f.do_it(<|>); -}"#, - ); - - assert_eq!(desc.name, "do_it".to_string()); - assert_eq!(desc.params, vec!["&self".to_string()]); - assert_eq!(desc.ret_type, None); - assert_eq!(param, None); -} - -#[test] -fn test_fn_signature_for_method_with_arg() { - let (desc, param) = get_signature( - r#"struct F; -impl F { - pub fn new() -> F{ - F{} - } - - pub fn do_it(&self, x: i32) {} -} - -fn bar() { - let f : F = F::new(); - f.do_it(<|>); -}"#, - ); - - assert_eq!(desc.name, "do_it".to_string()); - assert_eq!(desc.params, vec!["&self".to_string(), "x".to_string()]); - assert_eq!(desc.ret_type, None); - assert_eq!(param, Some(1)); -} - -#[test] -fn test_fn_signature_with_docs_simple() { - let (desc, param) = get_signature( - r#" -/// test -// non-doc-comment -fn foo(j: u32) -> u32 { - j -} - -fn bar() { - let _ = foo(<|>); -} -"#, - ); - - assert_eq!(desc.name, "foo".to_string()); - assert_eq!(desc.params, vec!["j".to_string()]); - assert_eq!(desc.ret_type, Some("-> u32".to_string())); - assert_eq!(param, Some(0)); - assert_eq!(desc.label, "fn foo(j: u32) -> u32".to_string()); - assert_eq!(desc.doc, Some("test".into())); -} - -#[test] -fn test_fn_signature_with_docs() { - let (desc, param) = get_signature( - r#" -/// Adds one to the number given. -/// -/// # Examples -/// -/// ``` -/// let five = 5; -/// -/// assert_eq!(6, my_crate::add_one(5)); -/// ``` -pub fn add_one(x: i32) -> i32 { - x + 1 -} - -pub fn do() { - add_one(<|> -}"#, - ); - - assert_eq!(desc.name, "add_one".to_string()); - assert_eq!(desc.params, vec!["x".to_string()]); - assert_eq!(desc.ret_type, Some("-> i32".to_string())); - assert_eq!(param, Some(0)); - assert_eq!(desc.label, "pub fn add_one(x: i32) -> i32".to_string()); - assert_eq!( - desc.doc, - Some( - r#"Adds one to the number given. - -# Examples - -```rust -let five = 5; - -assert_eq!(6, my_crate::add_one(5)); -```"# - .into() - ) - ); -} - -#[test] -fn test_fn_signature_with_docs_impl() { - let (desc, param) = get_signature( - r#" -struct addr; -impl addr { - /// Adds one to the number given. - /// - /// # Examples - /// - /// ``` - /// let five = 5; - /// - /// assert_eq!(6, my_crate::add_one(5)); - /// ``` - pub fn add_one(x: i32) -> i32 { - x + 1 - } -} - -pub fn do_it() { - addr {}; - addr::add_one(<|>); -}"#, - ); - - assert_eq!(desc.name, "add_one".to_string()); - assert_eq!(desc.params, vec!["x".to_string()]); - assert_eq!(desc.ret_type, Some("-> i32".to_string())); - assert_eq!(param, Some(0)); - assert_eq!(desc.label, "pub fn add_one(x: i32) -> i32".to_string()); - assert_eq!( - desc.doc, - Some( - r#"Adds one to the number given. - -# Examples - -```rust -let five = 5; - -assert_eq!(6, my_crate::add_one(5)); -```"# - .into() - ) - ); -} - -#[test] -fn test_fn_signature_with_docs_from_actix() { - let (desc, param) = get_signature( - r#" -pub trait WriteHandler -where - Self: Actor, - Self::Context: ActorContext, -{ - /// Method is called when writer emits error. - /// - /// If this method returns `ErrorAction::Continue` writer processing - /// continues otherwise stream processing stops. - fn error(&mut self, err: E, ctx: &mut Self::Context) -> Running { - Running::Stop - } - - /// Method is called when writer finishes. - /// - /// By default this method stops actor's `Context`. - fn finished(&mut self, ctx: &mut Self::Context) { - ctx.stop() - } -} - -pub fn foo() { - WriteHandler r; - r.finished(<|>); -} - -"#, - ); - - assert_eq!(desc.name, "finished".to_string()); - assert_eq!( - desc.params, - vec!["&mut self".to_string(), "ctx".to_string()] - ); - assert_eq!(desc.ret_type, None); - assert_eq!(param, Some(1)); - assert_eq!( - desc.doc, - Some( - r#"Method is called when writer finishes. - -By default this method stops actor's `Context`."# - .into() - ) - ); -} - fn get_all_refs(text: &str) -> Vec<(FileId, TextRange)> { let (analysis, position) = single_file_with_position(text); analysis.find_all_refs(position).unwrap()