• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use annotate_snippets::display_list::*;
2 use annotate_snippets::snippet::{self, Snippet};
3 
4 #[test]
test_source_empty()5 fn test_source_empty() {
6     let dl = DisplayList::from(vec![DisplayLine::Source {
7         lineno: None,
8         inline_marks: vec![],
9         line: DisplaySourceLine::Empty,
10     }]);
11 
12     assert_eq!(dl.to_string(), " |");
13 }
14 
15 #[test]
test_source_content()16 fn test_source_content() {
17     let dl = DisplayList::from(vec![
18         DisplayLine::Source {
19             lineno: Some(56),
20             inline_marks: vec![],
21             line: DisplaySourceLine::Content {
22                 text: "This is an example",
23                 range: (0, 19),
24             },
25         },
26         DisplayLine::Source {
27             lineno: Some(57),
28             inline_marks: vec![],
29             line: DisplaySourceLine::Content {
30                 text: "of content lines",
31                 range: (0, 19),
32             },
33         },
34     ]);
35 
36     assert_eq!(
37         dl.to_string(),
38         "56 | This is an example\n57 | of content lines"
39     );
40 }
41 
42 #[test]
test_source_annotation_standalone_singleline()43 fn test_source_annotation_standalone_singleline() {
44     let dl = DisplayList::from(vec![DisplayLine::Source {
45         lineno: None,
46         inline_marks: vec![],
47         line: DisplaySourceLine::Annotation {
48             range: (0, 5),
49             annotation: Annotation {
50                 annotation_type: DisplayAnnotationType::None,
51                 id: None,
52                 label: vec![DisplayTextFragment {
53                     content: "Example string",
54                     style: DisplayTextStyle::Regular,
55                 }],
56             },
57             annotation_type: DisplayAnnotationType::Error,
58             annotation_part: DisplayAnnotationPart::Standalone,
59         },
60     }]);
61 
62     assert_eq!(dl.to_string(), " | ^^^^^ Example string");
63 }
64 
65 #[test]
test_source_annotation_standalone_multiline()66 fn test_source_annotation_standalone_multiline() {
67     let dl = DisplayList::from(vec![
68         DisplayLine::Source {
69             lineno: None,
70             inline_marks: vec![],
71             line: DisplaySourceLine::Annotation {
72                 range: (0, 5),
73                 annotation: Annotation {
74                     annotation_type: DisplayAnnotationType::Help,
75                     id: None,
76                     label: vec![DisplayTextFragment {
77                         content: "Example string",
78                         style: DisplayTextStyle::Regular,
79                     }],
80                 },
81                 annotation_type: DisplayAnnotationType::Warning,
82                 annotation_part: DisplayAnnotationPart::Standalone,
83             },
84         },
85         DisplayLine::Source {
86             lineno: None,
87             inline_marks: vec![],
88             line: DisplaySourceLine::Annotation {
89                 range: (0, 5),
90                 annotation: Annotation {
91                     annotation_type: DisplayAnnotationType::Help,
92                     id: None,
93                     label: vec![DisplayTextFragment {
94                         content: "Second line",
95                         style: DisplayTextStyle::Regular,
96                     }],
97                 },
98                 annotation_type: DisplayAnnotationType::Warning,
99                 annotation_part: DisplayAnnotationPart::LabelContinuation,
100             },
101         },
102     ]);
103 
104     assert_eq!(
105         dl.to_string(),
106         " | ----- help: Example string\n |             Second line"
107     );
108 }
109 
110 #[test]
test_source_annotation_standalone_multi_annotation()111 fn test_source_annotation_standalone_multi_annotation() {
112     let dl = DisplayList::from(vec![
113         DisplayLine::Source {
114             lineno: None,
115             inline_marks: vec![],
116             line: DisplaySourceLine::Annotation {
117                 range: (0, 5),
118                 annotation: Annotation {
119                     annotation_type: DisplayAnnotationType::Info,
120                     id: None,
121                     label: vec![DisplayTextFragment {
122                         content: "Example string",
123                         style: DisplayTextStyle::Regular,
124                     }],
125                 },
126                 annotation_type: DisplayAnnotationType::Note,
127                 annotation_part: DisplayAnnotationPart::Standalone,
128             },
129         },
130         DisplayLine::Source {
131             lineno: None,
132             inline_marks: vec![],
133             line: DisplaySourceLine::Annotation {
134                 range: (0, 5),
135                 annotation: Annotation {
136                     annotation_type: DisplayAnnotationType::Info,
137                     id: None,
138                     label: vec![DisplayTextFragment {
139                         content: "Second line",
140                         style: DisplayTextStyle::Regular,
141                     }],
142                 },
143                 annotation_type: DisplayAnnotationType::Note,
144                 annotation_part: DisplayAnnotationPart::LabelContinuation,
145             },
146         },
147         DisplayLine::Source {
148             lineno: None,
149             inline_marks: vec![],
150             line: DisplaySourceLine::Annotation {
151                 range: (0, 5),
152                 annotation: Annotation {
153                     annotation_type: DisplayAnnotationType::Warning,
154                     id: None,
155                     label: vec![DisplayTextFragment {
156                         content: "This is a note",
157                         style: DisplayTextStyle::Regular,
158                     }],
159                 },
160                 annotation_type: DisplayAnnotationType::Note,
161                 annotation_part: DisplayAnnotationPart::Consequitive,
162             },
163         },
164         DisplayLine::Source {
165             lineno: None,
166             inline_marks: vec![],
167             line: DisplaySourceLine::Annotation {
168                 range: (0, 5),
169                 annotation: Annotation {
170                     annotation_type: DisplayAnnotationType::Warning,
171                     id: None,
172                     label: vec![DisplayTextFragment {
173                         content: "Second line of the warning",
174                         style: DisplayTextStyle::Regular,
175                     }],
176                 },
177                 annotation_type: DisplayAnnotationType::Note,
178                 annotation_part: DisplayAnnotationPart::LabelContinuation,
179             },
180         },
181         DisplayLine::Source {
182             lineno: None,
183             inline_marks: vec![],
184             line: DisplaySourceLine::Annotation {
185                 range: (0, 5),
186                 annotation: Annotation {
187                     annotation_type: DisplayAnnotationType::Info,
188                     id: None,
189                     label: vec![DisplayTextFragment {
190                         content: "This is an info",
191                         style: DisplayTextStyle::Regular,
192                     }],
193                 },
194                 annotation_type: DisplayAnnotationType::Info,
195                 annotation_part: DisplayAnnotationPart::Standalone,
196             },
197         },
198         DisplayLine::Source {
199             lineno: None,
200             inline_marks: vec![],
201             line: DisplaySourceLine::Annotation {
202                 range: (0, 5),
203                 annotation: Annotation {
204                     annotation_type: DisplayAnnotationType::Help,
205                     id: None,
206                     label: vec![DisplayTextFragment {
207                         content: "This is help",
208                         style: DisplayTextStyle::Regular,
209                     }],
210                 },
211                 annotation_type: DisplayAnnotationType::Help,
212                 annotation_part: DisplayAnnotationPart::Standalone,
213             },
214         },
215         DisplayLine::Source {
216             lineno: None,
217             inline_marks: vec![],
218             line: DisplaySourceLine::Annotation {
219                 range: (0, 0),
220                 annotation: Annotation {
221                     annotation_type: DisplayAnnotationType::None,
222                     id: None,
223                     label: vec![DisplayTextFragment {
224                         content: "This is an annotation of type none",
225                         style: DisplayTextStyle::Regular,
226                     }],
227                 },
228                 annotation_type: DisplayAnnotationType::None,
229                 annotation_part: DisplayAnnotationPart::Standalone,
230             },
231         },
232     ]);
233 
234     assert_eq!(dl.to_string(), " | ----- info: Example string\n |             Second line\n |       warning: This is a note\n |                Second line of the warning\n | ----- info: This is an info\n | ----- help: This is help\n |  This is an annotation of type none");
235 }
236 
237 #[test]
test_fold_line()238 fn test_fold_line() {
239     let dl = DisplayList::from(vec![
240         DisplayLine::Source {
241             lineno: Some(5),
242             inline_marks: vec![],
243             line: DisplaySourceLine::Content {
244                 text: "This is line 5",
245                 range: (0, 19),
246             },
247         },
248         DisplayLine::Fold {
249             inline_marks: vec![],
250         },
251         DisplayLine::Source {
252             lineno: Some(10021),
253             inline_marks: vec![],
254             line: DisplaySourceLine::Content {
255                 text: "... and now we're at line 10021",
256                 range: (0, 19),
257             },
258         },
259     ]);
260 
261     assert_eq!(
262         dl.to_string(),
263         "    5 | This is line 5\n...\n10021 | ... and now we're at line 10021"
264     );
265 }
266 
267 #[test]
test_raw_origin_initial_nopos()268 fn test_raw_origin_initial_nopos() {
269     let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Origin {
270         path: "src/test.rs",
271         pos: None,
272         header_type: DisplayHeaderType::Initial,
273     })]);
274 
275     assert_eq!(dl.to_string(), "--> src/test.rs");
276 }
277 
278 #[test]
test_raw_origin_initial_pos()279 fn test_raw_origin_initial_pos() {
280     let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Origin {
281         path: "src/test.rs",
282         pos: Some((23, 15)),
283         header_type: DisplayHeaderType::Initial,
284     })]);
285 
286     assert_eq!(dl.to_string(), "--> src/test.rs:23:15");
287 }
288 
289 #[test]
test_raw_origin_continuation()290 fn test_raw_origin_continuation() {
291     let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Origin {
292         path: "src/test.rs",
293         pos: Some((23, 15)),
294         header_type: DisplayHeaderType::Continuation,
295     })]);
296 
297     assert_eq!(dl.to_string(), "::: src/test.rs:23:15");
298 }
299 
300 #[test]
test_raw_annotation_unaligned()301 fn test_raw_annotation_unaligned() {
302     let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Annotation {
303         annotation: Annotation {
304             annotation_type: DisplayAnnotationType::Error,
305             id: Some("E0001"),
306             label: vec![DisplayTextFragment {
307                 content: "This is an error",
308                 style: DisplayTextStyle::Regular,
309             }],
310         },
311         source_aligned: false,
312         continuation: false,
313     })]);
314 
315     assert_eq!(dl.to_string(), "error[E0001]: This is an error");
316 }
317 
318 #[test]
test_raw_annotation_unaligned_multiline()319 fn test_raw_annotation_unaligned_multiline() {
320     let dl = DisplayList::from(vec![
321         DisplayLine::Raw(DisplayRawLine::Annotation {
322             annotation: Annotation {
323                 annotation_type: DisplayAnnotationType::Warning,
324                 id: Some("E0001"),
325                 label: vec![DisplayTextFragment {
326                     content: "This is an error",
327                     style: DisplayTextStyle::Regular,
328                 }],
329             },
330             source_aligned: false,
331             continuation: false,
332         }),
333         DisplayLine::Raw(DisplayRawLine::Annotation {
334             annotation: Annotation {
335                 annotation_type: DisplayAnnotationType::Warning,
336                 id: Some("E0001"),
337                 label: vec![DisplayTextFragment {
338                     content: "Second line of the error",
339                     style: DisplayTextStyle::Regular,
340                 }],
341             },
342             source_aligned: false,
343             continuation: true,
344         }),
345     ]);
346 
347     assert_eq!(
348         dl.to_string(),
349         "warning[E0001]: This is an error\n                Second line of the error"
350     );
351 }
352 
353 #[test]
test_raw_annotation_aligned()354 fn test_raw_annotation_aligned() {
355     let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Annotation {
356         annotation: Annotation {
357             annotation_type: DisplayAnnotationType::Error,
358             id: Some("E0001"),
359             label: vec![DisplayTextFragment {
360                 content: "This is an error",
361                 style: DisplayTextStyle::Regular,
362             }],
363         },
364         source_aligned: true,
365         continuation: false,
366     })]);
367 
368     assert_eq!(dl.to_string(), " = error[E0001]: This is an error");
369 }
370 
371 #[test]
test_raw_annotation_aligned_multiline()372 fn test_raw_annotation_aligned_multiline() {
373     let dl = DisplayList::from(vec![
374         DisplayLine::Raw(DisplayRawLine::Annotation {
375             annotation: Annotation {
376                 annotation_type: DisplayAnnotationType::Warning,
377                 id: Some("E0001"),
378                 label: vec![DisplayTextFragment {
379                     content: "This is an error",
380                     style: DisplayTextStyle::Regular,
381                 }],
382             },
383             source_aligned: true,
384             continuation: false,
385         }),
386         DisplayLine::Raw(DisplayRawLine::Annotation {
387             annotation: Annotation {
388                 annotation_type: DisplayAnnotationType::Warning,
389                 id: Some("E0001"),
390                 label: vec![DisplayTextFragment {
391                     content: "Second line of the error",
392                     style: DisplayTextStyle::Regular,
393                 }],
394             },
395             source_aligned: true,
396             continuation: true,
397         }),
398     ]);
399 
400     assert_eq!(
401         dl.to_string(),
402         " = warning[E0001]: This is an error\n                   Second line of the error"
403     );
404 }
405 
406 #[test]
test_different_annotation_types()407 fn test_different_annotation_types() {
408     let dl = DisplayList::from(vec![
409         DisplayLine::Raw(DisplayRawLine::Annotation {
410             annotation: Annotation {
411                 annotation_type: DisplayAnnotationType::Note,
412                 id: None,
413                 label: vec![DisplayTextFragment {
414                     content: "This is a note",
415                     style: DisplayTextStyle::Regular,
416                 }],
417             },
418             source_aligned: false,
419             continuation: false,
420         }),
421         DisplayLine::Raw(DisplayRawLine::Annotation {
422             annotation: Annotation {
423                 annotation_type: DisplayAnnotationType::None,
424                 id: None,
425                 label: vec![DisplayTextFragment {
426                     content: "This is just a string",
427                     style: DisplayTextStyle::Regular,
428                 }],
429             },
430             source_aligned: false,
431             continuation: false,
432         }),
433         DisplayLine::Raw(DisplayRawLine::Annotation {
434             annotation: Annotation {
435                 annotation_type: DisplayAnnotationType::None,
436                 id: None,
437                 label: vec![DisplayTextFragment {
438                     content: "Second line of none type annotation",
439                     style: DisplayTextStyle::Regular,
440                 }],
441             },
442             source_aligned: false,
443             continuation: true,
444         }),
445     ]);
446 
447     assert_eq!(
448         dl.to_string(),
449         "note: This is a note\nThis is just a string\n  Second line of none type annotation",
450     );
451 }
452 
453 #[test]
test_inline_marks_empty_line()454 fn test_inline_marks_empty_line() {
455     let dl = DisplayList::from(vec![DisplayLine::Source {
456         lineno: None,
457         inline_marks: vec![DisplayMark {
458             mark_type: DisplayMarkType::AnnotationThrough,
459             annotation_type: DisplayAnnotationType::Error,
460         }],
461         line: DisplaySourceLine::Empty,
462     }]);
463 
464     assert_eq!(dl.to_string(), " | |",);
465 }
466 
467 #[test]
test_anon_lines()468 fn test_anon_lines() {
469     let mut dl = DisplayList::from(vec![
470         DisplayLine::Source {
471             lineno: Some(56),
472             inline_marks: vec![],
473             line: DisplaySourceLine::Content {
474                 text: "This is an example",
475                 range: (0, 19),
476             },
477         },
478         DisplayLine::Source {
479             lineno: Some(57),
480             inline_marks: vec![],
481             line: DisplaySourceLine::Content {
482                 text: "of content lines",
483                 range: (0, 19),
484             },
485         },
486         DisplayLine::Source {
487             lineno: None,
488             inline_marks: vec![],
489             line: DisplaySourceLine::Empty,
490         },
491         DisplayLine::Source {
492             lineno: None,
493             inline_marks: vec![],
494             line: DisplaySourceLine::Content {
495                 text: "abc",
496                 range: (0, 19),
497             },
498         },
499     ]);
500 
501     dl.anonymized_line_numbers = true;
502     assert_eq!(
503         dl.to_string(),
504         "LL | This is an example\nLL | of content lines\n   |\n   | abc"
505     );
506 }
507 
508 #[test]
test_raw_origin_initial_pos_anon_lines()509 fn test_raw_origin_initial_pos_anon_lines() {
510     let mut dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Origin {
511         path: "src/test.rs",
512         pos: Some((23, 15)),
513         header_type: DisplayHeaderType::Initial,
514     })]);
515 
516     // Using anonymized_line_numbers should not affect the inital position
517     dl.anonymized_line_numbers = true;
518     assert_eq!(dl.to_string(), "--> src/test.rs:23:15");
519 }
520 
521 #[test]
test_i_29()522 fn test_i_29() {
523     let snippets = Snippet {
524         title: Some(snippet::Annotation {
525             id: None,
526             label: Some("oops"),
527             annotation_type: snippet::AnnotationType::Error,
528         }),
529         footer: vec![],
530         slices: vec![snippet::Slice {
531             source: "First line\r\nSecond oops line",
532             line_start: 1,
533             origin: Some("<current file>"),
534             annotations: vec![snippet::SourceAnnotation {
535                 range: (19, 23),
536                 label: "oops",
537                 annotation_type: snippet::AnnotationType::Error,
538             }],
539             fold: true,
540         }],
541         opt: Default::default(),
542     };
543     let expected = r#"error: oops
544  --> <current file>:2:8
545   |
546 1 | First line
547 2 | Second oops line
548   |        ^^^^ oops
549   |"#;
550 
551     assert_eq!(DisplayList::from(snippets).to_string(), expected);
552 }
553 
554 #[test]
test_point_to_double_width_characters()555 fn test_point_to_double_width_characters() {
556     let snippets = Snippet {
557         slices: vec![snippet::Slice {
558             source: "こんにちは、世界",
559             line_start: 1,
560             origin: Some("<current file>"),
561             annotations: vec![snippet::SourceAnnotation {
562                 range: (6, 8),
563                 label: "world",
564                 annotation_type: snippet::AnnotationType::Error,
565             }],
566             fold: false,
567         }],
568         title: None,
569         footer: vec![],
570         opt: Default::default(),
571     };
572 
573     let expected = r#" --> <current file>:1:7
574   |
575 1 | こんにちは、世界
576   |             ^^^^ world
577   |"#;
578 
579     assert_eq!(DisplayList::from(snippets).to_string(), expected);
580 }
581 
582 #[test]
test_point_to_double_width_characters_across_lines()583 fn test_point_to_double_width_characters_across_lines() {
584     let snippets = Snippet {
585         slices: vec![snippet::Slice {
586             source: "おはよう\nございます",
587             line_start: 1,
588             origin: Some("<current file>"),
589             annotations: vec![snippet::SourceAnnotation {
590                 range: (2, 8),
591                 label: "Good morning",
592                 annotation_type: snippet::AnnotationType::Error,
593             }],
594             fold: false,
595         }],
596         title: None,
597         footer: vec![],
598         opt: Default::default(),
599     };
600 
601     let expected = r#" --> <current file>:1:3
602   |
603 1 |   おはよう
604   |  _____^
605 2 | | ございます
606   | |______^ Good morning
607   |"#;
608 
609     assert_eq!(DisplayList::from(snippets).to_string(), expected);
610 }
611 
612 #[test]
test_point_to_double_width_characters_multiple()613 fn test_point_to_double_width_characters_multiple() {
614     let snippets = Snippet {
615         slices: vec![snippet::Slice {
616             source: "お寿司\n食べたい��",
617             line_start: 1,
618             origin: Some("<current file>"),
619             annotations: vec![
620                 snippet::SourceAnnotation {
621                     range: (0, 3),
622                     label: "Sushi1",
623                     annotation_type: snippet::AnnotationType::Error,
624                 },
625                 snippet::SourceAnnotation {
626                     range: (6, 8),
627                     label: "Sushi2",
628                     annotation_type: snippet::AnnotationType::Note,
629                 },
630             ],
631             fold: false,
632         }],
633         title: None,
634         footer: vec![],
635         opt: Default::default(),
636     };
637 
638     let expected = r#" --> <current file>:1:1
639   |
640 1 | お寿司
641   | ^^^^^^ Sushi1
642 2 | 食べたい��
643   |     ---- note: Sushi2
644   |"#;
645 
646     assert_eq!(DisplayList::from(snippets).to_string(), expected);
647 }
648 
649 #[test]
test_point_to_double_width_characters_mixed()650 fn test_point_to_double_width_characters_mixed() {
651     let snippets = Snippet {
652         slices: vec![snippet::Slice {
653             source: "こんにちは、新しいWorld!",
654             line_start: 1,
655             origin: Some("<current file>"),
656             annotations: vec![snippet::SourceAnnotation {
657                 range: (6, 14),
658                 label: "New world",
659                 annotation_type: snippet::AnnotationType::Error,
660             }],
661             fold: false,
662         }],
663         title: None,
664         footer: vec![],
665         opt: Default::default(),
666     };
667 
668     let expected = r#" --> <current file>:1:7
669   |
670 1 | こんにちは、新しいWorld!
671   |             ^^^^^^^^^^^ New world
672   |"#;
673 
674     assert_eq!(DisplayList::from(snippets).to_string(), expected);
675 }
676