diff options
Diffstat (limited to 'crates/test_utils')
-rw-r--r-- | crates/test_utils/src/lib.rs | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index ac5a9509d..b2fe25f82 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs | |||
@@ -190,10 +190,21 @@ pub fn add_cursor(text: &str, offset: TextSize) -> String { | |||
190 | res | 190 | res |
191 | } | 191 | } |
192 | 192 | ||
193 | /// Extracts `//^ some text` annotations | 193 | /// Extracts `//^^^ some text` annotations. |
194 | /// | ||
195 | /// A run of `^^^` can be arbitrary long and points to the corresponding range | ||
196 | /// in the line above. | ||
197 | /// | ||
198 | /// The `// ^file text` syntax can be used to attach `text` to the entirety of | ||
199 | /// the file. | ||
200 | /// | ||
201 | /// Multiline string values are supported: | ||
202 | /// | ||
203 | /// // ^^^ first line | ||
204 | /// // | second line | ||
194 | pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> { | 205 | pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> { |
195 | let mut res = Vec::new(); | 206 | let mut res = Vec::new(); |
196 | let mut prev_line_start: Option<TextSize> = None; | 207 | let mut prev_line_start: Option<TextSize> = Some(0.into()); |
197 | let mut line_start: TextSize = 0.into(); | 208 | let mut line_start: TextSize = 0.into(); |
198 | let mut prev_line_annotations: Vec<(TextSize, usize)> = Vec::new(); | 209 | let mut prev_line_annotations: Vec<(TextSize, usize)> = Vec::new(); |
199 | for line in text.split_inclusive('\n') { | 210 | for line in text.split_inclusive('\n') { |
@@ -202,10 +213,15 @@ pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> { | |||
202 | let annotation_offset = TextSize::of(&line[..idx + "//".len()]); | 213 | let annotation_offset = TextSize::of(&line[..idx + "//".len()]); |
203 | for annotation in extract_line_annotations(&line[idx + "//".len()..]) { | 214 | for annotation in extract_line_annotations(&line[idx + "//".len()..]) { |
204 | match annotation { | 215 | match annotation { |
205 | LineAnnotation::Annotation { mut range, content } => { | 216 | LineAnnotation::Annotation { mut range, content, file } => { |
206 | range += annotation_offset; | 217 | range += annotation_offset; |
207 | this_line_annotations.push((range.end(), res.len())); | 218 | this_line_annotations.push((range.end(), res.len())); |
208 | res.push((range + prev_line_start.unwrap(), content)) | 219 | let range = if file { |
220 | TextRange::up_to(TextSize::of(text)) | ||
221 | } else { | ||
222 | range + prev_line_start.unwrap() | ||
223 | }; | ||
224 | res.push((range, content)) | ||
209 | } | 225 | } |
210 | LineAnnotation::Continuation { mut offset, content } => { | 226 | LineAnnotation::Continuation { mut offset, content } => { |
211 | offset += annotation_offset; | 227 | offset += annotation_offset; |
@@ -226,11 +242,12 @@ pub fn extract_annotations(text: &str) -> Vec<(TextRange, String)> { | |||
226 | 242 | ||
227 | prev_line_annotations = this_line_annotations; | 243 | prev_line_annotations = this_line_annotations; |
228 | } | 244 | } |
245 | |||
229 | res | 246 | res |
230 | } | 247 | } |
231 | 248 | ||
232 | enum LineAnnotation { | 249 | enum LineAnnotation { |
233 | Annotation { range: TextRange, content: String }, | 250 | Annotation { range: TextRange, content: String, file: bool }, |
234 | Continuation { offset: TextSize, content: String }, | 251 | Continuation { offset: TextSize, content: String }, |
235 | } | 252 | } |
236 | 253 | ||
@@ -251,12 +268,20 @@ fn extract_line_annotations(mut line: &str) -> Vec<LineAnnotation> { | |||
251 | } | 268 | } |
252 | let range = TextRange::at(offset, len.try_into().unwrap()); | 269 | let range = TextRange::at(offset, len.try_into().unwrap()); |
253 | let next = line[len..].find(marker).map_or(line.len(), |it| it + len); | 270 | let next = line[len..].find(marker).map_or(line.len(), |it| it + len); |
254 | let content = line[len..][..next - len].trim().to_string(); | 271 | let mut content = &line[len..][..next - len]; |
272 | |||
273 | let mut file = false; | ||
274 | if !continuation && content.starts_with("file") { | ||
275 | file = true; | ||
276 | content = &content["file".len()..] | ||
277 | } | ||
278 | |||
279 | let content = content.trim().to_string(); | ||
255 | 280 | ||
256 | let annotation = if continuation { | 281 | let annotation = if continuation { |
257 | LineAnnotation::Continuation { offset: range.end(), content } | 282 | LineAnnotation::Continuation { offset: range.end(), content } |
258 | } else { | 283 | } else { |
259 | LineAnnotation::Annotation { range, content } | 284 | LineAnnotation::Annotation { range, content, file } |
260 | }; | 285 | }; |
261 | res.push(annotation); | 286 | res.push(annotation); |
262 | 287 | ||
@@ -277,16 +302,20 @@ fn main() { | |||
277 | zoo + 1 | 302 | zoo + 1 |
278 | } //^^^ type: | 303 | } //^^^ type: |
279 | // | i32 | 304 | // | i32 |
305 | |||
306 | // ^file | ||
280 | "#, | 307 | "#, |
281 | ); | 308 | ); |
282 | let res = extract_annotations(&text) | 309 | let res = extract_annotations(&text) |
283 | .into_iter() | 310 | .into_iter() |
284 | .map(|(range, ann)| (&text[range], ann)) | 311 | .map(|(range, ann)| (&text[range], ann)) |
285 | .collect::<Vec<_>>(); | 312 | .collect::<Vec<_>>(); |
313 | |||
286 | assert_eq!( | 314 | assert_eq!( |
287 | res, | 315 | res[..3], |
288 | vec![("x", "def".into()), ("y", "def".into()), ("zoo", "type:\ni32\n".into()),] | 316 | [("x", "def".into()), ("y", "def".into()), ("zoo", "type:\ni32\n".into())] |
289 | ); | 317 | ); |
318 | assert_eq!(res[3].0.len(), 115); | ||
290 | } | 319 | } |
291 | 320 | ||
292 | /// Returns `false` if slow tests should not run, otherwise returns `true` and | 321 | /// Returns `false` if slow tests should not run, otherwise returns `true` and |