diff options
Diffstat (limited to 'crates/test_utils')
-rw-r--r-- | crates/test_utils/src/lib.rs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index eaeeeb97b..e32a0a0c3 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs | |||
@@ -11,11 +11,13 @@ pub mod mark; | |||
11 | mod fixture; | 11 | mod fixture; |
12 | 12 | ||
13 | use std::{ | 13 | use std::{ |
14 | convert::{TryFrom, TryInto}, | ||
14 | env, fs, | 15 | env, fs, |
15 | path::{Path, PathBuf}, | 16 | path::{Path, PathBuf}, |
16 | }; | 17 | }; |
17 | 18 | ||
18 | use serde_json::Value; | 19 | use serde_json::Value; |
20 | use stdx::lines_with_ends; | ||
19 | use text_size::{TextRange, TextSize}; | 21 | use text_size::{TextRange, TextSize}; |
20 | 22 | ||
21 | pub use difference::Changeset as __Changeset; | 23 | pub use difference::Changeset as __Changeset; |
@@ -159,6 +161,57 @@ pub fn add_cursor(text: &str, offset: TextSize) -> String { | |||
159 | res | 161 | res |
160 | } | 162 | } |
161 | 163 | ||
164 | /// Extracts `//^ some text` annotations | ||
165 | pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> { | ||
166 | let mut res = Vec::new(); | ||
167 | let mut prev_line_start: Option<TextSize> = None; | ||
168 | let mut line_start: TextSize = 0.into(); | ||
169 | for line in lines_with_ends(text) { | ||
170 | if let Some(idx) = line.find("//^") { | ||
171 | let offset = prev_line_start.unwrap() + TextSize::of(&line[..idx + "//".len()]); | ||
172 | for (line_range, text) in extract_line_annotations(&line[idx + "//".len()..]) { | ||
173 | res.push((line_range + offset, text)) | ||
174 | } | ||
175 | } | ||
176 | prev_line_start = Some(line_start); | ||
177 | line_start += TextSize::of(line); | ||
178 | } | ||
179 | res | ||
180 | } | ||
181 | |||
182 | fn extract_line_annotations(mut line: &str) -> Vec<(TextRange, String)> { | ||
183 | let mut res = Vec::new(); | ||
184 | let mut offset: TextSize = 0.into(); | ||
185 | while !line.is_empty() { | ||
186 | let len = line.chars().take_while(|&it| it == '^').count(); | ||
187 | assert!(len > 0); | ||
188 | let range = TextRange::at(offset, len.try_into().unwrap()); | ||
189 | let next = line[len..].find('^').map_or(line.len(), |it| it + len); | ||
190 | res.push((range, line[len..][..next - len].trim().to_string())); | ||
191 | line = &line[next..]; | ||
192 | offset += TextSize::try_from(next).unwrap(); | ||
193 | } | ||
194 | res | ||
195 | } | ||
196 | |||
197 | #[test] | ||
198 | fn test_extract_annotations() { | ||
199 | let text = stdx::trim_indent( | ||
200 | r#" | ||
201 | fn main() { | ||
202 | let (x, y) = (9, 2); | ||
203 | //^ def ^ def | ||
204 | zoo + 1 | ||
205 | } //^^^ i32 | ||
206 | "#, | ||
207 | ); | ||
208 | let res = extract_annotations(&text) | ||
209 | .into_iter() | ||
210 | .map(|(range, ann)| (&text[range], ann)) | ||
211 | .collect::<Vec<_>>(); | ||
212 | assert_eq!(res, vec![("x", "def".into()), ("y", "def".into()), ("zoo", "i32".into()),]); | ||
213 | } | ||
214 | |||
162 | // Comparison functionality borrowed from cargo: | 215 | // Comparison functionality borrowed from cargo: |
163 | 216 | ||
164 | /// Compare a line with an expected pattern. | 217 | /// Compare a line with an expected pattern. |