diff options
Diffstat (limited to 'crates/ra_assists/src/lib.rs')
-rw-r--r-- | crates/ra_assists/src/lib.rs | 114 |
1 files changed, 49 insertions, 65 deletions
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index d7998b0d1..79fe43aa4 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs | |||
@@ -162,7 +162,7 @@ mod helpers { | |||
162 | use ra_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt}; | 162 | use ra_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt}; |
163 | use ra_ide_db::{symbol_index::SymbolsDatabase, RootDatabase}; | 163 | use ra_ide_db::{symbol_index::SymbolsDatabase, RootDatabase}; |
164 | use ra_syntax::TextRange; | 164 | use ra_syntax::TextRange; |
165 | use test_utils::{add_cursor, assert_eq_text, extract_offset, extract_range}; | 165 | use test_utils::{add_cursor, assert_eq_text, extract_range_or_offset, RangeOrOffset}; |
166 | 166 | ||
167 | use crate::{AssistCtx, AssistHandler}; | 167 | use crate::{AssistCtx, AssistHandler}; |
168 | 168 | ||
@@ -176,81 +176,65 @@ mod helpers { | |||
176 | } | 176 | } |
177 | 177 | ||
178 | pub(crate) fn check_assist(assist: AssistHandler, before: &str, after: &str) { | 178 | pub(crate) fn check_assist(assist: AssistHandler, before: &str, after: &str) { |
179 | let (before_cursor_pos, before) = extract_offset(before); | 179 | check(assist, before, ExpectedResult::After(after)); |
180 | let (db, file_id) = with_single_file(&before); | ||
181 | let frange = | ||
182 | FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) }; | ||
183 | let assist = | ||
184 | assist(AssistCtx::new(&db, frange, true)).expect("code action is not applicable"); | ||
185 | let action = assist.0[0].action.clone().unwrap(); | ||
186 | |||
187 | let actual = action.edit.apply(&before); | ||
188 | let actual_cursor_pos = match action.cursor_position { | ||
189 | None => action | ||
190 | .edit | ||
191 | .apply_to_offset(before_cursor_pos) | ||
192 | .expect("cursor position is affected by the edit"), | ||
193 | Some(off) => off, | ||
194 | }; | ||
195 | let actual = add_cursor(&actual, actual_cursor_pos); | ||
196 | assert_eq_text!(after, &actual); | ||
197 | } | ||
198 | |||
199 | pub(crate) fn check_assist_range(assist: AssistHandler, before: &str, after: &str) { | ||
200 | let (range, before) = extract_range(before); | ||
201 | let (db, file_id) = with_single_file(&before); | ||
202 | let frange = FileRange { file_id, range }; | ||
203 | let assist = | ||
204 | assist(AssistCtx::new(&db, frange, true)).expect("code action is not applicable"); | ||
205 | let action = assist.0[0].action.clone().unwrap(); | ||
206 | |||
207 | let mut actual = action.edit.apply(&before); | ||
208 | if let Some(pos) = action.cursor_position { | ||
209 | actual = add_cursor(&actual, pos); | ||
210 | } | ||
211 | assert_eq_text!(after, &actual); | ||
212 | } | 180 | } |
213 | 181 | ||
182 | // FIXME: instead of having a separate function here, maybe use | ||
183 | // `extract_ranges` and mark the target as `<target> </target>` in the | ||
184 | // fixuture? | ||
214 | pub(crate) fn check_assist_target(assist: AssistHandler, before: &str, target: &str) { | 185 | pub(crate) fn check_assist_target(assist: AssistHandler, before: &str, target: &str) { |
215 | let (before_cursor_pos, before) = extract_offset(before); | 186 | check(assist, before, ExpectedResult::Target(target)); |
216 | let (db, file_id) = with_single_file(&before); | ||
217 | let frange = | ||
218 | FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) }; | ||
219 | let assist = | ||
220 | assist(AssistCtx::new(&db, frange, true)).expect("code action is not applicable"); | ||
221 | let action = assist.0[0].action.clone().unwrap(); | ||
222 | |||
223 | let range = action.target.expect("expected target on action"); | ||
224 | assert_eq_text!(&before[range.start().to_usize()..range.end().to_usize()], target); | ||
225 | } | 187 | } |
226 | 188 | ||
227 | pub(crate) fn check_assist_range_target(assist: AssistHandler, before: &str, target: &str) { | 189 | pub(crate) fn check_assist_not_applicable(assist: AssistHandler, before: &str) { |
228 | let (range, before) = extract_range(before); | 190 | check(assist, before, ExpectedResult::NotApplicable); |
229 | let (db, file_id) = with_single_file(&before); | ||
230 | let frange = FileRange { file_id, range }; | ||
231 | let assist = | ||
232 | assist(AssistCtx::new(&db, frange, true)).expect("code action is not applicable"); | ||
233 | let action = assist.0[0].action.clone().unwrap(); | ||
234 | |||
235 | let range = action.target.expect("expected target on action"); | ||
236 | assert_eq_text!(&before[range.start().to_usize()..range.end().to_usize()], target); | ||
237 | } | 191 | } |
238 | 192 | ||
239 | pub(crate) fn check_assist_not_applicable(assist: AssistHandler, before: &str) { | 193 | enum ExpectedResult<'a> { |
240 | let (before_cursor_pos, before) = extract_offset(before); | 194 | NotApplicable, |
241 | let (db, file_id) = with_single_file(&before); | 195 | After(&'a str), |
242 | let frange = | 196 | Target(&'a str), |
243 | FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) }; | ||
244 | let assist = assist(AssistCtx::new(&db, frange, true)); | ||
245 | assert!(assist.is_none()); | ||
246 | } | 197 | } |
247 | 198 | ||
248 | pub(crate) fn check_assist_range_not_applicable(assist: AssistHandler, before: &str) { | 199 | fn check(assist: AssistHandler, before: &str, expected: ExpectedResult) { |
249 | let (range, before) = extract_range(before); | 200 | let (range_or_offset, before) = extract_range_or_offset(before); |
201 | let range: TextRange = range_or_offset.into(); | ||
202 | |||
250 | let (db, file_id) = with_single_file(&before); | 203 | let (db, file_id) = with_single_file(&before); |
251 | let frange = FileRange { file_id, range }; | 204 | let frange = FileRange { file_id, range }; |
252 | let assist = assist(AssistCtx::new(&db, frange, true)); | 205 | let assist_ctx = AssistCtx::new(&db, frange, true); |
253 | assert!(assist.is_none()); | 206 | |
207 | match (assist(assist_ctx), expected) { | ||
208 | (Some(assist), ExpectedResult::After(after)) => { | ||
209 | let action = assist.0[0].action.clone().unwrap(); | ||
210 | |||
211 | let mut actual = action.edit.apply(&before); | ||
212 | match action.cursor_position { | ||
213 | None => { | ||
214 | if let RangeOrOffset::Offset(before_cursor_pos) = range_or_offset { | ||
215 | let off = action | ||
216 | .edit | ||
217 | .apply_to_offset(before_cursor_pos) | ||
218 | .expect("cursor position is affected by the edit"); | ||
219 | actual = add_cursor(&actual, off) | ||
220 | } | ||
221 | } | ||
222 | Some(off) => actual = add_cursor(&actual, off), | ||
223 | }; | ||
224 | |||
225 | assert_eq_text!(after, &actual); | ||
226 | } | ||
227 | (Some(assist), ExpectedResult::Target(target)) => { | ||
228 | let action = assist.0[0].action.clone().unwrap(); | ||
229 | let range = action.target.expect("expected target on action"); | ||
230 | assert_eq_text!(&before[range.start().to_usize()..range.end().to_usize()], target); | ||
231 | } | ||
232 | (Some(_), ExpectedResult::NotApplicable) => panic!("assist should not be applicable!"), | ||
233 | (None, ExpectedResult::After(_)) | (None, ExpectedResult::Target(_)) => { | ||
234 | panic!("code action is not applicable") | ||
235 | } | ||
236 | (None, ExpectedResult::NotApplicable) => (), | ||
237 | }; | ||
254 | } | 238 | } |
255 | } | 239 | } |
256 | 240 | ||