diff options
author | Aleksey Kladov <[email protected]> | 2020-05-06 09:16:55 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-05-06 09:16:55 +0100 |
commit | 25e6bbde01d4a9cd08fa79db5b8b7da6bbf1a623 (patch) | |
tree | b47a0ba06886a45d9a07a594c14a04e019b5e2d8 /crates/ra_assists/src/lib.rs | |
parent | 30eb458b4fa8adcecd8cbf731bd1cfa9a7a8b88b (diff) |
Merge assits::test_helpers and tests
Diffstat (limited to 'crates/ra_assists/src/lib.rs')
-rw-r--r-- | crates/ra_assists/src/lib.rs | 149 |
1 files changed, 2 insertions, 147 deletions
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index 0f94f5ee8..b84d60c77 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs | |||
@@ -14,6 +14,8 @@ mod assist_ctx; | |||
14 | mod marks; | 14 | mod marks; |
15 | #[cfg(test)] | 15 | #[cfg(test)] |
16 | mod doc_tests; | 16 | mod doc_tests; |
17 | #[cfg(test)] | ||
18 | mod tests; | ||
17 | pub mod utils; | 19 | pub mod utils; |
18 | pub mod ast_transform; | 20 | pub mod ast_transform; |
19 | 21 | ||
@@ -194,150 +196,3 @@ mod handlers { | |||
194 | ] | 196 | ] |
195 | } | 197 | } |
196 | } | 198 | } |
197 | |||
198 | #[cfg(test)] | ||
199 | mod helpers { | ||
200 | use std::sync::Arc; | ||
201 | |||
202 | use hir::Semantics; | ||
203 | use ra_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt}; | ||
204 | use ra_ide_db::{symbol_index::SymbolsDatabase, RootDatabase}; | ||
205 | use test_utils::{add_cursor, assert_eq_text, extract_range_or_offset, RangeOrOffset}; | ||
206 | |||
207 | use crate::{handlers::Handler, AssistCtx, AssistFile}; | ||
208 | |||
209 | pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) { | ||
210 | let (mut db, file_id) = RootDatabase::with_single_file(text); | ||
211 | // FIXME: ideally, this should be done by the above `RootDatabase::with_single_file`, | ||
212 | // but it looks like this might need specialization? :( | ||
213 | db.set_local_roots(Arc::new(vec![db.file_source_root(file_id)])); | ||
214 | (db, file_id) | ||
215 | } | ||
216 | |||
217 | pub(crate) fn check_assist(assist: Handler, ra_fixture_before: &str, ra_fixture_after: &str) { | ||
218 | check(assist, ra_fixture_before, ExpectedResult::After(ra_fixture_after)); | ||
219 | } | ||
220 | |||
221 | // FIXME: instead of having a separate function here, maybe use | ||
222 | // `extract_ranges` and mark the target as `<target> </target>` in the | ||
223 | // fixuture? | ||
224 | pub(crate) fn check_assist_target(assist: Handler, ra_fixture: &str, target: &str) { | ||
225 | check(assist, ra_fixture, ExpectedResult::Target(target)); | ||
226 | } | ||
227 | |||
228 | pub(crate) fn check_assist_not_applicable(assist: Handler, ra_fixture: &str) { | ||
229 | check(assist, ra_fixture, ExpectedResult::NotApplicable); | ||
230 | } | ||
231 | |||
232 | enum ExpectedResult<'a> { | ||
233 | NotApplicable, | ||
234 | After(&'a str), | ||
235 | Target(&'a str), | ||
236 | } | ||
237 | |||
238 | fn check(assist: Handler, before: &str, expected: ExpectedResult) { | ||
239 | let (text_without_caret, file_with_caret_id, range_or_offset, db) = | ||
240 | if before.contains("//-") { | ||
241 | let (mut db, position) = RootDatabase::with_position(before); | ||
242 | db.set_local_roots(Arc::new(vec![db.file_source_root(position.file_id)])); | ||
243 | ( | ||
244 | db.file_text(position.file_id).as_ref().to_owned(), | ||
245 | position.file_id, | ||
246 | RangeOrOffset::Offset(position.offset), | ||
247 | db, | ||
248 | ) | ||
249 | } else { | ||
250 | let (range_or_offset, text_without_caret) = extract_range_or_offset(before); | ||
251 | let (db, file_id) = with_single_file(&text_without_caret); | ||
252 | (text_without_caret, file_id, range_or_offset, db) | ||
253 | }; | ||
254 | |||
255 | let frange = FileRange { file_id: file_with_caret_id, range: range_or_offset.into() }; | ||
256 | |||
257 | let sema = Semantics::new(&db); | ||
258 | let assist_ctx = AssistCtx::new(&sema, frange, true); | ||
259 | |||
260 | match (assist(assist_ctx), expected) { | ||
261 | (Some(assist), ExpectedResult::After(after)) => { | ||
262 | let action = assist.0[0].action.clone().unwrap(); | ||
263 | |||
264 | let mut actual = if let AssistFile::TargetFile(file_id) = action.file { | ||
265 | db.file_text(file_id).as_ref().to_owned() | ||
266 | } else { | ||
267 | text_without_caret | ||
268 | }; | ||
269 | action.edit.apply(&mut actual); | ||
270 | |||
271 | match action.cursor_position { | ||
272 | None => { | ||
273 | if let RangeOrOffset::Offset(before_cursor_pos) = range_or_offset { | ||
274 | let off = action | ||
275 | .edit | ||
276 | .apply_to_offset(before_cursor_pos) | ||
277 | .expect("cursor position is affected by the edit"); | ||
278 | actual = add_cursor(&actual, off) | ||
279 | } | ||
280 | } | ||
281 | Some(off) => actual = add_cursor(&actual, off), | ||
282 | }; | ||
283 | |||
284 | assert_eq_text!(after, &actual); | ||
285 | } | ||
286 | (Some(assist), ExpectedResult::Target(target)) => { | ||
287 | let action = assist.0[0].action.clone().unwrap(); | ||
288 | let range = action.target.expect("expected target on action"); | ||
289 | assert_eq_text!(&text_without_caret[range], target); | ||
290 | } | ||
291 | (Some(_), ExpectedResult::NotApplicable) => panic!("assist should not be applicable!"), | ||
292 | (None, ExpectedResult::After(_)) | (None, ExpectedResult::Target(_)) => { | ||
293 | panic!("code action is not applicable") | ||
294 | } | ||
295 | (None, ExpectedResult::NotApplicable) => (), | ||
296 | }; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | #[cfg(test)] | ||
301 | mod tests { | ||
302 | use ra_db::FileRange; | ||
303 | use ra_syntax::TextRange; | ||
304 | use test_utils::{extract_offset, extract_range}; | ||
305 | |||
306 | use crate::{helpers, resolved_assists}; | ||
307 | |||
308 | #[test] | ||
309 | fn assist_order_field_struct() { | ||
310 | let before = "struct Foo { <|>bar: u32 }"; | ||
311 | let (before_cursor_pos, before) = extract_offset(before); | ||
312 | let (db, file_id) = helpers::with_single_file(&before); | ||
313 | let frange = FileRange { file_id, range: TextRange::empty(before_cursor_pos) }; | ||
314 | let assists = resolved_assists(&db, frange); | ||
315 | let mut assists = assists.iter(); | ||
316 | |||
317 | assert_eq!( | ||
318 | assists.next().expect("expected assist").label.label, | ||
319 | "Change visibility to pub(crate)" | ||
320 | ); | ||
321 | assert_eq!(assists.next().expect("expected assist").label.label, "Add `#[derive]`"); | ||
322 | } | ||
323 | |||
324 | #[test] | ||
325 | fn assist_order_if_expr() { | ||
326 | let before = " | ||
327 | pub fn test_some_range(a: int) -> bool { | ||
328 | if let 2..6 = <|>5<|> { | ||
329 | true | ||
330 | } else { | ||
331 | false | ||
332 | } | ||
333 | }"; | ||
334 | let (range, before) = extract_range(before); | ||
335 | let (db, file_id) = helpers::with_single_file(&before); | ||
336 | let frange = FileRange { file_id, range }; | ||
337 | let assists = resolved_assists(&db, frange); | ||
338 | let mut assists = assists.iter(); | ||
339 | |||
340 | assert_eq!(assists.next().expect("expected assist").label.label, "Extract into variable"); | ||
341 | assert_eq!(assists.next().expect("expected assist").label.label, "Replace with match"); | ||
342 | } | ||
343 | } | ||