aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/tests/test
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-01-03 17:15:12 +0000
committerAleksey Kladov <[email protected]>2019-01-03 17:15:12 +0000
commitcd32177a25a98026584a514de46461ce66f3eb56 (patch)
tree62a4dfebe2b179df6c7636100e1c13e33afe16f5 /crates/ra_analysis/tests/test
parent8a24f25482f07eecab254c93223369fa532c076f (diff)
don't create many compilation units for tests
Diffstat (limited to 'crates/ra_analysis/tests/test')
-rw-r--r--crates/ra_analysis/tests/test/main.rs549
-rw-r--r--crates/ra_analysis/tests/test/runnables.rs109
-rw-r--r--crates/ra_analysis/tests/test/type_of.rs77
3 files changed, 735 insertions, 0 deletions
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 @@
1mod runnables;
2mod type_of;
3
4use ra_syntax::TextRange;
5use test_utils::{assert_eq_dbg, assert_eq_text};
6
7use ra_analysis::{
8 mock_analysis::{analysis_and_position, single_file, single_file_with_position, MockAnalysis},
9 AnalysisChange, CrateGraph, FileId, FnSignatureInfo,
10};
11
12fn get_signature(text: &str) -> (FnSignatureInfo, Option<usize>) {
13 let (analysis, position) = single_file_with_position(text);
14 analysis.resolve_callable(position).unwrap().unwrap()
15}
16
17#[test]
18fn approximate_resolve_works_in_items() {
19 let (analysis, pos) = analysis_and_position(
20 "
21 //- /lib.rs
22 struct Foo;
23 enum E { X(Foo<|>) }
24 ",
25 );
26
27 let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap();
28 assert_eq_dbg(
29 r#"ReferenceResolution {
30 reference_range: [23; 26),
31 resolves_to: [NavigationTarget { file_id: FileId(1), name: "Foo", kind: STRUCT_DEF, range: [0; 11), ptr: Some(LocalSyntaxPtr { range: [0; 11), kind: STRUCT_DEF }) }]
32 }"#,
33 &symbols,
34 );
35}
36
37#[test]
38fn test_resolve_module() {
39 let (analysis, pos) = analysis_and_position(
40 "
41 //- /lib.rs
42 mod <|>foo;
43 //- /foo.rs
44 // empty
45 ",
46 );
47
48 let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap();
49 assert_eq_dbg(
50 r#"ReferenceResolution {
51 reference_range: [4; 7),
52 resolves_to: [NavigationTarget { file_id: FileId(2), name: "foo", kind: MODULE, range: [0; 0), ptr: None }]
53 }"#,
54 &symbols,
55 );
56
57 let (analysis, pos) = analysis_and_position(
58 "
59 //- /lib.rs
60 mod <|>foo;
61 //- /foo/mod.rs
62 // empty
63 ",
64 );
65
66 let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap();
67 assert_eq_dbg(
68 r#"ReferenceResolution {
69 reference_range: [4; 7),
70 resolves_to: [NavigationTarget { file_id: FileId(2), name: "foo", kind: MODULE, range: [0; 0), ptr: None }]
71 }"#,
72 &symbols,
73 );
74}
75
76#[test]
77fn test_unresolved_module_diagnostic() {
78 let (analysis, file_id) = single_file("mod foo;");
79 let diagnostics = analysis.diagnostics(file_id).unwrap();
80 assert_eq_dbg(
81 r#"[Diagnostic {
82 message: "unresolved module",
83 range: [4; 7),
84 fix: Some(SourceChange {
85 label: "create module",
86 source_file_edits: [],
87 file_system_edits: [CreateFile { source_root: SourceRootId(0), path: "foo.rs" }],
88 cursor_position: None }),
89 severity: Error }]"#,
90 &diagnostics,
91 );
92}
93
94#[test]
95fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() {
96 let (analysis, file_id) = single_file("mod foo {}");
97 let diagnostics = analysis.diagnostics(file_id).unwrap();
98 assert_eq_dbg(r#"[]"#, &diagnostics);
99}
100
101#[test]
102fn test_resolve_parent_module() {
103 let (analysis, pos) = analysis_and_position(
104 "
105 //- /lib.rs
106 mod foo;
107 //- /foo.rs
108 <|>// empty
109 ",
110 );
111 let symbols = analysis.parent_module(pos).unwrap();
112 assert_eq_dbg(
113 r#"[NavigationTarget { file_id: FileId(1), name: "foo", kind: MODULE, range: [4; 7), ptr: None }]"#,
114 &symbols,
115 );
116}
117
118#[test]
119fn test_resolve_parent_module_for_inline() {
120 let (analysis, pos) = analysis_and_position(
121 "
122 //- /lib.rs
123 mod foo {
124 mod bar {
125 mod baz { <|> }
126 }
127 }
128 ",
129 );
130 let symbols = analysis.parent_module(pos).unwrap();
131 assert_eq_dbg(
132 r#"[NavigationTarget { file_id: FileId(1), name: "bar", kind: MODULE, range: [18; 21), ptr: None }]"#,
133 &symbols,
134 );
135}
136
137#[test]
138fn test_resolve_crate_root() {
139 let mock = MockAnalysis::with_files(
140 "
141 //- /lib.rs
142 mod foo;
143 //- /foo.rs
144 // emtpy <|>
145 ",
146 );
147 let root_file = mock.id_of("/lib.rs");
148 let mod_file = mock.id_of("/foo.rs");
149 let mut host = mock.analysis_host();
150 assert!(host.analysis().crate_for(mod_file).unwrap().is_empty());
151
152 let mut crate_graph = CrateGraph::default();
153 let crate_id = crate_graph.add_crate_root(root_file);
154 let mut change = AnalysisChange::new();
155 change.set_crate_graph(crate_graph);
156 host.apply_change(change);
157
158 assert_eq!(host.analysis().crate_for(mod_file).unwrap(), vec![crate_id]);
159}
160
161#[test]
162fn test_fn_signature_two_args_first() {
163 let (desc, param) = get_signature(
164 r#"fn foo(x: u32, y: u32) -> u32 {x + y}
165fn bar() { foo(<|>3, ); }"#,
166 );
167
168 assert_eq!(desc.name, "foo".to_string());
169 assert_eq!(desc.params, vec!("x".to_string(), "y".to_string()));
170 assert_eq!(desc.ret_type, Some("-> u32".into()));
171 assert_eq!(param, Some(0));
172}
173
174#[test]
175fn test_fn_signature_two_args_second() {
176 let (desc, param) = get_signature(
177 r#"fn foo(x: u32, y: u32) -> u32 {x + y}
178fn bar() { foo(3, <|>); }"#,
179 );
180
181 assert_eq!(desc.name, "foo".to_string());
182 assert_eq!(desc.params, vec!("x".to_string(), "y".to_string()));
183 assert_eq!(desc.ret_type, Some("-> u32".into()));
184 assert_eq!(param, Some(1));
185}
186
187#[test]
188fn test_fn_signature_for_impl() {
189 let (desc, param) = get_signature(
190 r#"struct F; impl F { pub fn new() { F{}} }
191fn bar() {let _ : F = F::new(<|>);}"#,
192 );
193
194 assert_eq!(desc.name, "new".to_string());
195 assert_eq!(desc.params, Vec::<String>::new());
196 assert_eq!(desc.ret_type, None);
197 assert_eq!(param, None);
198}
199
200#[test]
201fn test_fn_signature_for_method_self() {
202 let (desc, param) = get_signature(
203 r#"struct F;
204impl F {
205 pub fn new() -> F{
206 F{}
207 }
208
209 pub fn do_it(&self) {}
210}
211
212fn bar() {
213 let f : F = F::new();
214 f.do_it(<|>);
215}"#,
216 );
217
218 assert_eq!(desc.name, "do_it".to_string());
219 assert_eq!(desc.params, vec!["&self".to_string()]);
220 assert_eq!(desc.ret_type, None);
221 assert_eq!(param, None);
222}
223
224#[test]
225fn test_fn_signature_for_method_with_arg() {
226 let (desc, param) = get_signature(
227 r#"struct F;
228impl F {
229 pub fn new() -> F{
230 F{}
231 }
232
233 pub fn do_it(&self, x: i32) {}
234}
235
236fn bar() {
237 let f : F = F::new();
238 f.do_it(<|>);
239}"#,
240 );
241
242 assert_eq!(desc.name, "do_it".to_string());
243 assert_eq!(desc.params, vec!["&self".to_string(), "x".to_string()]);
244 assert_eq!(desc.ret_type, None);
245 assert_eq!(param, Some(1));
246}
247
248#[test]
249fn test_fn_signature_with_docs_simple() {
250 let (desc, param) = get_signature(
251 r#"
252// test
253fn foo(j: u32) -> u32 {
254 j
255}
256
257fn bar() {
258 let _ = foo(<|>);
259}
260"#,
261 );
262
263 assert_eq!(desc.name, "foo".to_string());
264 assert_eq!(desc.params, vec!["j".to_string()]);
265 assert_eq!(desc.ret_type, Some("-> u32".to_string()));
266 assert_eq!(param, Some(0));
267 assert_eq!(desc.label, "fn foo(j: u32) -> u32".to_string());
268 assert_eq!(desc.doc, Some("test".into()));
269}
270
271#[test]
272fn test_fn_signature_with_docs() {
273 let (desc, param) = get_signature(
274 r#"
275/// Adds one to the number given.
276///
277/// # Examples
278///
279/// ```
280/// let five = 5;
281///
282/// assert_eq!(6, my_crate::add_one(5));
283/// ```
284pub fn add_one(x: i32) -> i32 {
285 x + 1
286}
287
288pub fn do() {
289 add_one(<|>
290}"#,
291 );
292
293 assert_eq!(desc.name, "add_one".to_string());
294 assert_eq!(desc.params, vec!["x".to_string()]);
295 assert_eq!(desc.ret_type, Some("-> i32".to_string()));
296 assert_eq!(param, Some(0));
297 assert_eq!(desc.label, "pub fn add_one(x: i32) -> i32".to_string());
298 assert_eq!(
299 desc.doc,
300 Some(
301 r#"Adds one to the number given.
302
303# Examples
304
305```rust
306let five = 5;
307
308assert_eq!(6, my_crate::add_one(5));
309```"#
310 .into()
311 )
312 );
313}
314
315#[test]
316fn test_fn_signature_with_docs_impl() {
317 let (desc, param) = get_signature(
318 r#"
319struct addr;
320impl addr {
321 /// Adds one to the number given.
322 ///
323 /// # Examples
324 ///
325 /// ```
326 /// let five = 5;
327 ///
328 /// assert_eq!(6, my_crate::add_one(5));
329 /// ```
330 pub fn add_one(x: i32) -> i32 {
331 x + 1
332 }
333}
334
335pub fn do_it() {
336 addr {};
337 addr::add_one(<|>);
338}"#,
339 );
340
341 assert_eq!(desc.name, "add_one".to_string());
342 assert_eq!(desc.params, vec!["x".to_string()]);
343 assert_eq!(desc.ret_type, Some("-> i32".to_string()));
344 assert_eq!(param, Some(0));
345 assert_eq!(desc.label, "pub fn add_one(x: i32) -> i32".to_string());
346 assert_eq!(
347 desc.doc,
348 Some(
349 r#"Adds one to the number given.
350
351# Examples
352
353```rust
354let five = 5;
355
356assert_eq!(6, my_crate::add_one(5));
357```"#
358 .into()
359 )
360 );
361}
362
363#[test]
364fn test_fn_signature_with_docs_from_actix() {
365 let (desc, param) = get_signature(
366 r#"
367pub trait WriteHandler<E>
368where
369 Self: Actor,
370 Self::Context: ActorContext,
371{
372 /// Method is called when writer emits error.
373 ///
374 /// If this method returns `ErrorAction::Continue` writer processing
375 /// continues otherwise stream processing stops.
376 fn error(&mut self, err: E, ctx: &mut Self::Context) -> Running {
377 Running::Stop
378 }
379
380 /// Method is called when writer finishes.
381 ///
382 /// By default this method stops actor's `Context`.
383 fn finished(&mut self, ctx: &mut Self::Context) {
384 ctx.stop()
385 }
386}
387
388pub fn foo() {
389 WriteHandler r;
390 r.finished(<|>);
391}
392
393"#,
394 );
395
396 assert_eq!(desc.name, "finished".to_string());
397 assert_eq!(
398 desc.params,
399 vec!["&mut self".to_string(), "ctx".to_string()]
400 );
401 assert_eq!(desc.ret_type, None);
402 assert_eq!(param, Some(1));
403 assert_eq!(
404 desc.doc,
405 Some(
406 r#"Method is called when writer finishes.
407
408By default this method stops actor's `Context`."#
409 .into()
410 )
411 );
412}
413
414fn get_all_refs(text: &str) -> Vec<(FileId, TextRange)> {
415 let (analysis, position) = single_file_with_position(text);
416 analysis.find_all_refs(position).unwrap()
417}
418
419#[test]
420fn test_find_all_refs_for_local() {
421 let code = r#"
422 fn main() {
423 let mut i = 1;
424 let j = 1;
425 i = i<|> + j;
426
427 {
428 i = 0;
429 }
430
431 i = 5;
432 }"#;
433
434 let refs = get_all_refs(code);
435 assert_eq!(refs.len(), 5);
436}
437
438#[test]
439fn test_find_all_refs_for_param_inside() {
440 let code = r#"
441 fn foo(i : u32) -> u32 {
442 i<|>
443 }"#;
444
445 let refs = get_all_refs(code);
446 assert_eq!(refs.len(), 2);
447}
448
449#[test]
450fn test_find_all_refs_for_fn_param() {
451 let code = r#"
452 fn foo(i<|> : u32) -> u32 {
453 i
454 }"#;
455
456 let refs = get_all_refs(code);
457 assert_eq!(refs.len(), 2);
458}
459#[test]
460fn test_rename_for_local() {
461 test_rename(
462 r#"
463 fn main() {
464 let mut i = 1;
465 let j = 1;
466 i = i<|> + j;
467
468 {
469 i = 0;
470 }
471
472 i = 5;
473 }"#,
474 "k",
475 r#"
476 fn main() {
477 let mut k = 1;
478 let j = 1;
479 k = k + j;
480
481 {
482 k = 0;
483 }
484
485 k = 5;
486 }"#,
487 );
488}
489
490#[test]
491fn test_rename_for_param_inside() {
492 test_rename(
493 r#"
494 fn foo(i : u32) -> u32 {
495 i<|>
496 }"#,
497 "j",
498 r#"
499 fn foo(j : u32) -> u32 {
500 j
501 }"#,
502 );
503}
504
505#[test]
506fn test_rename_refs_for_fn_param() {
507 test_rename(
508 r#"
509 fn foo(i<|> : u32) -> u32 {
510 i
511 }"#,
512 "new_name",
513 r#"
514 fn foo(new_name : u32) -> u32 {
515 new_name
516 }"#,
517 );
518}
519
520#[test]
521fn test_rename_for_mut_param() {
522 test_rename(
523 r#"
524 fn foo(mut i<|> : u32) -> u32 {
525 i
526 }"#,
527 "new_name",
528 r#"
529 fn foo(mut new_name : u32) -> u32 {
530 new_name
531 }"#,
532 );
533}
534fn test_rename(text: &str, new_name: &str, expected: &str) {
535 let (analysis, position) = single_file_with_position(text);
536 let edits = analysis.rename(position, new_name).unwrap();
537 let mut text_edit_bulder = ra_text_edit::TextEditBuilder::default();
538 let mut file_id: Option<FileId> = None;
539 for edit in edits {
540 file_id = Some(edit.file_id);
541 for atom in edit.edit.as_atoms() {
542 text_edit_bulder.replace(atom.delete, atom.insert.clone());
543 }
544 }
545 let result = text_edit_bulder
546 .finish()
547 .apply(&*analysis.file_text(file_id.unwrap()));
548 assert_eq_text!(expected, &*result);
549}
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 @@
1use test_utils::assert_eq_dbg;
2
3use ra_analysis::mock_analysis::analysis_and_position;
4
5#[test]
6fn test_runnables() {
7 let (analysis, pos) = analysis_and_position(
8 r#"
9 //- /lib.rs
10 <|> //empty
11 fn main() {}
12
13 #[test]
14 fn test_foo() {}
15
16 #[test]
17 #[ignore]
18 fn test_foo() {}
19 "#,
20 );
21 let runnables = analysis.runnables(pos.file_id).unwrap();
22 assert_eq_dbg(
23 r#"[Runnable { range: [1; 21), kind: Bin },
24 Runnable { range: [22; 46), kind: Test { name: "test_foo" } },
25 Runnable { range: [47; 81), kind: Test { name: "test_foo" } }]"#,
26 &runnables,
27 )
28}
29
30#[test]
31fn test_runnables_module() {
32 let (analysis, pos) = analysis_and_position(
33 r#"
34 //- /lib.rs
35 <|> //empty
36 mod test_mod {
37 #[test]
38 fn test_foo1() {}
39 }
40 "#,
41 );
42 let runnables = analysis.runnables(pos.file_id).unwrap();
43 assert_eq_dbg(
44 r#"[Runnable { range: [1; 59), kind: TestMod { path: "test_mod" } },
45 Runnable { range: [28; 57), kind: Test { name: "test_foo1" } }]"#,
46 &runnables,
47 )
48}
49
50#[test]
51fn test_runnables_one_depth_layer_module() {
52 let (analysis, pos) = analysis_and_position(
53 r#"
54 //- /lib.rs
55 <|> //empty
56 mod foo {
57 mod test_mod {
58 #[test]
59 fn test_foo1() {}
60 }
61 }
62 "#,
63 );
64 let runnables = analysis.runnables(pos.file_id).unwrap();
65 assert_eq_dbg(
66 r#"[Runnable { range: [23; 85), kind: TestMod { path: "foo::test_mod" } },
67 Runnable { range: [46; 79), kind: Test { name: "test_foo1" } }]"#,
68 &runnables,
69 )
70}
71
72#[test]
73fn test_runnables_multiple_depth_module() {
74 let (analysis, pos) = analysis_and_position(
75 r#"
76 //- /lib.rs
77 <|> //empty
78 mod foo {
79 mod bar {
80 mod test_mod {
81 #[test]
82 fn test_foo1() {}
83 }
84 }
85 }
86 "#,
87 );
88 let runnables = analysis.runnables(pos.file_id).unwrap();
89 assert_eq_dbg(
90 r#"[Runnable { range: [41; 115), kind: TestMod { path: "foo::bar::test_mod" } },
91 Runnable { range: [68; 105), kind: Test { name: "test_foo1" } }]"#,
92 &runnables,
93 )
94}
95
96#[test]
97fn test_runnables_no_test_function_in_module() {
98 let (analysis, pos) = analysis_and_position(
99 r#"
100 //- /lib.rs
101 <|> //empty
102 mod test_mod {
103 fn foo1() {}
104 }
105 "#,
106 );
107 let runnables = analysis.runnables(pos.file_id).unwrap();
108 assert_eq_dbg(r#"[]"#, &runnables)
109}
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 @@
1use ra_analysis::mock_analysis::single_file_with_range;
2
3#[test]
4fn test_type_of_for_function() {
5 let (analysis, range) = single_file_with_range(
6 "
7 pub fn foo() -> u32 { 1 };
8
9 fn main() {
10 let foo_test = <|>foo()<|>;
11 }
12 ",
13 );
14
15 let type_name = analysis.type_of(range).unwrap().unwrap();
16 assert_eq!("u32", &type_name);
17}
18
19// FIXME: improve type_of to make this work
20#[test]
21fn test_type_of_for_num() {
22 let (analysis, range) = single_file_with_range(
23 r#"
24 fn main() {
25 let foo_test = <|>"foo"<|>;
26 }
27 "#,
28 );
29
30 assert!(analysis.type_of(range).unwrap().is_none());
31}
32// FIXME: improve type_of to make this work
33#[test]
34fn test_type_of_for_binding() {
35 let (analysis, range) = single_file_with_range(
36 "
37 pub fn foo() -> u32 { 1 };
38
39 fn main() {
40 let <|>foo_test<|> = foo();
41 }
42 ",
43 );
44
45 assert!(analysis.type_of(range).unwrap().is_none());
46}
47
48// FIXME: improve type_of to make this work
49#[test]
50fn test_type_of_for_expr_1() {
51 let (analysis, range) = single_file_with_range(
52 "
53 fn main() {
54 let foo = <|>1 + foo_test<|>;
55 }
56 ",
57 );
58
59 let type_name = analysis.type_of(range).unwrap().unwrap();
60 assert_eq!("[unknown]", &type_name);
61}
62
63// FIXME: improve type_of to make this work
64#[test]
65fn test_type_of_for_expr_2() {
66 let (analysis, range) = single_file_with_range(
67 "
68 fn main() {
69 let foo: usize = 1;
70 let bar = <|>1 + foo_test<|>;
71 }
72 ",
73 );
74
75 let type_name = analysis.type_of(range).unwrap().unwrap();
76 assert_eq!("[unknown]", &type_name);
77}