Skip to content

Commit d025016

Browse files
theotherphilmatklad
authored andcommitted
Mock std String and Result types in tests for ok-wrapping diagnostic
1 parent bacb938 commit d025016

File tree

3 files changed

+65
-16
lines changed

3 files changed

+65
-16
lines changed

crates/ra_hir/src/expr/validation.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,10 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
106106
Some(m) => m,
107107
None => return,
108108
};
109-
110109
let ret = match &mismatch.expected {
111110
Ty::Apply(t) => t,
112111
_ => return,
113112
};
114-
115113
let ret_enum = match ret.ctor {
116114
TypeCtor::Adt(AdtDef::Enum(e)) => e,
117115
_ => return,

crates/ra_ide_api/src/diagnostics.rs

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ mod tests {
187187
use ra_syntax::SourceFile;
188188
use test_utils::assert_eq_text;
189189

190-
use crate::mock_analysis::single_file;
190+
use crate::mock_analysis::{fixture_with_target_file, single_file};
191191

192192
use super::*;
193193

@@ -216,6 +216,15 @@ mod tests {
216216
assert_eq_text!(after, &actual);
217217
}
218218

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+
219228
fn check_apply_diagnostic_fix(before: &str, after: &str) {
220229
let (analysis, file_id) = single_file(before);
221230
let diagnostic = analysis.diagnostics(file_id).unwrap().pop().unwrap();
@@ -225,6 +234,12 @@ mod tests {
225234
assert_eq_text!(after, &actual);
226235
}
227236

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+
228243
fn check_no_diagnostic(content: &str) {
229244
let (analysis, file_id) = single_file(content);
230245
let diagnostics = analysis.diagnostics(file_id).unwrap();
@@ -234,38 +249,57 @@ mod tests {
234249
#[test]
235250
fn test_wrap_return_type() {
236251
let before = r#"
237-
enum Result<T, E> { Ok(T), Err(E) }
238-
struct String { }
252+
//- /main.rs
253+
use std::{string::String, result::Result::{self, Ok, Err}};
239254
240255
fn div(x: i32, y: i32) -> Result<i32, String> {
241256
if y == 0 {
242257
return Err("div by zero".into());
243258
}
244259
x / y
245260
}
246-
"#;
247-
let after = r#"
248-
enum Result<T, E> { Ok(T), Err(E) }
249-
struct String { }
250261
251-
fn div(x: i32, y: i32) -> Result<i32, String> {
252-
if y == 0 {
253-
return Err("div by zero".into());
254-
}
255-
Ok(x / y)
262+
//- /std/lib.rs
263+
pub mod string {
264+
pub struct String { }
265+
}
266+
pub mod result {
267+
pub enum Result<T, E> { Ok(T), Err(E) }
256268
}
257269
"#;
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);
259282
}
260283

261284
#[test]
262285
fn test_wrap_return_type_not_applicable() {
263286
let content = r#"
287+
//- /main.rs
288+
use std::{string::String, result::Result::{self, Ok, Err}};
289+
264290
fn foo() -> Result<String, i32> {
265291
0
266292
}
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+
}
267301
"#;
268-
check_no_diagnostic(content);
302+
check_no_diagnostic_for_target_file("/main.rs", content);
269303
}
270304

271305
#[test]

crates/ra_ide_api/src/mock_analysis.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@ impl MockAnalysis {
8080
.expect("no file in this mock");
8181
FileId(idx as u32 + 1)
8282
}
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+
}
8392
pub fn analysis_host(self) -> AnalysisHost {
8493
let mut host = AnalysisHost::default();
8594
let source_root = SourceRootId(0);
@@ -124,6 +133,14 @@ pub fn single_file(code: &str) -> (Analysis, FileId) {
124133
(mock.analysis(), file_id)
125134
}
126135

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+
127144
/// Creates analysis for a single file, returns position marked with <|>.
128145
pub fn single_file_with_position(code: &str) -> (Analysis, FilePosition) {
129146
let mut mock = MockAnalysis::new();

0 commit comments

Comments
 (0)