From cd32177a25a98026584a514de46461ce66f3eb56 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 3 Jan 2019 20:15:12 +0300 Subject: don't create many compilation units for tests --- crates/ra_analysis/tests/runnables.rs | 118 ------- crates/ra_analysis/tests/test/main.rs | 549 +++++++++++++++++++++++++++++ crates/ra_analysis/tests/test/runnables.rs | 109 ++++++ crates/ra_analysis/tests/test/type_of.rs | 77 ++++ crates/ra_analysis/tests/tests.rs | 546 ---------------------------- crates/ra_analysis/tests/type_of.rs | 79 ----- 6 files changed, 735 insertions(+), 743 deletions(-) delete mode 100644 crates/ra_analysis/tests/runnables.rs create mode 100644 crates/ra_analysis/tests/test/main.rs create mode 100644 crates/ra_analysis/tests/test/runnables.rs create mode 100644 crates/ra_analysis/tests/test/type_of.rs delete mode 100644 crates/ra_analysis/tests/tests.rs delete mode 100644 crates/ra_analysis/tests/type_of.rs (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/tests/runnables.rs b/crates/ra_analysis/tests/runnables.rs deleted file mode 100644 index 9e5342c46..000000000 --- a/crates/ra_analysis/tests/runnables.rs +++ /dev/null @@ -1,118 +0,0 @@ -extern crate ra_analysis; -extern crate ra_editor; -extern crate ra_syntax; -extern crate relative_path; -extern crate rustc_hash; -extern crate test_utils; - -use test_utils::assert_eq_dbg; - -use ra_analysis::{ - mock_analysis::{analysis_and_position}, -}; - -#[test] -fn test_runnables() { - let (analysis, pos) = analysis_and_position( - r#" - //- /lib.rs - <|> //empty - fn main() {} - - #[test] - fn test_foo() {} - - #[test] - #[ignore] - fn test_foo() {} - "#, - ); - let runnables = analysis.runnables(pos.file_id).unwrap(); - assert_eq_dbg( - r#"[Runnable { range: [1; 21), kind: Bin }, - Runnable { range: [22; 46), kind: Test { name: "test_foo" } }, - Runnable { range: [47; 81), kind: Test { name: "test_foo" } }]"#, - &runnables, - ) -} - -#[test] -fn test_runnables_module() { - let (analysis, pos) = analysis_and_position( - r#" - //- /lib.rs - <|> //empty - mod test_mod { - #[test] - fn test_foo1() {} - } - "#, - ); - let runnables = analysis.runnables(pos.file_id).unwrap(); - assert_eq_dbg( - r#"[Runnable { range: [1; 59), kind: TestMod { path: "test_mod" } }, - Runnable { range: [28; 57), kind: Test { name: "test_foo1" } }]"#, - &runnables, - ) -} - -#[test] -fn test_runnables_one_depth_layer_module() { - let (analysis, pos) = analysis_and_position( - r#" - //- /lib.rs - <|> //empty - mod foo { - mod test_mod { - #[test] - fn test_foo1() {} - } - } - "#, - ); - let runnables = analysis.runnables(pos.file_id).unwrap(); - assert_eq_dbg( - r#"[Runnable { range: [23; 85), kind: TestMod { path: "foo::test_mod" } }, - Runnable { range: [46; 79), kind: Test { name: "test_foo1" } }]"#, - &runnables, - ) -} - -#[test] -fn test_runnables_multiple_depth_module() { - let (analysis, pos) = analysis_and_position( - r#" - //- /lib.rs - <|> //empty - mod foo { - mod bar { - mod test_mod { - #[test] - fn test_foo1() {} - } - } - } - "#, - ); - let runnables = analysis.runnables(pos.file_id).unwrap(); - assert_eq_dbg( - r#"[Runnable { range: [41; 115), kind: TestMod { path: "foo::bar::test_mod" } }, - Runnable { range: [68; 105), kind: Test { name: "test_foo1" } }]"#, - &runnables, - ) -} - -#[test] -fn test_runnables_no_test_function_in_module() { - let (analysis, pos) = analysis_and_position( - r#" - //- /lib.rs - <|> //empty - mod test_mod { - fn foo1() {} - } - "#, - ); - let runnables = analysis.runnables(pos.file_id).unwrap(); - assert_eq_dbg(r#"[]"#, &runnables) -} diff --git a/crates/ra_analysis/tests/test/main.rs b/crates/ra_analysis/tests/test/main.rs new file mode 100644 index 000000000..23a5799b9 --- /dev/null +++ b/crates/ra_analysis/tests/test/main.rs @@ -0,0 +1,549 @@ +mod runnables; +mod type_of; + +use ra_syntax::TextRange; +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, +}; + +fn get_signature(text: &str) -> (FnSignatureInfo, Option) { + let (analysis, position) = single_file_with_position(text); + analysis.resolve_callable(position).unwrap().unwrap() +} + +#[test] +fn approximate_resolve_works_in_items() { + let (analysis, pos) = analysis_and_position( + " + //- /lib.rs + struct Foo; + enum E { X(Foo<|>) } + ", + ); + + let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap(); + assert_eq_dbg( + r#"ReferenceResolution { + reference_range: [23; 26), + resolves_to: [NavigationTarget { file_id: FileId(1), name: "Foo", kind: STRUCT_DEF, range: [0; 11), ptr: Some(LocalSyntaxPtr { range: [0; 11), kind: STRUCT_DEF }) }] + }"#, + &symbols, + ); +} + +#[test] +fn test_resolve_module() { + let (analysis, pos) = analysis_and_position( + " + //- /lib.rs + mod <|>foo; + //- /foo.rs + // empty + ", + ); + + let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap(); + assert_eq_dbg( + r#"ReferenceResolution { + reference_range: [4; 7), + resolves_to: [NavigationTarget { file_id: FileId(2), name: "foo", kind: MODULE, range: [0; 0), ptr: None }] + }"#, + &symbols, + ); + + let (analysis, pos) = analysis_and_position( + " + //- /lib.rs + mod <|>foo; + //- /foo/mod.rs + // empty + ", + ); + + let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap(); + assert_eq_dbg( + r#"ReferenceResolution { + reference_range: [4; 7), + resolves_to: [NavigationTarget { file_id: FileId(2), name: "foo", kind: MODULE, range: [0; 0), ptr: None }] + }"#, + &symbols, + ); +} + +#[test] +fn test_unresolved_module_diagnostic() { + let (analysis, file_id) = single_file("mod foo;"); + let diagnostics = analysis.diagnostics(file_id).unwrap(); + assert_eq_dbg( + r#"[Diagnostic { + message: "unresolved module", + range: [4; 7), + fix: Some(SourceChange { + label: "create module", + source_file_edits: [], + file_system_edits: [CreateFile { source_root: SourceRootId(0), path: "foo.rs" }], + cursor_position: None }), + severity: Error }]"#, + &diagnostics, + ); +} + +#[test] +fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() { + let (analysis, file_id) = single_file("mod foo {}"); + let diagnostics = analysis.diagnostics(file_id).unwrap(); + assert_eq_dbg(r#"[]"#, &diagnostics); +} + +#[test] +fn test_resolve_parent_module() { + let (analysis, pos) = analysis_and_position( + " + //- /lib.rs + mod foo; + //- /foo.rs + <|>// empty + ", + ); + let symbols = analysis.parent_module(pos).unwrap(); + assert_eq_dbg( + r#"[NavigationTarget { file_id: FileId(1), name: "foo", kind: MODULE, range: [4; 7), ptr: None }]"#, + &symbols, + ); +} + +#[test] +fn test_resolve_parent_module_for_inline() { + let (analysis, pos) = analysis_and_position( + " + //- /lib.rs + mod foo { + mod bar { + mod baz { <|> } + } + } + ", + ); + let symbols = analysis.parent_module(pos).unwrap(); + assert_eq_dbg( + r#"[NavigationTarget { file_id: FileId(1), name: "bar", kind: MODULE, range: [18; 21), ptr: None }]"#, + &symbols, + ); +} + +#[test] +fn test_resolve_crate_root() { + let mock = MockAnalysis::with_files( + " + //- /lib.rs + mod foo; + //- /foo.rs + // emtpy <|> + ", + ); + let root_file = mock.id_of("/lib.rs"); + let mod_file = mock.id_of("/foo.rs"); + let mut host = mock.analysis_host(); + assert!(host.analysis().crate_for(mod_file).unwrap().is_empty()); + + let mut crate_graph = CrateGraph::default(); + let crate_id = crate_graph.add_crate_root(root_file); + let mut change = AnalysisChange::new(); + change.set_crate_graph(crate_graph); + host.apply_change(change); + + 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 +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() +} + +#[test] +fn test_find_all_refs_for_local() { + let code = r#" + fn main() { + let mut i = 1; + let j = 1; + i = i<|> + j; + + { + i = 0; + } + + i = 5; + }"#; + + let refs = get_all_refs(code); + assert_eq!(refs.len(), 5); +} + +#[test] +fn test_find_all_refs_for_param_inside() { + let code = r#" + fn foo(i : u32) -> u32 { + i<|> + }"#; + + let refs = get_all_refs(code); + assert_eq!(refs.len(), 2); +} + +#[test] +fn test_find_all_refs_for_fn_param() { + let code = r#" + fn foo(i<|> : u32) -> u32 { + i + }"#; + + let refs = get_all_refs(code); + assert_eq!(refs.len(), 2); +} +#[test] +fn test_rename_for_local() { + test_rename( + r#" + fn main() { + let mut i = 1; + let j = 1; + i = i<|> + j; + + { + i = 0; + } + + i = 5; + }"#, + "k", + r#" + fn main() { + let mut k = 1; + let j = 1; + k = k + j; + + { + k = 0; + } + + k = 5; + }"#, + ); +} + +#[test] +fn test_rename_for_param_inside() { + test_rename( + r#" + fn foo(i : u32) -> u32 { + i<|> + }"#, + "j", + r#" + fn foo(j : u32) -> u32 { + j + }"#, + ); +} + +#[test] +fn test_rename_refs_for_fn_param() { + test_rename( + r#" + fn foo(i<|> : u32) -> u32 { + i + }"#, + "new_name", + r#" + fn foo(new_name : u32) -> u32 { + new_name + }"#, + ); +} + +#[test] +fn test_rename_for_mut_param() { + test_rename( + r#" + fn foo(mut i<|> : u32) -> u32 { + i + }"#, + "new_name", + r#" + fn foo(mut new_name : u32) -> u32 { + new_name + }"#, + ); +} +fn test_rename(text: &str, new_name: &str, expected: &str) { + let (analysis, position) = single_file_with_position(text); + let edits = analysis.rename(position, new_name).unwrap(); + let mut text_edit_bulder = ra_text_edit::TextEditBuilder::default(); + let mut file_id: Option = None; + for edit in edits { + file_id = Some(edit.file_id); + for atom in edit.edit.as_atoms() { + text_edit_bulder.replace(atom.delete, atom.insert.clone()); + } + } + let result = text_edit_bulder + .finish() + .apply(&*analysis.file_text(file_id.unwrap())); + assert_eq_text!(expected, &*result); +} diff --git a/crates/ra_analysis/tests/test/runnables.rs b/crates/ra_analysis/tests/test/runnables.rs new file mode 100644 index 000000000..e6e0afbc3 --- /dev/null +++ b/crates/ra_analysis/tests/test/runnables.rs @@ -0,0 +1,109 @@ +use test_utils::assert_eq_dbg; + +use ra_analysis::mock_analysis::analysis_and_position; + +#[test] +fn test_runnables() { + let (analysis, pos) = analysis_and_position( + r#" + //- /lib.rs + <|> //empty + fn main() {} + + #[test] + fn test_foo() {} + + #[test] + #[ignore] + fn test_foo() {} + "#, + ); + let runnables = analysis.runnables(pos.file_id).unwrap(); + assert_eq_dbg( + r#"[Runnable { range: [1; 21), kind: Bin }, + Runnable { range: [22; 46), kind: Test { name: "test_foo" } }, + Runnable { range: [47; 81), kind: Test { name: "test_foo" } }]"#, + &runnables, + ) +} + +#[test] +fn test_runnables_module() { + let (analysis, pos) = analysis_and_position( + r#" + //- /lib.rs + <|> //empty + mod test_mod { + #[test] + fn test_foo1() {} + } + "#, + ); + let runnables = analysis.runnables(pos.file_id).unwrap(); + assert_eq_dbg( + r#"[Runnable { range: [1; 59), kind: TestMod { path: "test_mod" } }, + Runnable { range: [28; 57), kind: Test { name: "test_foo1" } }]"#, + &runnables, + ) +} + +#[test] +fn test_runnables_one_depth_layer_module() { + let (analysis, pos) = analysis_and_position( + r#" + //- /lib.rs + <|> //empty + mod foo { + mod test_mod { + #[test] + fn test_foo1() {} + } + } + "#, + ); + let runnables = analysis.runnables(pos.file_id).unwrap(); + assert_eq_dbg( + r#"[Runnable { range: [23; 85), kind: TestMod { path: "foo::test_mod" } }, + Runnable { range: [46; 79), kind: Test { name: "test_foo1" } }]"#, + &runnables, + ) +} + +#[test] +fn test_runnables_multiple_depth_module() { + let (analysis, pos) = analysis_and_position( + r#" + //- /lib.rs + <|> //empty + mod foo { + mod bar { + mod test_mod { + #[test] + fn test_foo1() {} + } + } + } + "#, + ); + let runnables = analysis.runnables(pos.file_id).unwrap(); + assert_eq_dbg( + r#"[Runnable { range: [41; 115), kind: TestMod { path: "foo::bar::test_mod" } }, + Runnable { range: [68; 105), kind: Test { name: "test_foo1" } }]"#, + &runnables, + ) +} + +#[test] +fn test_runnables_no_test_function_in_module() { + let (analysis, pos) = analysis_and_position( + r#" + //- /lib.rs + <|> //empty + mod test_mod { + fn foo1() {} + } + "#, + ); + let runnables = analysis.runnables(pos.file_id).unwrap(); + assert_eq_dbg(r#"[]"#, &runnables) +} diff --git a/crates/ra_analysis/tests/test/type_of.rs b/crates/ra_analysis/tests/test/type_of.rs new file mode 100644 index 000000000..9d15b52a8 --- /dev/null +++ b/crates/ra_analysis/tests/test/type_of.rs @@ -0,0 +1,77 @@ +use ra_analysis::mock_analysis::single_file_with_range; + +#[test] +fn test_type_of_for_function() { + let (analysis, range) = single_file_with_range( + " + pub fn foo() -> u32 { 1 }; + + fn main() { + let foo_test = <|>foo()<|>; + } + ", + ); + + let type_name = analysis.type_of(range).unwrap().unwrap(); + assert_eq!("u32", &type_name); +} + +// FIXME: improve type_of to make this work +#[test] +fn test_type_of_for_num() { + let (analysis, range) = single_file_with_range( + r#" + fn main() { + let foo_test = <|>"foo"<|>; + } + "#, + ); + + assert!(analysis.type_of(range).unwrap().is_none()); +} +// FIXME: improve type_of to make this work +#[test] +fn test_type_of_for_binding() { + let (analysis, range) = single_file_with_range( + " + pub fn foo() -> u32 { 1 }; + + fn main() { + let <|>foo_test<|> = foo(); + } + ", + ); + + assert!(analysis.type_of(range).unwrap().is_none()); +} + +// FIXME: improve type_of to make this work +#[test] +fn test_type_of_for_expr_1() { + let (analysis, range) = single_file_with_range( + " + fn main() { + let foo = <|>1 + foo_test<|>; + } + ", + ); + + let type_name = analysis.type_of(range).unwrap().unwrap(); + assert_eq!("[unknown]", &type_name); +} + +// FIXME: improve type_of to make this work +#[test] +fn test_type_of_for_expr_2() { + let (analysis, range) = single_file_with_range( + " + fn main() { + let foo: usize = 1; + let bar = <|>1 + foo_test<|>; + } + ", + ); + + let type_name = analysis.type_of(range).unwrap().unwrap(); + assert_eq!("[unknown]", &type_name); +} diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs deleted file mode 100644 index c2ef87b54..000000000 --- a/crates/ra_analysis/tests/tests.rs +++ /dev/null @@ -1,546 +0,0 @@ -use ra_syntax::TextRange; -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, -}; - -fn get_signature(text: &str) -> (FnSignatureInfo, Option) { - let (analysis, position) = single_file_with_position(text); - analysis.resolve_callable(position).unwrap().unwrap() -} - -#[test] -fn approximate_resolve_works_in_items() { - let (analysis, pos) = analysis_and_position( - " - //- /lib.rs - struct Foo; - enum E { X(Foo<|>) } - ", - ); - - let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap(); - assert_eq_dbg( - r#"ReferenceResolution { - reference_range: [23; 26), - resolves_to: [NavigationTarget { file_id: FileId(1), name: "Foo", kind: STRUCT_DEF, range: [0; 11), ptr: Some(LocalSyntaxPtr { range: [0; 11), kind: STRUCT_DEF }) }] - }"#, - &symbols, - ); -} - -#[test] -fn test_resolve_module() { - let (analysis, pos) = analysis_and_position( - " - //- /lib.rs - mod <|>foo; - //- /foo.rs - // empty - ", - ); - - let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap(); - assert_eq_dbg( - r#"ReferenceResolution { - reference_range: [4; 7), - resolves_to: [NavigationTarget { file_id: FileId(2), name: "foo", kind: MODULE, range: [0; 0), ptr: None }] - }"#, - &symbols, - ); - - let (analysis, pos) = analysis_and_position( - " - //- /lib.rs - mod <|>foo; - //- /foo/mod.rs - // empty - ", - ); - - let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap(); - assert_eq_dbg( - r#"ReferenceResolution { - reference_range: [4; 7), - resolves_to: [NavigationTarget { file_id: FileId(2), name: "foo", kind: MODULE, range: [0; 0), ptr: None }] - }"#, - &symbols, - ); -} - -#[test] -fn test_unresolved_module_diagnostic() { - let (analysis, file_id) = single_file("mod foo;"); - let diagnostics = analysis.diagnostics(file_id).unwrap(); - assert_eq_dbg( - r#"[Diagnostic { - message: "unresolved module", - range: [4; 7), - fix: Some(SourceChange { - label: "create module", - source_file_edits: [], - file_system_edits: [CreateFile { source_root: SourceRootId(0), path: "foo.rs" }], - cursor_position: None }), - severity: Error }]"#, - &diagnostics, - ); -} - -#[test] -fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() { - let (analysis, file_id) = single_file("mod foo {}"); - let diagnostics = analysis.diagnostics(file_id).unwrap(); - assert_eq_dbg(r#"[]"#, &diagnostics); -} - -#[test] -fn test_resolve_parent_module() { - let (analysis, pos) = analysis_and_position( - " - //- /lib.rs - mod foo; - //- /foo.rs - <|>// empty - ", - ); - let symbols = analysis.parent_module(pos).unwrap(); - assert_eq_dbg( - r#"[NavigationTarget { file_id: FileId(1), name: "foo", kind: MODULE, range: [4; 7), ptr: None }]"#, - &symbols, - ); -} - -#[test] -fn test_resolve_parent_module_for_inline() { - let (analysis, pos) = analysis_and_position( - " - //- /lib.rs - mod foo { - mod bar { - mod baz { <|> } - } - } - ", - ); - let symbols = analysis.parent_module(pos).unwrap(); - assert_eq_dbg( - r#"[NavigationTarget { file_id: FileId(1), name: "bar", kind: MODULE, range: [18; 21), ptr: None }]"#, - &symbols, - ); -} - -#[test] -fn test_resolve_crate_root() { - let mock = MockAnalysis::with_files( - " - //- /lib.rs - mod foo; - //- /foo.rs - // emtpy <|> - ", - ); - let root_file = mock.id_of("/lib.rs"); - let mod_file = mock.id_of("/foo.rs"); - let mut host = mock.analysis_host(); - assert!(host.analysis().crate_for(mod_file).unwrap().is_empty()); - - let mut crate_graph = CrateGraph::default(); - let crate_id = crate_graph.add_crate_root(root_file); - let mut change = AnalysisChange::new(); - change.set_crate_graph(crate_graph); - host.apply_change(change); - - 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 -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() -} - -#[test] -fn test_find_all_refs_for_local() { - let code = r#" - fn main() { - let mut i = 1; - let j = 1; - i = i<|> + j; - - { - i = 0; - } - - i = 5; - }"#; - - let refs = get_all_refs(code); - assert_eq!(refs.len(), 5); -} - -#[test] -fn test_find_all_refs_for_param_inside() { - let code = r#" - fn foo(i : u32) -> u32 { - i<|> - }"#; - - let refs = get_all_refs(code); - assert_eq!(refs.len(), 2); -} - -#[test] -fn test_find_all_refs_for_fn_param() { - let code = r#" - fn foo(i<|> : u32) -> u32 { - i - }"#; - - let refs = get_all_refs(code); - assert_eq!(refs.len(), 2); -} -#[test] -fn test_rename_for_local() { - test_rename( - r#" - fn main() { - let mut i = 1; - let j = 1; - i = i<|> + j; - - { - i = 0; - } - - i = 5; - }"#, - "k", - r#" - fn main() { - let mut k = 1; - let j = 1; - k = k + j; - - { - k = 0; - } - - k = 5; - }"#, - ); -} - -#[test] -fn test_rename_for_param_inside() { - test_rename( - r#" - fn foo(i : u32) -> u32 { - i<|> - }"#, - "j", - r#" - fn foo(j : u32) -> u32 { - j - }"#, - ); -} - -#[test] -fn test_rename_refs_for_fn_param() { - test_rename( - r#" - fn foo(i<|> : u32) -> u32 { - i - }"#, - "new_name", - r#" - fn foo(new_name : u32) -> u32 { - new_name - }"#, - ); -} - -#[test] -fn test_rename_for_mut_param() { - test_rename( - r#" - fn foo(mut i<|> : u32) -> u32 { - i - }"#, - "new_name", - r#" - fn foo(mut new_name : u32) -> u32 { - new_name - }"#, - ); -} -fn test_rename(text: &str, new_name: &str, expected: &str) { - let (analysis, position) = single_file_with_position(text); - let edits = analysis.rename(position, new_name).unwrap(); - let mut text_edit_bulder = ra_text_edit::TextEditBuilder::default(); - let mut file_id: Option = None; - for edit in edits { - file_id = Some(edit.file_id); - for atom in edit.edit.as_atoms() { - text_edit_bulder.replace(atom.delete, atom.insert.clone()); - } - } - let result = text_edit_bulder - .finish() - .apply(&*analysis.file_text(file_id.unwrap())); - assert_eq_text!(expected, &*result); -} diff --git a/crates/ra_analysis/tests/type_of.rs b/crates/ra_analysis/tests/type_of.rs deleted file mode 100644 index 375f808bb..000000000 --- a/crates/ra_analysis/tests/type_of.rs +++ /dev/null @@ -1,79 +0,0 @@ -use ra_analysis::{ - mock_analysis::{single_file_with_range}, -}; - -#[test] -fn test_type_of_for_function() { - let (analysis, range) = single_file_with_range( - " - pub fn foo() -> u32 { 1 }; - - fn main() { - let foo_test = <|>foo()<|>; - } - ", - ); - - let type_name = analysis.type_of(range).unwrap().unwrap(); - assert_eq!("u32", &type_name); -} - -// FIXME: improve type_of to make this work -#[test] -fn test_type_of_for_num() { - let (analysis, range) = single_file_with_range( - r#" - fn main() { - let foo_test = <|>"foo"<|>; - } - "#, - ); - - assert!(analysis.type_of(range).unwrap().is_none()); -} -// FIXME: improve type_of to make this work -#[test] -fn test_type_of_for_binding() { - let (analysis, range) = single_file_with_range( - " - pub fn foo() -> u32 { 1 }; - - fn main() { - let <|>foo_test<|> = foo(); - } - ", - ); - - assert!(analysis.type_of(range).unwrap().is_none()); -} - -// FIXME: improve type_of to make this work -#[test] -fn test_type_of_for_expr_1() { - let (analysis, range) = single_file_with_range( - " - fn main() { - let foo = <|>1 + foo_test<|>; - } - ", - ); - - let type_name = analysis.type_of(range).unwrap().unwrap(); - assert_eq!("[unknown]", &type_name); -} - -// FIXME: improve type_of to make this work -#[test] -fn test_type_of_for_expr_2() { - let (analysis, range) = single_file_with_range( - " - fn main() { - let foo: usize = 1; - let bar = <|>1 + foo_test<|>; - } - ", - ); - - let type_name = analysis.type_of(range).unwrap().unwrap(); - assert_eq!("[unknown]", &type_name); -} -- cgit v1.2.3