Skip to content

Commit 34072d5

Browse files
committed
Rewrite goto implementation tests
1 parent 4484908 commit 34072d5

File tree

3 files changed

+119
-104
lines changed

3 files changed

+119
-104
lines changed

crates/ra_ide/src/display/navigation_target.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,17 @@ impl ToNav for hir::Module {
279279
impl ToNav for hir::ImplDef {
280280
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
281281
let src = self.source(db);
282-
let frange = if let Some(item) = self.is_builtin_derive(db) {
282+
let derive_attr = self.is_builtin_derive(db);
283+
let frange = if let Some(item) = &derive_attr {
283284
original_range(db, item.syntax())
284285
} else {
285286
original_range(db, src.as_ref().map(|it| it.syntax()))
286287
};
287-
let focus_range =
288-
src.value.target_type().map(|ty| original_range(db, src.with_value(ty.syntax())).range);
288+
let focus_range = if derive_attr.is_some() {
289+
None
290+
} else {
291+
src.value.target_type().map(|ty| original_range(db, src.with_value(ty.syntax())).range)
292+
};
289293

290294
NavigationTarget::from_syntax(
291295
frange.file_id,

crates/ra_ide/src/goto_implementation.rs

Lines changed: 105 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -74,135 +74,152 @@ fn impls_for_trait(
7474

7575
#[cfg(test)]
7676
mod tests {
77-
use crate::mock_analysis::analysis_and_position;
77+
use ra_db::FileRange;
7878

79-
fn check_goto(fixture: &str, expected: &[&str]) {
80-
let (analysis, pos) = analysis_and_position(fixture);
79+
use crate::mock_analysis::{analysis_and_position, MockAnalysis};
8180

82-
let mut navs = analysis.goto_implementation(pos).unwrap().unwrap().info;
83-
assert_eq!(navs.len(), expected.len());
84-
navs.sort_by_key(|nav| (nav.file_id(), nav.full_range().start()));
85-
navs.into_iter().enumerate().for_each(|(i, nav)| nav.assert_match(expected[i]));
81+
fn check(ra_fixture: &str) {
82+
let (mock, position) = MockAnalysis::with_files_and_position(ra_fixture);
83+
let annotations = mock.annotations();
84+
let analysis = mock.analysis();
85+
86+
let navs = analysis.goto_implementation(position).unwrap().unwrap().info;
87+
88+
let key = |frange: &FileRange| (frange.file_id, frange.range.start());
89+
90+
let mut expected = annotations
91+
.into_iter()
92+
.map(|(range, data)| {
93+
assert!(data.is_empty());
94+
range
95+
})
96+
.collect::<Vec<_>>();
97+
expected.sort_by_key(key);
98+
99+
let mut actual = navs
100+
.into_iter()
101+
.map(|nav| FileRange { file_id: nav.file_id(), range: nav.range() })
102+
.collect::<Vec<_>>();
103+
actual.sort_by_key(key);
104+
105+
assert_eq!(expected, actual);
86106
}
87107

88108
#[test]
89109
fn goto_implementation_works() {
90-
check_goto(
91-
"
92-
//- /lib.rs
93-
struct Foo<|>;
94-
impl Foo {}
95-
",
96-
&["impl IMPL_DEF FileId(1) 12..23"],
110+
check(
111+
r#"
112+
struct Foo<|>;
113+
impl Foo {}
114+
//^^^
115+
"#,
97116
);
98117
}
99118

100119
#[test]
101120
fn goto_implementation_works_multiple_blocks() {
102-
check_goto(
103-
"
104-
//- /lib.rs
105-
struct Foo<|>;
106-
impl Foo {}
107-
impl Foo {}
108-
",
109-
&["impl IMPL_DEF FileId(1) 12..23", "impl IMPL_DEF FileId(1) 24..35"],
121+
check(
122+
r#"
123+
struct Foo<|>;
124+
impl Foo {}
125+
//^^^
126+
impl Foo {}
127+
//^^^
128+
"#,
110129
);
111130
}
112131

113132
#[test]
114133
fn goto_implementation_works_multiple_mods() {
115-
check_goto(
116-
"
117-
//- /lib.rs
118-
struct Foo<|>;
119-
mod a {
120-
impl super::Foo {}
121-
}
122-
mod b {
123-
impl super::Foo {}
124-
}
125-
",
126-
&["impl IMPL_DEF FileId(1) 24..42", "impl IMPL_DEF FileId(1) 57..75"],
134+
check(
135+
r#"
136+
struct Foo<|>;
137+
mod a {
138+
impl super::Foo {}
139+
//^^^^^^^^^^
140+
}
141+
mod b {
142+
impl super::Foo {}
143+
//^^^^^^^^^^
144+
}
145+
"#,
127146
);
128147
}
129148

130149
#[test]
131150
fn goto_implementation_works_multiple_files() {
132-
check_goto(
133-
"
134-
//- /lib.rs
135-
struct Foo<|>;
136-
mod a;
137-
mod b;
138-
//- /a.rs
139-
impl crate::Foo {}
140-
//- /b.rs
141-
impl crate::Foo {}
142-
",
143-
&["impl IMPL_DEF FileId(2) 0..18", "impl IMPL_DEF FileId(3) 0..18"],
151+
check(
152+
r#"
153+
//- /lib.rs
154+
struct Foo<|>;
155+
mod a;
156+
mod b;
157+
//- /a.rs
158+
impl crate::Foo {}
159+
//^^^^^^^^^^
160+
//- /b.rs
161+
impl crate::Foo {}
162+
//^^^^^^^^^^
163+
"#,
144164
);
145165
}
146166

147167
#[test]
148168
fn goto_implementation_for_trait() {
149-
check_goto(
150-
"
151-
//- /lib.rs
152-
trait T<|> {}
153-
struct Foo;
154-
impl T for Foo {}
155-
",
156-
&["impl IMPL_DEF FileId(1) 23..40"],
169+
check(
170+
r#"
171+
trait T<|> {}
172+
struct Foo;
173+
impl T for Foo {}
174+
//^^^
175+
"#,
157176
);
158177
}
159178

160179
#[test]
161180
fn goto_implementation_for_trait_multiple_files() {
162-
check_goto(
163-
"
164-
//- /lib.rs
165-
trait T<|> {};
166-
struct Foo;
167-
mod a;
168-
mod b;
169-
//- /a.rs
170-
impl crate::T for crate::Foo {}
171-
//- /b.rs
172-
impl crate::T for crate::Foo {}
173-
",
174-
&["impl IMPL_DEF FileId(2) 0..31", "impl IMPL_DEF FileId(3) 0..31"],
181+
check(
182+
r#"
183+
//- /lib.rs
184+
trait T<|> {};
185+
struct Foo;
186+
mod a;
187+
mod b;
188+
//- /a.rs
189+
impl crate::T for crate::Foo {}
190+
//^^^^^^^^^^
191+
//- /b.rs
192+
impl crate::T for crate::Foo {}
193+
//^^^^^^^^^^
194+
"#,
175195
);
176196
}
177197

178198
#[test]
179199
fn goto_implementation_all_impls() {
180-
check_goto(
181-
"
182-
//- /lib.rs
183-
trait T {}
184-
struct Foo<|>;
185-
impl Foo {}
186-
impl T for Foo {}
187-
impl T for &Foo {}
188-
",
189-
&[
190-
"impl IMPL_DEF FileId(1) 23..34",
191-
"impl IMPL_DEF FileId(1) 35..52",
192-
"impl IMPL_DEF FileId(1) 53..71",
193-
],
200+
check(
201+
r#"
202+
//- /lib.rs
203+
trait T {}
204+
struct Foo<|>;
205+
impl Foo {}
206+
//^^^
207+
impl T for Foo {}
208+
//^^^
209+
impl T for &Foo {}
210+
//^^^^
211+
"#,
194212
);
195213
}
196214

197215
#[test]
198216
fn goto_implementation_to_builtin_derive() {
199-
check_goto(
200-
"
201-
//- /lib.rs
202-
#[derive(Copy)]
203-
struct Foo<|>;
204-
",
205-
&["impl IMPL_DEF FileId(1) 0..15"],
217+
check(
218+
r#"
219+
#[derive(Copy)]
220+
//^^^^^^^^^^^^^^^
221+
struct Foo<|>;
222+
"#,
206223
);
207224
}
208225
}

crates/ra_ide/src/mock_analysis.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ use test_utils::{
1010
use crate::{
1111
Analysis, AnalysisChange, AnalysisHost, CrateGraph, Edition, FileId, FilePosition, FileRange,
1212
};
13-
use ra_syntax::TextRange;
14-
use rustc_hash::FxHashMap;
1513

1614
/// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis
1715
/// from a set of in-memory files.
@@ -81,27 +79,23 @@ impl MockAnalysis {
8179
.expect("no file in this mock");
8280
FileId(idx as u32 + 1)
8381
}
84-
pub fn annotations(&self) -> FxHashMap<FileId, Vec<(TextRange, String)>> {
82+
pub fn annotations(&self) -> Vec<(FileRange, String)> {
8583
self.files
8684
.iter()
8785
.enumerate()
88-
.filter_map(|(idx, fixture)| {
86+
.flat_map(|(idx, fixture)| {
8987
let file_id = FileId(idx as u32 + 1);
9088
let annotations = extract_annotations(&fixture.text);
91-
if annotations.is_empty() {
92-
return None;
93-
}
94-
Some((file_id, annotations))
89+
annotations
90+
.into_iter()
91+
.map(move |(range, data)| (FileRange { file_id, range }, data))
9592
})
9693
.collect()
9794
}
9895
pub fn annotation(&self) -> (FileRange, String) {
99-
let all = self.annotations();
96+
let mut all = self.annotations();
10097
assert_eq!(all.len(), 1);
101-
let (file_id, mut for_file) = all.into_iter().next().unwrap();
102-
assert_eq!(for_file.len(), 1);
103-
let (range, data) = for_file.pop().unwrap();
104-
(FileRange { file_id, range}, data)
98+
all.pop().unwrap()
10599
}
106100
pub fn analysis_host(self) -> AnalysisHost {
107101
let mut host = AnalysisHost::default();

0 commit comments

Comments
 (0)