diff options
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | crates/assists/Cargo.toml | 3 | ||||
-rw-r--r-- | crates/assists/src/lib.rs | 10 | ||||
-rw-r--r-- | crates/assists/src/tests.rs | 105 | ||||
-rw-r--r-- | crates/base_db/src/fixture.rs | 11 |
5 files changed, 88 insertions, 42 deletions
diff --git a/Cargo.lock b/Cargo.lock index 050c23970..c3f649325 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -58,6 +58,7 @@ name = "assists" | |||
58 | version = "0.0.0" | 58 | version = "0.0.0" |
59 | dependencies = [ | 59 | dependencies = [ |
60 | "either", | 60 | "either", |
61 | "expect-test", | ||
61 | "hir", | 62 | "hir", |
62 | "ide_db", | 63 | "ide_db", |
63 | "itertools 0.10.0", | 64 | "itertools 0.10.0", |
diff --git a/crates/assists/Cargo.toml b/crates/assists/Cargo.toml index ed8ad666f..c78cb99af 100644 --- a/crates/assists/Cargo.toml +++ b/crates/assists/Cargo.toml | |||
@@ -21,3 +21,6 @@ profile = { path = "../profile", version = "0.0.0" } | |||
21 | ide_db = { path = "../ide_db", version = "0.0.0" } | 21 | ide_db = { path = "../ide_db", version = "0.0.0" } |
22 | hir = { path = "../hir", version = "0.0.0" } | 22 | hir = { path = "../hir", version = "0.0.0" } |
23 | test_utils = { path = "../test_utils", version = "0.0.0" } | 23 | test_utils = { path = "../test_utils", version = "0.0.0" } |
24 | |||
25 | [dev-dependencies] | ||
26 | expect-test = "1.1" | ||
diff --git a/crates/assists/src/lib.rs b/crates/assists/src/lib.rs index 957efa6b9..7067cf8b6 100644 --- a/crates/assists/src/lib.rs +++ b/crates/assists/src/lib.rs | |||
@@ -179,9 +179,7 @@ mod handlers { | |||
179 | early_return::convert_to_guarded_return, | 179 | early_return::convert_to_guarded_return, |
180 | expand_glob_import::expand_glob_import, | 180 | expand_glob_import::expand_glob_import, |
181 | move_module_to_file::move_module_to_file, | 181 | move_module_to_file::move_module_to_file, |
182 | extract_function::extract_function, | ||
183 | extract_struct_from_enum_variant::extract_struct_from_enum_variant, | 182 | extract_struct_from_enum_variant::extract_struct_from_enum_variant, |
184 | extract_variable::extract_variable, | ||
185 | fill_match_arms::fill_match_arms, | 183 | fill_match_arms::fill_match_arms, |
186 | fix_visibility::fix_visibility, | 184 | fix_visibility::fix_visibility, |
187 | flip_binexpr::flip_binexpr, | 185 | flip_binexpr::flip_binexpr, |
@@ -229,12 +227,18 @@ mod handlers { | |||
229 | unmerge_use::unmerge_use, | 227 | unmerge_use::unmerge_use, |
230 | unwrap_block::unwrap_block, | 228 | unwrap_block::unwrap_block, |
231 | wrap_return_type_in_result::wrap_return_type_in_result, | 229 | wrap_return_type_in_result::wrap_return_type_in_result, |
232 | // These are manually sorted for better priorities | 230 | // These are manually sorted for better priorities. By default, |
231 | // priority is determined by the size of the target range (smaller | ||
232 | // target wins). If the ranges are equal, position in this list is | ||
233 | // used as a tie-breaker. | ||
233 | add_missing_impl_members::add_missing_impl_members, | 234 | add_missing_impl_members::add_missing_impl_members, |
234 | add_missing_impl_members::add_missing_default_members, | 235 | add_missing_impl_members::add_missing_default_members, |
235 | // | 236 | // |
236 | replace_string_with_char::replace_string_with_char, | 237 | replace_string_with_char::replace_string_with_char, |
237 | raw_string::make_raw_string, | 238 | raw_string::make_raw_string, |
239 | // | ||
240 | extract_variable::extract_variable, | ||
241 | extract_function::extract_function, | ||
238 | // Are you sure you want to add new assist here, and not to the | 242 | // Are you sure you want to add new assist here, and not to the |
239 | // sorted list above? | 243 | // sorted list above? |
240 | ] | 244 | ] |
diff --git a/crates/assists/src/tests.rs b/crates/assists/src/tests.rs index 720f561a1..384eb7eee 100644 --- a/crates/assists/src/tests.rs +++ b/crates/assists/src/tests.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | mod generated; | 1 | mod generated; |
2 | 2 | ||
3 | use expect_test::expect; | ||
3 | use hir::Semantics; | 4 | use hir::Semantics; |
4 | use ide_db::{ | 5 | use ide_db::{ |
5 | base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt}, | 6 | base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt}, |
@@ -10,11 +11,11 @@ use ide_db::{ | |||
10 | source_change::FileSystemEdit, | 11 | source_change::FileSystemEdit, |
11 | RootDatabase, | 12 | RootDatabase, |
12 | }; | 13 | }; |
14 | use stdx::{format_to, trim_indent}; | ||
13 | use syntax::TextRange; | 15 | use syntax::TextRange; |
14 | use test_utils::{assert_eq_text, extract_offset, extract_range}; | 16 | use test_utils::{assert_eq_text, extract_offset}; |
15 | 17 | ||
16 | use crate::{handlers::Handler, Assist, AssistConfig, AssistContext, AssistKind, Assists}; | 18 | use crate::{handlers::Handler, Assist, AssistConfig, AssistContext, AssistKind, Assists}; |
17 | use stdx::{format_to, trim_indent}; | ||
18 | 19 | ||
19 | pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig { | 20 | pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig { |
20 | snippet_cap: SnippetCap::new(true), | 21 | snippet_cap: SnippetCap::new(true), |
@@ -163,6 +164,22 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label: | |||
163 | }; | 164 | }; |
164 | } | 165 | } |
165 | 166 | ||
167 | fn labels(assists: &[Assist]) -> String { | ||
168 | let mut labels = assists | ||
169 | .iter() | ||
170 | .map(|assist| { | ||
171 | let mut label = match &assist.group { | ||
172 | Some(g) => g.0.clone(), | ||
173 | None => assist.label.to_string(), | ||
174 | }; | ||
175 | label.push('\n'); | ||
176 | label | ||
177 | }) | ||
178 | .collect::<Vec<_>>(); | ||
179 | labels.dedup(); | ||
180 | labels.into_iter().collect::<String>() | ||
181 | } | ||
182 | |||
166 | #[test] | 183 | #[test] |
167 | fn assist_order_field_struct() { | 184 | fn assist_order_field_struct() { |
168 | let before = "struct Foo { $0bar: u32 }"; | 185 | let before = "struct Foo { $0bar: u32 }"; |
@@ -181,66 +198,78 @@ fn assist_order_field_struct() { | |||
181 | 198 | ||
182 | #[test] | 199 | #[test] |
183 | fn assist_order_if_expr() { | 200 | fn assist_order_if_expr() { |
184 | let before = " | 201 | let (db, frange) = RootDatabase::with_range( |
185 | pub fn test_some_range(a: int) -> bool { | 202 | r#" |
186 | if let 2..6 = $05$0 { | 203 | pub fn test_some_range(a: int) -> bool { |
187 | true | 204 | if let 2..6 = $05$0 { |
188 | } else { | 205 | true |
189 | false | 206 | } else { |
190 | } | 207 | false |
191 | }"; | 208 | } |
192 | let (range, before) = extract_range(before); | 209 | } |
193 | let (db, file_id) = with_single_file(&before); | 210 | "#, |
194 | let frange = FileRange { file_id, range }; | 211 | ); |
212 | |||
195 | let assists = Assist::get(&db, &TEST_CONFIG, false, frange); | 213 | let assists = Assist::get(&db, &TEST_CONFIG, false, frange); |
196 | let mut assists = assists.iter(); | 214 | let expected = labels(&assists); |
197 | 215 | ||
198 | assert_eq!(assists.next().expect("expected assist").label, "Extract into function"); | 216 | expect![[r#" |
199 | assert_eq!(assists.next().expect("expected assist").label, "Extract into variable"); | 217 | Convert integer base |
200 | assert_eq!(assists.next().expect("expected assist").label, "Replace with match"); | 218 | Extract into variable |
219 | Extract into function | ||
220 | Replace with match | ||
221 | "#]] | ||
222 | .assert_eq(&expected); | ||
201 | } | 223 | } |
202 | 224 | ||
203 | #[test] | 225 | #[test] |
204 | fn assist_filter_works() { | 226 | fn assist_filter_works() { |
205 | let before = " | 227 | let (db, frange) = RootDatabase::with_range( |
206 | pub fn test_some_range(a: int) -> bool { | 228 | r#" |
207 | if let 2..6 = $05$0 { | 229 | pub fn test_some_range(a: int) -> bool { |
208 | true | 230 | if let 2..6 = $05$0 { |
209 | } else { | 231 | true |
210 | false | 232 | } else { |
211 | } | 233 | false |
212 | }"; | 234 | } |
213 | let (range, before) = extract_range(before); | 235 | } |
214 | let (db, file_id) = with_single_file(&before); | 236 | "#, |
215 | let frange = FileRange { file_id, range }; | 237 | ); |
216 | |||
217 | { | 238 | { |
218 | let mut cfg = TEST_CONFIG; | 239 | let mut cfg = TEST_CONFIG; |
219 | cfg.allowed = Some(vec![AssistKind::Refactor]); | 240 | cfg.allowed = Some(vec![AssistKind::Refactor]); |
220 | 241 | ||
221 | let assists = Assist::get(&db, &cfg, false, frange); | 242 | let assists = Assist::get(&db, &cfg, false, frange); |
222 | let mut assists = assists.iter(); | 243 | let expected = labels(&assists); |
223 | 244 | ||
224 | assert_eq!(assists.next().expect("expected assist").label, "Extract into function"); | 245 | expect![[r#" |
225 | assert_eq!(assists.next().expect("expected assist").label, "Extract into variable"); | 246 | Convert integer base |
226 | assert_eq!(assists.next().expect("expected assist").label, "Replace with match"); | 247 | Extract into variable |
248 | Extract into function | ||
249 | Replace with match | ||
250 | "#]] | ||
251 | .assert_eq(&expected); | ||
227 | } | 252 | } |
228 | 253 | ||
229 | { | 254 | { |
230 | let mut cfg = TEST_CONFIG; | 255 | let mut cfg = TEST_CONFIG; |
231 | cfg.allowed = Some(vec![AssistKind::RefactorExtract]); | 256 | cfg.allowed = Some(vec![AssistKind::RefactorExtract]); |
232 | let assists = Assist::get(&db, &cfg, false, frange); | 257 | let assists = Assist::get(&db, &cfg, false, frange); |
233 | assert_eq!(assists.len(), 2); | 258 | let expected = labels(&assists); |
234 | 259 | ||
235 | let mut assists = assists.iter(); | 260 | expect![[r#" |
236 | assert_eq!(assists.next().expect("expected assist").label, "Extract into function"); | 261 | Extract into variable |
237 | assert_eq!(assists.next().expect("expected assist").label, "Extract into variable"); | 262 | Extract into function |
263 | "#]] | ||
264 | .assert_eq(&expected); | ||
238 | } | 265 | } |
239 | 266 | ||
240 | { | 267 | { |
241 | let mut cfg = TEST_CONFIG; | 268 | let mut cfg = TEST_CONFIG; |
242 | cfg.allowed = Some(vec![AssistKind::QuickFix]); | 269 | cfg.allowed = Some(vec![AssistKind::QuickFix]); |
243 | let assists = Assist::get(&db, &cfg, false, frange); | 270 | let assists = Assist::get(&db, &cfg, false, frange); |
244 | assert!(assists.is_empty(), "All asserts but quickfixes should be filtered out"); | 271 | let expected = labels(&assists); |
272 | |||
273 | expect![[r#""#]].assert_eq(&expected); | ||
245 | } | 274 | } |
246 | } | 275 | } |
diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs index 98acd61b1..5c9824814 100644 --- a/crates/base_db/src/fixture.rs +++ b/crates/base_db/src/fixture.rs | |||
@@ -67,7 +67,7 @@ use test_utils::{ | |||
67 | use vfs::{file_set::FileSet, VfsPath}; | 67 | use vfs::{file_set::FileSet, VfsPath}; |
68 | 68 | ||
69 | use crate::{ | 69 | use crate::{ |
70 | input::CrateName, Change, CrateGraph, CrateId, Edition, Env, FileId, FilePosition, | 70 | input::CrateName, Change, CrateGraph, CrateId, Edition, Env, FileId, FilePosition, FileRange, |
71 | SourceDatabaseExt, SourceRoot, SourceRootId, | 71 | SourceDatabaseExt, SourceRoot, SourceRootId, |
72 | }; | 72 | }; |
73 | 73 | ||
@@ -99,6 +99,15 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static { | |||
99 | (db, FilePosition { file_id, offset }) | 99 | (db, FilePosition { file_id, offset }) |
100 | } | 100 | } |
101 | 101 | ||
102 | fn with_range(ra_fixture: &str) -> (Self, FileRange) { | ||
103 | let (db, file_id, range_or_offset) = Self::with_range_or_offset(ra_fixture); | ||
104 | let range = match range_or_offset { | ||
105 | RangeOrOffset::Range(it) => it, | ||
106 | RangeOrOffset::Offset(_) => panic!(), | ||
107 | }; | ||
108 | (db, FileRange { file_id, range }) | ||
109 | } | ||
110 | |||
102 | fn with_range_or_offset(ra_fixture: &str) -> (Self, FileId, RangeOrOffset) { | 111 | fn with_range_or_offset(ra_fixture: &str) -> (Self, FileId, RangeOrOffset) { |
103 | let fixture = ChangeFixture::parse(ra_fixture); | 112 | let fixture = ChangeFixture::parse(ra_fixture); |
104 | let mut db = Self::default(); | 113 | let mut db = Self::default(); |