diff options
-rw-r--r-- | crates/ra_ide_api/src/diagnostics.rs | 91 |
1 files changed, 55 insertions, 36 deletions
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index 4e1f47db6..1a4882824 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs | |||
@@ -184,6 +184,7 @@ fn check_struct_shorthand_initialization( | |||
184 | #[cfg(test)] | 184 | #[cfg(test)] |
185 | mod tests { | 185 | mod tests { |
186 | use insta::assert_debug_snapshot_matches; | 186 | use insta::assert_debug_snapshot_matches; |
187 | use join_to_string::join; | ||
187 | use ra_syntax::SourceFile; | 188 | use ra_syntax::SourceFile; |
188 | use test_utils::assert_eq_text; | 189 | use test_utils::assert_eq_text; |
189 | 190 | ||
@@ -228,9 +229,30 @@ mod tests { | |||
228 | let edit = fix.source_file_edits.pop().unwrap().edit; | 229 | let edit = fix.source_file_edits.pop().unwrap().edit; |
229 | let target_file_contents = analysis.file_text(file_position.file_id).unwrap(); | 230 | let target_file_contents = analysis.file_text(file_position.file_id).unwrap(); |
230 | let actual = edit.apply(&target_file_contents); | 231 | let actual = edit.apply(&target_file_contents); |
231 | assert_eq_text!(after, &actual); | 232 | |
233 | // Strip indent and empty lines from `after`, to match the behaviour of | ||
234 | // `parse_fixture` called from `analysis_and_position`. | ||
235 | let margin = fixture | ||
236 | .lines() | ||
237 | .filter(|it| it.trim_start().starts_with("//-")) | ||
238 | .map(|it| it.len() - it.trim_start().len()) | ||
239 | .next() | ||
240 | .expect("empty fixture"); | ||
241 | let after = join(after.lines().filter_map(|line| { | ||
242 | if line.len() > margin { | ||
243 | Some(&line[margin..]) | ||
244 | } else { | ||
245 | None | ||
246 | } | ||
247 | })) | ||
248 | .separator("\n") | ||
249 | .suffix("\n") | ||
250 | .to_string(); | ||
251 | |||
252 | assert_eq_text!(&after, &actual); | ||
232 | assert!( | 253 | assert!( |
233 | diagnostic.range.start() <= file_position.offset && diagnostic.range.end() >= file_position.offset, | 254 | diagnostic.range.start() <= file_position.offset |
255 | && diagnostic.range.end() >= file_position.offset, | ||
234 | "diagnostic range {} does not touch cursor position {}", | 256 | "diagnostic range {} does not touch cursor position {}", |
235 | diagnostic.range, | 257 | diagnostic.range, |
236 | file_position.offset | 258 | file_position.offset |
@@ -281,17 +303,16 @@ mod tests { | |||
281 | pub enum Result<T, E> { Ok(T), Err(E) } | 303 | pub enum Result<T, E> { Ok(T), Err(E) } |
282 | } | 304 | } |
283 | "#; | 305 | "#; |
284 | // The formatting here is a bit odd due to how the parse_fixture function works in test_utils - | 306 | let after = r#" |
285 | // it strips empty lines and leading whitespace. The important part of this test is that the final | 307 | use std::{string::String, result::Result::{self, Ok, Err}}; |
286 | // `x / y` expr is now wrapped in `Ok(..)` | 308 | |
287 | let after = r#"use std::{string::String, result::Result::{self, Ok, Err}}; | 309 | fn div(x: i32, y: i32) -> Result<i32, String> { |
288 | fn div(x: i32, y: i32) -> Result<i32, String> { | 310 | if y == 0 { |
289 | if y == 0 { | 311 | return Err("div by zero".into()); |
290 | return Err("div by zero".into()); | 312 | } |
291 | } | 313 | Ok(x / y) |
292 | Ok(x / y) | 314 | } |
293 | } | 315 | "#; |
294 | "#; | ||
295 | check_apply_diagnostic_fix_from_position(before, after); | 316 | check_apply_diagnostic_fix_from_position(before, after); |
296 | } | 317 | } |
297 | 318 | ||
@@ -313,17 +334,16 @@ fn div(x: i32, y: i32) -> Result<i32, String> { | |||
313 | pub enum Result<T, E> { Ok(T), Err(E) } | 334 | pub enum Result<T, E> { Ok(T), Err(E) } |
314 | } | 335 | } |
315 | "#; | 336 | "#; |
316 | // The formatting here is a bit odd due to how the parse_fixture function works in test_utils - | 337 | let after = r#" |
317 | // it strips empty lines and leading whitespace. The important part of this test is that the final | 338 | use std::result::Result::{self, Ok, Err}; |
318 | // expr is now wrapped in `Ok(..)` | 339 | |
319 | let after = r#"use std::result::Result::{self, Ok, Err}; | 340 | fn div<T>(x: T) -> Result<T, i32> { |
320 | fn div<T>(x: T) -> Result<T, i32> { | 341 | if x == 0 { |
321 | if x == 0 { | 342 | return Err(7); |
322 | return Err(7); | 343 | } |
323 | } | 344 | Ok(x) |
324 | Ok(x) | 345 | } |
325 | } | 346 | "#; |
326 | "#; | ||
327 | check_apply_diagnostic_fix_from_position(before, after); | 347 | check_apply_diagnostic_fix_from_position(before, after); |
328 | } | 348 | } |
329 | 349 | ||
@@ -350,18 +370,17 @@ fn div<T>(x: T) -> Result<T, i32> { | |||
350 | pub enum Result<T, E> { Ok(T), Err(E) } | 370 | pub enum Result<T, E> { Ok(T), Err(E) } |
351 | } | 371 | } |
352 | "#; | 372 | "#; |
353 | // The formatting here is a bit odd due to how the parse_fixture function works in test_utils - | 373 | let after = r#" |
354 | // it strips empty lines and leading whitespace. The important part of this test is that the final | 374 | use std::{string::String, result::Result::{self, Ok, Err}}; |
355 | // `x / y` expr is now wrapped in `Ok(..)` | 375 | |
356 | let after = r#"use std::{string::String, result::Result::{self, Ok, Err}}; | 376 | type MyResult<T> = Result<T, String>; |
357 | type MyResult<T> = Result<T, String>; | 377 | fn div(x: i32, y: i32) -> MyResult<i32> { |
358 | fn div(x: i32, y: i32) -> MyResult<i32> { | 378 | if y == 0 { |
359 | if y == 0 { | 379 | return Err("div by zero".into()); |
360 | return Err("div by zero".into()); | 380 | } |
361 | } | 381 | Ok(x / y) |
362 | Ok(x / y) | 382 | } |
363 | } | 383 | "#; |
364 | "#; | ||
365 | check_apply_diagnostic_fix_from_position(before, after); | 384 | check_apply_diagnostic_fix_from_position(before, after); |
366 | } | 385 | } |
367 | 386 | ||