aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_ide_api/src/diagnostics.rs49
-rw-r--r--crates/ra_ide_api/src/mock_analysis.rs17
2 files changed, 31 insertions, 35 deletions
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs
index 94424dc16..4e1f47db6 100644
--- a/crates/ra_ide_api/src/diagnostics.rs
+++ b/crates/ra_ide_api/src/diagnostics.rs
@@ -187,7 +187,7 @@ mod tests {
187 use ra_syntax::SourceFile; 187 use ra_syntax::SourceFile;
188 use test_utils::assert_eq_text; 188 use test_utils::assert_eq_text;
189 189
190 use crate::mock_analysis::{fixture_with_target_file, single_file}; 190 use crate::mock_analysis::{analysis_and_position, single_file};
191 191
192 use super::*; 192 use super::*;
193 193
@@ -216,14 +216,25 @@ mod tests {
216 assert_eq_text!(after, &actual); 216 assert_eq_text!(after, &actual);
217 } 217 }
218 218
219 fn check_apply_diagnostic_fix_for_target_file(target_file: &str, fixture: &str, after: &str) { 219 /// Takes a multi-file input fixture with annotated cursor positions,
220 let (analysis, file_id, target_file_contents) = 220 /// and checks that:
221 fixture_with_target_file(fixture, target_file); 221 /// * a diagnostic is produced
222 let diagnostic = analysis.diagnostics(file_id).unwrap().pop().unwrap(); 222 /// * this diagnostic touches the input cursor position
223 /// * that the contents of the file containing the cursor match `after` after the diagnostic fix is applied
224 fn check_apply_diagnostic_fix_from_position(fixture: &str, after: &str) {
225 let (analysis, file_position) = analysis_and_position(fixture);
226 let diagnostic = analysis.diagnostics(file_position.file_id).unwrap().pop().unwrap();
223 let mut fix = diagnostic.fix.unwrap(); 227 let mut fix = diagnostic.fix.unwrap();
224 let edit = fix.source_file_edits.pop().unwrap().edit; 228 let edit = fix.source_file_edits.pop().unwrap().edit;
229 let target_file_contents = analysis.file_text(file_position.file_id).unwrap();
225 let actual = edit.apply(&target_file_contents); 230 let actual = edit.apply(&target_file_contents);
226 assert_eq_text!(after, &actual); 231 assert_eq_text!(after, &actual);
232 assert!(
233 diagnostic.range.start() <= file_position.offset && diagnostic.range.end() >= file_position.offset,
234 "diagnostic range {} does not touch cursor position {}",
235 diagnostic.range,
236 file_position.offset
237 );
227 } 238 }
228 239
229 fn check_apply_diagnostic_fix(before: &str, after: &str) { 240 fn check_apply_diagnostic_fix(before: &str, after: &str) {
@@ -235,9 +246,11 @@ mod tests {
235 assert_eq_text!(after, &actual); 246 assert_eq_text!(after, &actual);
236 } 247 }
237 248
238 fn check_no_diagnostic_for_target_file(target_file: &str, fixture: &str) { 249 /// Takes a multi-file input fixture with annotated cursor position and checks that no diagnostics
239 let (analysis, file_id, _) = fixture_with_target_file(fixture, target_file); 250 /// apply to the file containing the cursor.
240 let diagnostics = analysis.diagnostics(file_id).unwrap(); 251 fn check_no_diagnostic_for_target_file(fixture: &str) {
252 let (analysis, file_position) = analysis_and_position(fixture);
253 let diagnostics = analysis.diagnostics(file_position.file_id).unwrap();
241 assert_eq!(diagnostics.len(), 0); 254 assert_eq!(diagnostics.len(), 0);
242 } 255 }
243 256
@@ -257,7 +270,7 @@ mod tests {
257 if y == 0 { 270 if y == 0 {
258 return Err("div by zero".into()); 271 return Err("div by zero".into());
259 } 272 }
260 x / y 273 x / y<|>
261 } 274 }
262 275
263 //- /std/lib.rs 276 //- /std/lib.rs
@@ -279,7 +292,7 @@ fn div(x: i32, y: i32) -> Result<i32, String> {
279 Ok(x / y) 292 Ok(x / y)
280} 293}
281"#; 294"#;
282 check_apply_diagnostic_fix_for_target_file("/main.rs", before, after); 295 check_apply_diagnostic_fix_from_position(before, after);
283 } 296 }
284 297
285 #[test] 298 #[test]
@@ -292,7 +305,7 @@ fn div(x: i32, y: i32) -> Result<i32, String> {
292 if x == 0 { 305 if x == 0 {
293 return Err(7); 306 return Err(7);
294 } 307 }
295 x 308 <|>x
296 } 309 }
297 310
298 //- /std/lib.rs 311 //- /std/lib.rs
@@ -311,7 +324,7 @@ fn div<T>(x: T) -> Result<T, i32> {
311 Ok(x) 324 Ok(x)
312} 325}
313"#; 326"#;
314 check_apply_diagnostic_fix_for_target_file("/main.rs", before, after); 327 check_apply_diagnostic_fix_from_position(before, after);
315 } 328 }
316 329
317 #[test] 330 #[test]
@@ -326,7 +339,7 @@ fn div<T>(x: T) -> Result<T, i32> {
326 if y == 0 { 339 if y == 0 {
327 return Err("div by zero".into()); 340 return Err("div by zero".into());
328 } 341 }
329 x / y 342 x <|>/ y
330 } 343 }
331 344
332 //- /std/lib.rs 345 //- /std/lib.rs
@@ -349,7 +362,7 @@ fn div(x: i32, y: i32) -> MyResult<i32> {
349 Ok(x / y) 362 Ok(x / y)
350} 363}
351"#; 364"#;
352 check_apply_diagnostic_fix_for_target_file("/main.rs", before, after); 365 check_apply_diagnostic_fix_from_position(before, after);
353 } 366 }
354 367
355 #[test] 368 #[test]
@@ -359,7 +372,7 @@ fn div(x: i32, y: i32) -> MyResult<i32> {
359 use std::{string::String, result::Result::{self, Ok, Err}}; 372 use std::{string::String, result::Result::{self, Ok, Err}};
360 373
361 fn foo() -> Result<String, i32> { 374 fn foo() -> Result<String, i32> {
362 0 375 0<|>
363 } 376 }
364 377
365 //- /std/lib.rs 378 //- /std/lib.rs
@@ -370,7 +383,7 @@ fn div(x: i32, y: i32) -> MyResult<i32> {
370 pub enum Result<T, E> { Ok(T), Err(E) } 383 pub enum Result<T, E> { Ok(T), Err(E) }
371 } 384 }
372 "#; 385 "#;
373 check_no_diagnostic_for_target_file("/main.rs", content); 386 check_no_diagnostic_for_target_file(content);
374 } 387 }
375 388
376 #[test] 389 #[test]
@@ -385,7 +398,7 @@ fn div(x: i32, y: i32) -> MyResult<i32> {
385 } 398 }
386 399
387 fn foo() -> SomeOtherEnum { 400 fn foo() -> SomeOtherEnum {
388 0 401 0<|>
389 } 402 }
390 403
391 //- /std/lib.rs 404 //- /std/lib.rs
@@ -396,7 +409,7 @@ fn div(x: i32, y: i32) -> MyResult<i32> {
396 pub enum Result<T, E> { Ok(T), Err(E) } 409 pub enum Result<T, E> { Ok(T), Err(E) }
397 } 410 }
398 "#; 411 "#;
399 check_no_diagnostic_for_target_file("/main.rs", content); 412 check_no_diagnostic_for_target_file(content);
400 } 413 }
401 414
402 #[test] 415 #[test]
diff --git a/crates/ra_ide_api/src/mock_analysis.rs b/crates/ra_ide_api/src/mock_analysis.rs
index 0eaf5d15a..132f6f875 100644
--- a/crates/ra_ide_api/src/mock_analysis.rs
+++ b/crates/ra_ide_api/src/mock_analysis.rs
@@ -80,15 +80,6 @@ impl MockAnalysis {
80 .expect("no file in this mock"); 80 .expect("no file in this mock");
81 FileId(idx as u32 + 1) 81 FileId(idx as u32 + 1)
82 } 82 }
83 pub fn id_and_contents_of(&self, path: &str) -> (FileId, String) {
84 let (idx, contents) = self
85 .files
86 .iter()
87 .enumerate()
88 .find(|(_, (p, _text))| path == p)
89 .expect("no file in this mock");
90 (FileId(idx as u32 + 1), contents.1.to_string())
91 }
92 pub fn analysis_host(self) -> AnalysisHost { 83 pub fn analysis_host(self) -> AnalysisHost {
93 let mut host = AnalysisHost::default(); 84 let mut host = AnalysisHost::default();
94 let source_root = SourceRootId(0); 85 let source_root = SourceRootId(0);
@@ -133,14 +124,6 @@ pub fn single_file(code: &str) -> (Analysis, FileId) {
133 (mock.analysis(), file_id) 124 (mock.analysis(), file_id)
134} 125}
135 126
136/// Creates analysis from a fixture with multiple files
137/// and returns the file id and contents of the target file.
138pub fn fixture_with_target_file(fixture: &str, target_file: &str) -> (Analysis, FileId, String) {
139 let mock = MockAnalysis::with_files(fixture);
140 let (target_file_id, target_file_contents) = mock.id_and_contents_of(target_file);
141 (mock.analysis(), target_file_id, target_file_contents)
142}
143
144/// Creates analysis for a single file, returns position marked with <|>. 127/// Creates analysis for a single file, returns position marked with <|>.
145pub fn single_file_with_position(code: &str) -> (Analysis, FilePosition) { 128pub fn single_file_with_position(code: &str) -> (Analysis, FilePosition) {
146 let mut mock = MockAnalysis::new(); 129 let mut mock = MockAnalysis::new();