diff options
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 051f1f995..1db499175 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -386,3 +386,64 @@ where | |||
386 | self.iter.next().map(|item| item.conv_with(self.ctx)) | 386 | self.iter.next().map(|item| item.conv_with(self.ctx)) |
387 | } | 387 | } |
388 | } | 388 | } |
389 | |||
390 | #[cfg(test)] | ||
391 | mod test { | ||
392 | use proptest::{prelude::*, proptest, proptest_helper}; | ||
393 | use super::*; | ||
394 | use ra_text_edit::test_utils::{arb_text, arb_offset, arb_edits}; | ||
395 | |||
396 | #[derive(Debug)] | ||
397 | struct ArbTextWithOffsetAndEdits { | ||
398 | text: String, | ||
399 | offset: TextUnit, | ||
400 | edits: Vec<AtomTextEdit>, | ||
401 | } | ||
402 | |||
403 | fn arb_text_with_offset_and_edits() -> BoxedStrategy<ArbTextWithOffsetAndEdits> { | ||
404 | arb_text() | ||
405 | .prop_flat_map(|text| { | ||
406 | (arb_offset(&text), arb_edits(&text), Just(text)).prop_map( | ||
407 | |(offset, edits, text)| ArbTextWithOffsetAndEdits { | ||
408 | text, | ||
409 | offset, | ||
410 | edits, | ||
411 | }, | ||
412 | ) | ||
413 | }) | ||
414 | .boxed() | ||
415 | } | ||
416 | |||
417 | fn translate_offset_with_edit_naive( | ||
418 | pre_edit_text: String, | ||
419 | offset: TextUnit, | ||
420 | edits: &[AtomTextEdit], | ||
421 | ) -> LineCol { | ||
422 | // apply edits ordered from last to first | ||
423 | // since they should not overlap we can just use start() | ||
424 | let mut edits: Vec<AtomTextEdit> = edits.to_vec(); | ||
425 | edits.sort_by_key(|x| -(x.delete.start().to_usize() as isize)); | ||
426 | |||
427 | let mut text = pre_edit_text; | ||
428 | |||
429 | for edit in &edits { | ||
430 | let range = edit.delete.start().to_usize()..edit.delete.end().to_usize(); | ||
431 | text.replace_range(range, &edit.insert); | ||
432 | } | ||
433 | |||
434 | let line_index = LineIndex::new(&text); | ||
435 | |||
436 | line_index.line_col(offset) | ||
437 | } | ||
438 | |||
439 | proptest! { | ||
440 | #[test] | ||
441 | fn test_translate_offset_with_edit(x in arb_text_with_offset_and_edits()) { | ||
442 | if x.edits.len() <= 1 { | ||
443 | let expected = translate_offset_with_edit_naive(x.text.clone(), x.offset, &x.edits); | ||
444 | let actual = translate_offset_with_edit(&LineIndex::new(&x.text), x.offset, &x.edits); | ||
445 | assert_eq!(actual, expected); | ||
446 | } | ||
447 | } | ||
448 | } | ||
449 | } | ||