diff options
Diffstat (limited to 'crates/ra_ide_api/src/diagnostics.rs')
-rw-r--r-- | crates/ra_ide_api/src/diagnostics.rs | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index be5197767..84d2b7fb1 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::single_file; | 190 | use crate::mock_analysis::{fixture_with_target_file, single_file}; |
191 | 191 | ||
192 | use super::*; | 192 | use super::*; |
193 | 193 | ||
@@ -216,6 +216,15 @@ 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) { | ||
220 | let (analysis, file_id, target_file_contents) = fixture_with_target_file(fixture, target_file); | ||
221 | let diagnostic = analysis.diagnostics(file_id).unwrap().pop().unwrap(); | ||
222 | let mut fix = diagnostic.fix.unwrap(); | ||
223 | let edit = fix.source_file_edits.pop().unwrap().edit; | ||
224 | let actual = edit.apply(&target_file_contents); | ||
225 | assert_eq_text!(after, &actual); | ||
226 | } | ||
227 | |||
219 | fn check_apply_diagnostic_fix(before: &str, after: &str) { | 228 | fn check_apply_diagnostic_fix(before: &str, after: &str) { |
220 | let (analysis, file_id) = single_file(before); | 229 | let (analysis, file_id) = single_file(before); |
221 | let diagnostic = analysis.diagnostics(file_id).unwrap().pop().unwrap(); | 230 | let diagnostic = analysis.diagnostics(file_id).unwrap().pop().unwrap(); |
@@ -225,6 +234,12 @@ mod tests { | |||
225 | assert_eq_text!(after, &actual); | 234 | assert_eq_text!(after, &actual); |
226 | } | 235 | } |
227 | 236 | ||
237 | fn check_no_diagnostic_for_target_file(target_file: &str, fixture: &str) { | ||
238 | let (analysis, file_id, _) = fixture_with_target_file(fixture, target_file); | ||
239 | let diagnostics = analysis.diagnostics(file_id).unwrap(); | ||
240 | assert_eq!(diagnostics.len(), 0); | ||
241 | } | ||
242 | |||
228 | fn check_no_diagnostic(content: &str) { | 243 | fn check_no_diagnostic(content: &str) { |
229 | let (analysis, file_id) = single_file(content); | 244 | let (analysis, file_id) = single_file(content); |
230 | let diagnostics = analysis.diagnostics(file_id).unwrap(); | 245 | let diagnostics = analysis.diagnostics(file_id).unwrap(); |
@@ -234,8 +249,8 @@ mod tests { | |||
234 | #[test] | 249 | #[test] |
235 | fn test_wrap_return_type() { | 250 | fn test_wrap_return_type() { |
236 | let before = r#" | 251 | let before = r#" |
237 | enum Result<T, E> { Ok(T), Err(E) } | 252 | //- /main.rs |
238 | struct String { } | 253 | use std::{string::String, result::Result::{self, Ok, Err}}; |
239 | 254 | ||
240 | fn div(x: i32, y: i32) -> Result<i32, String> { | 255 | fn div(x: i32, y: i32) -> Result<i32, String> { |
241 | if y == 0 { | 256 | if y == 0 { |
@@ -243,29 +258,48 @@ mod tests { | |||
243 | } | 258 | } |
244 | x / y | 259 | x / y |
245 | } | 260 | } |
246 | "#; | ||
247 | let after = r#" | ||
248 | enum Result<T, E> { Ok(T), Err(E) } | ||
249 | struct String { } | ||
250 | 261 | ||
251 | fn div(x: i32, y: i32) -> Result<i32, String> { | 262 | //- /std/lib.rs |
252 | if y == 0 { | 263 | pub mod string { |
253 | return Err("div by zero".into()); | 264 | pub struct String { } |
254 | } | 265 | } |
255 | Ok(x / y) | 266 | pub mod result { |
267 | pub enum Result<T, E> { Ok(T), Err(E) } | ||
256 | } | 268 | } |
257 | "#; | 269 | "#; |
258 | check_apply_diagnostic_fix(before, after); | 270 | // The formatting here is a bit odd due to how the parse_fixture function works in test_utils - |
271 | // it strips empty lines and leading whitespace. The important part of this test is that the final | ||
272 | // `x / y` expr is now wrapped in `Ok(..)` | ||
273 | let after = r#"use std::{string::String, result::Result::{self, Ok, Err}}; | ||
274 | fn div(x: i32, y: i32) -> Result<i32, String> { | ||
275 | if y == 0 { | ||
276 | return Err("div by zero".into()); | ||
277 | } | ||
278 | Ok(x / y) | ||
279 | } | ||
280 | "#; | ||
281 | check_apply_diagnostic_fix_for_target_file("/main.rs", before, after); | ||
259 | } | 282 | } |
260 | 283 | ||
261 | #[test] | 284 | #[test] |
262 | fn test_wrap_return_type_not_applicable() { | 285 | fn test_wrap_return_type_not_applicable() { |
263 | let content = r#" | 286 | let content = r#" |
287 | //- /main.rs | ||
288 | use std::{string::String, result::Result::{self, Ok, Err}}; | ||
289 | |||
264 | fn foo() -> Result<String, i32> { | 290 | fn foo() -> Result<String, i32> { |
265 | 0 | 291 | 0 |
266 | } | 292 | } |
293 | |||
294 | //- /std/lib.rs | ||
295 | pub mod string { | ||
296 | pub struct String { } | ||
297 | } | ||
298 | pub mod result { | ||
299 | pub enum Result<T, E> { Ok(T), Err(E) } | ||
300 | } | ||
267 | "#; | 301 | "#; |
268 | check_no_diagnostic(content); | 302 | check_no_diagnostic_for_target_file("/main.rs", content); |
269 | } | 303 | } |
270 | 304 | ||
271 | #[test] | 305 | #[test] |