aboutsummaryrefslogtreecommitdiff
path: root/crates/test_utils/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/test_utils/src/lib.rs')
-rw-r--r--crates/test_utils/src/lib.rs39
1 files changed, 32 insertions, 7 deletions
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index 0a94adb74..1ae800d7c 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -66,15 +66,40 @@ pub fn try_extract_range(text: &str) -> Option<(TextRange, String)> {
66 Some((TextRange::from_to(start, end), text)) 66 Some((TextRange::from_to(start, end), text))
67} 67}
68 68
69pub fn extract_ranges(text: &str) -> (Vec<TextRange>, String) { 69/// Extracts ranges, marked with `<tag> </tag>` paris from the `text`
70pub fn extract_ranges(mut text: &str, tag: &str) -> (Vec<TextRange>, String) {
71 let open = format!("<{}>", tag);
72 let close = format!("</{}>", tag);
70 let mut ranges = Vec::new(); 73 let mut ranges = Vec::new();
71 let mut text = String::from(text); 74 let mut res = String::new();
72 while let Some((range, new_text)) = try_extract_range(&text) { 75 let mut stack = Vec::new();
73 text = new_text; 76 loop {
74 ranges.push(range); 77 match text.find('<') {
78 None => {
79 res.push_str(text);
80 break;
81 }
82 Some(i) => {
83 res.push_str(&text[..i]);
84 text = &text[i..];
85 if text.starts_with(&open) {
86 text = &text[open.len()..];
87 let from = TextUnit::of_str(&res);
88 stack.push(from);
89 } else if text.starts_with(&close) {
90 text = &text[close.len()..];
91 let from = stack
92 .pop()
93 .unwrap_or_else(|| panic!("unmatched </{}>", tag));
94 let to = TextUnit::of_str(&res);
95 ranges.push(TextRange::from_to(from, to));
96 }
97 }
98 }
75 } 99 }
76 100 assert!(stack.is_empty(), "unmatched <{}>", tag);
77 (ranges, text) 101 ranges.sort_by_key(|r| (r.start(), r.end()));
102 (ranges, res)
78} 103}
79 104
80pub fn add_cursor(text: &str, offset: TextUnit) -> String { 105pub fn add_cursor(text: &str, offset: TextUnit) -> String {