aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_text_edit/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_text_edit/src')
-rw-r--r--crates/ra_text_edit/src/lib.rs5
-rw-r--r--crates/ra_text_edit/src/test_utils.rs83
2 files changed, 2 insertions, 86 deletions
diff --git a/crates/ra_text_edit/src/lib.rs b/crates/ra_text_edit/src/lib.rs
index 37f23d043..f6769e6a6 100644
--- a/crates/ra_text_edit/src/lib.rs
+++ b/crates/ra_text_edit/src/lib.rs
@@ -1,12 +1,11 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3mod text_edit; 3mod text_edit;
4pub mod test_utils;
5
6pub use crate::text_edit::{TextEdit, TextEditBuilder};
7 4
8use text_unit::{TextRange, TextUnit}; 5use text_unit::{TextRange, TextUnit};
9 6
7pub use crate::text_edit::{TextEdit, TextEditBuilder};
8
10/// Must not overlap with other `AtomTextEdit`s 9/// Must not overlap with other `AtomTextEdit`s
11#[derive(Debug, Clone)] 10#[derive(Debug, Clone)]
12pub struct AtomTextEdit { 11pub struct AtomTextEdit {
diff --git a/crates/ra_text_edit/src/test_utils.rs b/crates/ra_text_edit/src/test_utils.rs
deleted file mode 100644
index d4c7840ff..000000000
--- a/crates/ra_text_edit/src/test_utils.rs
+++ /dev/null
@@ -1,83 +0,0 @@
1//! FIXME: write short doc here
2
3use crate::{AtomTextEdit, TextEdit};
4use proptest::prelude::*;
5use text_unit::{TextRange, TextUnit};
6
7pub fn arb_text() -> proptest::string::RegexGeneratorStrategy<String> {
8 // generate multiple newlines
9 proptest::string::string_regex("(.*\n?)*").unwrap()
10}
11
12fn text_offsets(text: &str) -> Vec<TextUnit> {
13 text.char_indices().map(|(i, _)| TextUnit::from_usize(i)).collect()
14}
15
16pub fn arb_offset(text: &str) -> BoxedStrategy<TextUnit> {
17 let offsets = text_offsets(text);
18 // this is necessary to avoid "Uniform::new called with `low >= high`" panic
19 if offsets.is_empty() {
20 Just(TextUnit::from(0)).boxed()
21 } else {
22 prop::sample::select(offsets).boxed()
23 }
24}
25
26pub fn arb_text_edit(text: &str) -> BoxedStrategy<TextEdit> {
27 if text.is_empty() {
28 // only valid edits
29 return Just(vec![])
30 .boxed()
31 .prop_union(
32 arb_text()
33 .prop_map(|text| vec![AtomTextEdit::insert(TextUnit::from(0), text)])
34 .boxed(),
35 )
36 .prop_map(TextEdit::from_atoms)
37 .boxed();
38 }
39
40 let offsets = text_offsets(text);
41 let max_cuts = 7.min(offsets.len());
42
43 proptest::sample::subsequence(offsets, 0..max_cuts)
44 .prop_flat_map(|cuts| {
45 let strategies: Vec<_> = cuts
46 .chunks(2)
47 .map(|chunk| match *chunk {
48 [from, to] => {
49 let range = TextRange::from_to(from, to);
50 Just(AtomTextEdit::delete(range))
51 .boxed()
52 .prop_union(
53 arb_text()
54 .prop_map(move |text| AtomTextEdit::replace(range, text))
55 .boxed(),
56 )
57 .boxed()
58 }
59 [x] => arb_text().prop_map(move |text| AtomTextEdit::insert(x, text)).boxed(),
60 _ => unreachable!(),
61 })
62 .collect();
63 strategies
64 })
65 .prop_map(TextEdit::from_atoms)
66 .boxed()
67}
68
69#[derive(Debug, Clone)]
70pub struct ArbTextWithEdit {
71 pub text: String,
72 pub edit: TextEdit,
73}
74
75pub fn arb_text_with_edit() -> BoxedStrategy<ArbTextWithEdit> {
76 let text = arb_text();
77 text.prop_flat_map(|s| {
78 let edit = arb_text_edit(&s);
79 (Just(s), edit)
80 })
81 .prop_map(|(text, edit)| ArbTextWithEdit { text, edit })
82 .boxed()
83}