diff options
-rw-r--r-- | crates/ra_ide_api/src/diagnostics.rs | 49 | ||||
-rw-r--r-- | crates/ra_ide_api/src/mock_analysis.rs | 17 |
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. | ||
138 | pub 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 <|>. |
145 | pub fn single_file_with_position(code: &str) -> (Analysis, FilePosition) { | 128 | pub fn single_file_with_position(code: &str) -> (Analysis, FilePosition) { |
146 | let mut mock = MockAnalysis::new(); | 129 | let mut mock = MockAnalysis::new(); |