diff options
Diffstat (limited to 'vendor/annotate-snippets-0.8.0/tests')
15 files changed, 1382 insertions, 0 deletions
diff --git a/vendor/annotate-snippets-0.8.0/tests/diff/mod.rs b/vendor/annotate-snippets-0.8.0/tests/diff/mod.rs new file mode 100644 index 000000000..576c6c4d6 --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/diff/mod.rs @@ -0,0 +1,43 @@ +use difference::{Changeset, Difference}; +use yansi_term::Color::{Black, Green, Red}; + +pub fn get_diff(left: &str, right: &str) -> String { + let mut output = String::new(); + + let Changeset { diffs, .. } = Changeset::new(left, right, "\n"); + + for i in 0..diffs.len() { + match diffs[i] { + Difference::Same(ref x) => { + output += &format!(" {}\n", x); + } + Difference::Add(ref x) => { + match diffs[i - 1] { + Difference::Rem(ref y) => { + output += &format!("{}", Green.paint("+")); + let Changeset { diffs, .. } = Changeset::new(y, x, " "); + for c in diffs { + match c { + Difference::Same(ref z) => { + output += &format!("{} ", Green.paint(z.as_str())); + } + Difference::Add(ref z) => { + output += &format!("{} ", Black.on(Green).paint(z.as_str())); + } + _ => (), + } + } + output += "\n"; + } + _ => { + output += &format!("+{}\n", Green.paint(x.as_str())); + } + }; + } + Difference::Rem(ref x) => { + output += &format!("-{}\n", Red.paint(x.as_str())); + } + } + } + output +} diff --git a/vendor/annotate-snippets-0.8.0/tests/dl_from_snippet.rs b/vendor/annotate-snippets-0.8.0/tests/dl_from_snippet.rs new file mode 100644 index 000000000..2ed990261 --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/dl_from_snippet.rs @@ -0,0 +1,401 @@ +use annotate_snippets::display_list::DisplayList; +use annotate_snippets::{display_list as dl, formatter::get_term_style, snippet}; + +#[test] +fn test_format_title() { + let input = snippet::Snippet { + title: Some(snippet::Annotation { + id: Some("E0001"), + label: Some("This is a title"), + annotation_type: snippet::AnnotationType::Error, + }), + footer: vec![], + slices: vec![], + opt: Default::default(), + }; + let output = dl::DisplayList { + body: vec![dl::DisplayLine::Raw(dl::DisplayRawLine::Annotation { + annotation: dl::Annotation { + annotation_type: dl::DisplayAnnotationType::Error, + id: Some("E0001"), + label: vec![dl::DisplayTextFragment { + content: "This is a title", + style: dl::DisplayTextStyle::Emphasis, + }], + }, + source_aligned: false, + continuation: false, + })], + stylesheet: get_term_style(input.opt.color), + anonymized_line_numbers: input.opt.anonymized_line_numbers, + }; + assert_eq!(dl::DisplayList::from(input), output); +} + +#[test] +fn test_format_slice() { + let line_1 = "This is line 1"; + let line_2 = "This is line 2"; + let source = vec![line_1, line_2].join("\n"); + let input = snippet::Snippet { + title: None, + footer: vec![], + slices: vec![snippet::Slice { + source: &source, + line_start: 5402, + origin: None, + annotations: vec![], + fold: false, + }], + opt: Default::default(), + }; + let output = dl::DisplayList { + body: vec![ + dl::DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: dl::DisplaySourceLine::Empty, + }, + dl::DisplayLine::Source { + lineno: Some(5402), + inline_marks: vec![], + line: dl::DisplaySourceLine::Content { + text: line_1, + range: (0, line_1.len()), + }, + }, + dl::DisplayLine::Source { + lineno: Some(5403), + inline_marks: vec![], + line: dl::DisplaySourceLine::Content { + range: (line_1.len() + 1, source.len()), + text: line_2, + }, + }, + dl::DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: dl::DisplaySourceLine::Empty, + }, + ], + stylesheet: get_term_style(input.opt.color), + anonymized_line_numbers: input.opt.anonymized_line_numbers, + }; + assert_eq!(dl::DisplayList::from(input), output); +} + +#[test] +fn test_format_slices_continuation() { + let src_0 = "This is slice 1"; + let src_0_len = src_0.len(); + let src_1 = "This is slice 2"; + let src_1_len = src_1.len(); + let input = snippet::Snippet { + title: None, + footer: vec![], + slices: vec![ + snippet::Slice { + source: src_0, + line_start: 5402, + origin: Some("file1.rs"), + annotations: vec![], + fold: false, + }, + snippet::Slice { + source: src_1, + line_start: 2, + origin: Some("file2.rs"), + annotations: vec![], + fold: false, + }, + ], + opt: Default::default(), + }; + let output = dl::DisplayList { + body: vec![ + dl::DisplayLine::Raw(dl::DisplayRawLine::Origin { + path: "file1.rs", + pos: None, + header_type: dl::DisplayHeaderType::Initial, + }), + dl::DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: dl::DisplaySourceLine::Empty, + }, + dl::DisplayLine::Source { + lineno: Some(5402), + inline_marks: vec![], + line: dl::DisplaySourceLine::Content { + text: src_0, + range: (0, src_0_len), + }, + }, + dl::DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: dl::DisplaySourceLine::Empty, + }, + dl::DisplayLine::Raw(dl::DisplayRawLine::Origin { + path: "file2.rs", + pos: None, + header_type: dl::DisplayHeaderType::Continuation, + }), + dl::DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: dl::DisplaySourceLine::Empty, + }, + dl::DisplayLine::Source { + lineno: Some(2), + inline_marks: vec![], + line: dl::DisplaySourceLine::Content { + text: src_1, + range: (0, src_1_len), + }, + }, + dl::DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: dl::DisplaySourceLine::Empty, + }, + ], + stylesheet: get_term_style(input.opt.color), + anonymized_line_numbers: input.opt.anonymized_line_numbers, + }; + assert_eq!(dl::DisplayList::from(input), output); +} + +#[test] +fn test_format_slice_annotation_standalone() { + let line_1 = "This is line 1"; + let line_2 = "This is line 2"; + let source = vec![line_1, line_2].join("\n"); + // In line 2 + let range = (22, 24); + let input = snippet::Snippet { + title: None, + footer: vec![], + slices: vec![snippet::Slice { + source: &source, + line_start: 5402, + origin: None, + annotations: vec![snippet::SourceAnnotation { + range, + label: "Test annotation", + annotation_type: snippet::AnnotationType::Info, + }], + fold: false, + }], + opt: Default::default(), + }; + let output = dl::DisplayList { + body: vec![ + dl::DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: dl::DisplaySourceLine::Empty, + }, + dl::DisplayLine::Source { + lineno: Some(5402), + inline_marks: vec![], + line: dl::DisplaySourceLine::Content { + range: (0, line_1.len()), + text: line_1, + }, + }, + dl::DisplayLine::Source { + lineno: Some(5403), + inline_marks: vec![], + line: dl::DisplaySourceLine::Content { + range: (line_1.len() + 1, source.len()), + text: line_2, + }, + }, + dl::DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: dl::DisplaySourceLine::Annotation { + annotation: dl::Annotation { + annotation_type: dl::DisplayAnnotationType::Info, + id: None, + label: vec![dl::DisplayTextFragment { + content: "Test annotation", + style: dl::DisplayTextStyle::Regular, + }], + }, + range: (range.0 - (line_1.len() + 1), range.1 - (line_1.len() + 1)), + annotation_type: dl::DisplayAnnotationType::Info, + annotation_part: dl::DisplayAnnotationPart::Standalone, + }, + }, + dl::DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: dl::DisplaySourceLine::Empty, + }, + ], + stylesheet: get_term_style(input.opt.color), + anonymized_line_numbers: input.opt.anonymized_line_numbers, + }; + assert_eq!(dl::DisplayList::from(input), output); +} + +#[test] +fn test_format_label() { + let input = snippet::Snippet { + title: None, + footer: vec![snippet::Annotation { + id: None, + label: Some("This __is__ a title"), + annotation_type: snippet::AnnotationType::Error, + }], + slices: vec![], + opt: Default::default(), + }; + let output = dl::DisplayList { + body: vec![dl::DisplayLine::Raw(dl::DisplayRawLine::Annotation { + annotation: dl::Annotation { + annotation_type: dl::DisplayAnnotationType::Error, + id: None, + label: vec![ + dl::DisplayTextFragment { + content: "This ", + style: dl::DisplayTextStyle::Regular, + }, + dl::DisplayTextFragment { + content: "is", + style: dl::DisplayTextStyle::Emphasis, + }, + dl::DisplayTextFragment { + content: " a title", + style: dl::DisplayTextStyle::Regular, + }, + ], + }, + source_aligned: true, + continuation: false, + })], + stylesheet: get_term_style(input.opt.color), + anonymized_line_numbers: input.opt.anonymized_line_numbers, + }; + assert_eq!(dl::DisplayList::from(input), output); +} + +#[test] +#[should_panic] +fn test_i26() { + let source = "short"; + let label = "label"; + let input = snippet::Snippet { + title: None, + footer: vec![], + slices: vec![snippet::Slice { + annotations: vec![snippet::SourceAnnotation { + range: (0, source.len() + 1), + label, + annotation_type: snippet::AnnotationType::Error, + }], + source, + line_start: 0, + origin: None, + fold: false, + }], + opt: Default::default(), + }; + + let _ = dl::DisplayList::from(input); +} + +#[test] +fn test_i_29() { + let snippets = snippet::Snippet { + title: Some(snippet::Annotation { + id: None, + label: Some("oops"), + annotation_type: snippet::AnnotationType::Error, + }), + footer: vec![], + slices: vec![snippet::Slice { + source: "First line\r\nSecond oops line", + line_start: 1, + origin: Some("<current file>"), + annotations: vec![snippet::SourceAnnotation { + range: (19, 23), + label: "oops", + annotation_type: snippet::AnnotationType::Error, + }], + fold: true, + }], + opt: Default::default(), + }; + + let expected = DisplayList { + body: vec![ + dl::DisplayLine::Raw(dl::DisplayRawLine::Annotation { + annotation: dl::Annotation { + annotation_type: dl::DisplayAnnotationType::Error, + id: None, + label: vec![dl::DisplayTextFragment { + content: "oops", + style: dl::DisplayTextStyle::Emphasis, + }], + }, + source_aligned: false, + continuation: false, + }), + dl::DisplayLine::Raw(dl::DisplayRawLine::Origin { + path: "<current file>", + pos: Some((2, 8)), + header_type: dl::DisplayHeaderType::Initial, + }), + dl::DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: dl::DisplaySourceLine::Empty, + }, + dl::DisplayLine::Source { + lineno: Some(1), + inline_marks: vec![], + line: dl::DisplaySourceLine::Content { + text: "First line", + range: (0, 10), + }, + }, + dl::DisplayLine::Source { + lineno: Some(2), + inline_marks: vec![], + line: dl::DisplaySourceLine::Content { + text: "Second oops line", + range: (12, 28), + }, + }, + dl::DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: dl::DisplaySourceLine::Annotation { + annotation: dl::Annotation { + annotation_type: dl::DisplayAnnotationType::None, + id: None, + label: vec![dl::DisplayTextFragment { + content: "oops", + style: dl::DisplayTextStyle::Regular, + }], + }, + range: (7, 11), + annotation_type: dl::DisplayAnnotationType::Error, + annotation_part: dl::DisplayAnnotationPart::Standalone, + }, + }, + dl::DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: dl::DisplaySourceLine::Empty, + }, + ], + stylesheet: get_term_style(false), + anonymized_line_numbers: false, + }; + + assert_eq!(DisplayList::from(snippets), expected); +} diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.toml b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.toml new file mode 100644 index 000000000..bdb577f46 --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.toml @@ -0,0 +1,40 @@ +[[slices]] +source = """ +) -> Option<String> { + for ann in annotations { + match (ann.range.0, ann.range.1) { + (None, None) => continue, + (Some(start), Some(end)) if start > end_index || end < start_index => continue, + (Some(start), Some(end)) if start >= start_index && end <= end_index => { + let label = if let Some(ref label) = ann.label { + format!(" {}", label) + } else { + String::from("") + }; + + return Some(format!( + "{}{}{}", + " ".repeat(start - start_index), + "^".repeat(end - start), + label + )); + } + _ => continue, + } + } +""" +line_start = 51 +origin = "src/format.rs" +fold = true +[[slices.annotations]] +label = "expected `std::option::Option<std::string::String>` because of return type" +annotation_type = "Warning" +range = [5, 19] +[[slices.annotations]] +label = "expected enum `std::option::Option`, found ()" +annotation_type = "Error" +range = [22, 765] +[title] +label = "mismatched types" +id = "E0308" +annotation_type = "Error" diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.txt b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.txt new file mode 100644 index 000000000..bacdec10d --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation.txt @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> src/format.rs:51:6 + | +51 | ) -> Option<String> { + | -------------- expected `std::option::Option<std::string::String>` because of return type +52 | / for ann in annotations { +53 | | match (ann.range.0, ann.range.1) { +54 | | (None, None) => continue, +55 | | (Some(start), Some(end)) if start > end_index || end < start_index => continue, +... | +71 | | } +72 | | } + | |_____^ expected enum `std::option::Option`, found () + | diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.toml b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.toml new file mode 100644 index 000000000..6ec0b1fe8 --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.toml @@ -0,0 +1,18 @@ +[[slices]] +source = """ + if let DisplayLine::Source { + ref mut inline_marks, + } = body[body_idx] +""" +line_start = 139 +origin = "src/display_list.rs" +fold = false +[[slices.annotations]] +label = "missing fields `lineno`, `content`" +annotation_type = "Error" +range = [31, 127] + +[title] +label = "pattern does not mention fields `lineno`, `content`" +id = "E0027" +annotation_type = "Error" diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.txt b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.txt new file mode 100644 index 000000000..8a00bfa20 --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation2.txt @@ -0,0 +1,9 @@ +error[E0027]: pattern does not mention fields `lineno`, `content` + --> src/display_list.rs:139:32 + | +139 | if let DisplayLine::Source { + | ________________________________^ +140 | | ref mut inline_marks, +141 | | } = body[body_idx] + | |_________________________^ missing fields `lineno`, `content` + | diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.toml b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.toml new file mode 100644 index 000000000..21bbcd857 --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.toml @@ -0,0 +1,18 @@ +[[slices]] +source = """ +This is an exampl +e of an edge case of an annotation overflowing +to exactly one character on next line. +""" +line_start = 26 +origin = "foo.txt" +fold = false +[[slices.annotations]] +label = "this should not be on separate lines" +annotation_type = "Error" +range = [11, 18] + +[title] +label = "spacing error found" +id = "E####" +annotation_type = "Error" diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.txt b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.txt new file mode 100644 index 000000000..12e174c56 --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiline_annotation3.txt @@ -0,0 +1,9 @@ +error[E####]: spacing error found + --> foo.txt:26:12 + | +26 | This is an exampl + | ____________^ +27 | | e of an edge case of an annotation overflowing + | |_^ this should not be on separate lines +28 | to exactly one character on next line. + |
\ No newline at end of file diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.toml b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.toml new file mode 100644 index 000000000..84efc5f17 --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.toml @@ -0,0 +1,25 @@ +[[slices]] +source = """ +fn add_title_line(result: &mut Vec<String>, main_annotation: Option<&Annotation>) { + if let Some(annotation) = main_annotation { + result.push(format_title_line( + &annotation.annotation_type, + None, + &annotation.label, + )); + } +} +""" +line_start = 96 +[[slices.annotations]] +label = "Variable defined here" +annotation_type = "Error" +range = [100, 110] +[[slices.annotations]] +label = "Referenced here" +annotation_type = "Error" +range = [184, 194] +[[slices.annotations]] +label = "Referenced again here" +annotation_type = "Error" +range = [243, 253] diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.txt b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.txt new file mode 100644 index 000000000..26c677f7e --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/multiple_annotations.txt @@ -0,0 +1,14 @@ + | + 96 | fn add_title_line(result: &mut Vec<String>, main_annotation: Option<&Annotation>) { + 97 | if let Some(annotation) = main_annotation { + | ^^^^^^^^^^ Variable defined here + 98 | result.push(format_title_line( + 99 | &annotation.annotation_type, + | ^^^^^^^^^^ Referenced here +100 | None, +101 | &annotation.label, + | ^^^^^^^^^^ Referenced again here +102 | )); +103 | } +104 | } + | diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.toml b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.toml new file mode 100644 index 000000000..6c38674ac --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.toml @@ -0,0 +1,18 @@ +[[slices]] +source = """ + }) + + for line in &self.body {""" +line_start = 169 +origin = "src/format_color.rs" +[[slices.annotations]] +label = "unexpected token" +annotation_type = "Error" +range = [20, 23] +[[slices.annotations]] +label = "expected one of `.`, `;`, `?`, or an operator here" +annotation_type = "Warning" +range = [10, 11] +[title] +label = "expected one of `.`, `;`, `?`, or an operator, found `for`" +annotation_type = "Error" diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.txt b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.txt new file mode 100644 index 000000000..752cc890f --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/fixtures/no-color/simple.txt @@ -0,0 +1,9 @@ +error: expected one of `.`, `;`, `?`, or an operator, found `for` + --> src/format_color.rs:171:9 + | +169 | }) + | - expected one of `.`, `;`, `?`, or an operator here +170 | +171 | for line in &self.body { + | ^^^ unexpected token + | diff --git a/vendor/annotate-snippets-0.8.0/tests/fixtures_test.rs b/vendor/annotate-snippets-0.8.0/tests/fixtures_test.rs new file mode 100644 index 000000000..e471521f2 --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/fixtures_test.rs @@ -0,0 +1,45 @@ +mod diff; +mod snippet; + +use crate::snippet::SnippetDef; +use annotate_snippets::{display_list::DisplayList, snippet::Snippet}; +use glob::glob; +use std::{error::Error, fs::File, io, io::prelude::*}; + +fn read_file(path: &str) -> Result<String, io::Error> { + let mut f = File::open(path)?; + let mut s = String::new(); + (f.read_to_string(&mut s))?; + Ok(s.trim_end().to_string()) +} + +fn read_fixture<'de>(src: &'de str) -> Result<Snippet<'de>, Box<dyn Error>> { + Ok(toml::from_str(src).map(|a: SnippetDef| a.into())?) +} + +#[test] +fn test_fixtures() { + for entry in glob("./tests/fixtures/no-color/**/*.toml").expect("Failed to read glob pattern") { + let p = entry.expect("Error while getting an entry"); + + let path_in = p.to_str().expect("Can't print path"); + let path_out = path_in.replace(".toml", ".txt"); + + let src = read_file(&path_in).expect("Failed to read file"); + let snippet = read_fixture(&src).expect("Failed to read file"); + let expected_out = read_file(&path_out).expect("Failed to read file"); + + let dl = DisplayList::from(snippet); + let actual_out = dl.to_string(); + println!("{}", expected_out); + println!("{}", actual_out.trim_end()); + + assert_eq!( + expected_out, + actual_out.trim_end(), + "\n\n\nWhile parsing: {}\nThe diff is:\n\n\n{}\n\n\n", + path_in, + diff::get_diff(expected_out.as_str(), actual_out.as_str()) + ); + } +} diff --git a/vendor/annotate-snippets-0.8.0/tests/formatter.rs b/vendor/annotate-snippets-0.8.0/tests/formatter.rs new file mode 100644 index 000000000..5c7211d1e --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/formatter.rs @@ -0,0 +1,552 @@ +use annotate_snippets::display_list::*; +use annotate_snippets::snippet::{self, Snippet}; + +#[test] +fn test_source_empty() { + let dl = DisplayList::from(vec![DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: DisplaySourceLine::Empty, + }]); + + assert_eq!(dl.to_string(), " |"); +} + +#[test] +fn test_source_content() { + let dl = DisplayList::from(vec![ + DisplayLine::Source { + lineno: Some(56), + inline_marks: vec![], + line: DisplaySourceLine::Content { + text: "This is an example", + range: (0, 19), + }, + }, + DisplayLine::Source { + lineno: Some(57), + inline_marks: vec![], + line: DisplaySourceLine::Content { + text: "of content lines", + range: (0, 19), + }, + }, + ]); + + assert_eq!( + dl.to_string(), + "56 | This is an example\n57 | of content lines" + ); +} + +#[test] +fn test_source_annotation_standalone_singleline() { + let dl = DisplayList::from(vec![DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: DisplaySourceLine::Annotation { + range: (0, 5), + annotation: Annotation { + annotation_type: DisplayAnnotationType::None, + id: None, + label: vec![DisplayTextFragment { + content: "Example string", + style: DisplayTextStyle::Regular, + }], + }, + annotation_type: DisplayAnnotationType::Error, + annotation_part: DisplayAnnotationPart::Standalone, + }, + }]); + + assert_eq!(dl.to_string(), " | ^^^^^ Example string"); +} + +#[test] +fn test_source_annotation_standalone_multiline() { + let dl = DisplayList::from(vec![ + DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: DisplaySourceLine::Annotation { + range: (0, 5), + annotation: Annotation { + annotation_type: DisplayAnnotationType::Help, + id: None, + label: vec![DisplayTextFragment { + content: "Example string", + style: DisplayTextStyle::Regular, + }], + }, + annotation_type: DisplayAnnotationType::Warning, + annotation_part: DisplayAnnotationPart::Standalone, + }, + }, + DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: DisplaySourceLine::Annotation { + range: (0, 5), + annotation: Annotation { + annotation_type: DisplayAnnotationType::Help, + id: None, + label: vec![DisplayTextFragment { + content: "Second line", + style: DisplayTextStyle::Regular, + }], + }, + annotation_type: DisplayAnnotationType::Warning, + annotation_part: DisplayAnnotationPart::LabelContinuation, + }, + }, + ]); + + assert_eq!( + dl.to_string(), + " | ----- help: Example string\n | Second line" + ); +} + +#[test] +fn test_source_annotation_standalone_multi_annotation() { + let dl = DisplayList::from(vec![ + DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: DisplaySourceLine::Annotation { + range: (0, 5), + annotation: Annotation { + annotation_type: DisplayAnnotationType::Info, + id: None, + label: vec![DisplayTextFragment { + content: "Example string", + style: DisplayTextStyle::Regular, + }], + }, + annotation_type: DisplayAnnotationType::Note, + annotation_part: DisplayAnnotationPart::Standalone, + }, + }, + DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: DisplaySourceLine::Annotation { + range: (0, 5), + annotation: Annotation { + annotation_type: DisplayAnnotationType::Info, + id: None, + label: vec![DisplayTextFragment { + content: "Second line", + style: DisplayTextStyle::Regular, + }], + }, + annotation_type: DisplayAnnotationType::Note, + annotation_part: DisplayAnnotationPart::LabelContinuation, + }, + }, + DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: DisplaySourceLine::Annotation { + range: (0, 5), + annotation: Annotation { + annotation_type: DisplayAnnotationType::Warning, + id: None, + label: vec![DisplayTextFragment { + content: "This is a note", + style: DisplayTextStyle::Regular, + }], + }, + annotation_type: DisplayAnnotationType::Note, + annotation_part: DisplayAnnotationPart::Consequitive, + }, + }, + DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: DisplaySourceLine::Annotation { + range: (0, 5), + annotation: Annotation { + annotation_type: DisplayAnnotationType::Warning, + id: None, + label: vec![DisplayTextFragment { + content: "Second line of the warning", + style: DisplayTextStyle::Regular, + }], + }, + annotation_type: DisplayAnnotationType::Note, + annotation_part: DisplayAnnotationPart::LabelContinuation, + }, + }, + DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: DisplaySourceLine::Annotation { + range: (0, 5), + annotation: Annotation { + annotation_type: DisplayAnnotationType::Info, + id: None, + label: vec![DisplayTextFragment { + content: "This is an info", + style: DisplayTextStyle::Regular, + }], + }, + annotation_type: DisplayAnnotationType::Info, + annotation_part: DisplayAnnotationPart::Standalone, + }, + }, + DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: DisplaySourceLine::Annotation { + range: (0, 5), + annotation: Annotation { + annotation_type: DisplayAnnotationType::Help, + id: None, + label: vec![DisplayTextFragment { + content: "This is help", + style: DisplayTextStyle::Regular, + }], + }, + annotation_type: DisplayAnnotationType::Help, + annotation_part: DisplayAnnotationPart::Standalone, + }, + }, + DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: DisplaySourceLine::Annotation { + range: (0, 0), + annotation: Annotation { + annotation_type: DisplayAnnotationType::None, + id: None, + label: vec![DisplayTextFragment { + content: "This is an annotation of type none", + style: DisplayTextStyle::Regular, + }], + }, + annotation_type: DisplayAnnotationType::None, + annotation_part: DisplayAnnotationPart::Standalone, + }, + }, + ]); + + 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"); +} + +#[test] +fn test_fold_line() { + let dl = DisplayList::from(vec![ + DisplayLine::Source { + lineno: Some(5), + inline_marks: vec![], + line: DisplaySourceLine::Content { + text: "This is line 5", + range: (0, 19), + }, + }, + DisplayLine::Fold { + inline_marks: vec![], + }, + DisplayLine::Source { + lineno: Some(10021), + inline_marks: vec![], + line: DisplaySourceLine::Content { + text: "... and now we're at line 10021", + range: (0, 19), + }, + }, + ]); + + assert_eq!( + dl.to_string(), + " 5 | This is line 5\n...\n10021 | ... and now we're at line 10021" + ); +} + +#[test] +fn test_raw_origin_initial_nopos() { + let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Origin { + path: "src/test.rs", + pos: None, + header_type: DisplayHeaderType::Initial, + })]); + + assert_eq!(dl.to_string(), "--> src/test.rs"); +} + +#[test] +fn test_raw_origin_initial_pos() { + let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Origin { + path: "src/test.rs", + pos: Some((23, 15)), + header_type: DisplayHeaderType::Initial, + })]); + + assert_eq!(dl.to_string(), "--> src/test.rs:23:15"); +} + +#[test] +fn test_raw_origin_continuation() { + let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Origin { + path: "src/test.rs", + pos: Some((23, 15)), + header_type: DisplayHeaderType::Continuation, + })]); + + assert_eq!(dl.to_string(), "::: src/test.rs:23:15"); +} + +#[test] +fn test_raw_annotation_unaligned() { + let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Annotation { + annotation: Annotation { + annotation_type: DisplayAnnotationType::Error, + id: Some("E0001"), + label: vec![DisplayTextFragment { + content: "This is an error", + style: DisplayTextStyle::Regular, + }], + }, + source_aligned: false, + continuation: false, + })]); + + assert_eq!(dl.to_string(), "error[E0001]: This is an error"); +} + +#[test] +fn test_raw_annotation_unaligned_multiline() { + let dl = DisplayList::from(vec![ + DisplayLine::Raw(DisplayRawLine::Annotation { + annotation: Annotation { + annotation_type: DisplayAnnotationType::Warning, + id: Some("E0001"), + label: vec![DisplayTextFragment { + content: "This is an error", + style: DisplayTextStyle::Regular, + }], + }, + source_aligned: false, + continuation: false, + }), + DisplayLine::Raw(DisplayRawLine::Annotation { + annotation: Annotation { + annotation_type: DisplayAnnotationType::Warning, + id: Some("E0001"), + label: vec![DisplayTextFragment { + content: "Second line of the error", + style: DisplayTextStyle::Regular, + }], + }, + source_aligned: false, + continuation: true, + }), + ]); + + assert_eq!( + dl.to_string(), + "warning[E0001]: This is an error\n Second line of the error" + ); +} + +#[test] +fn test_raw_annotation_aligned() { + let dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Annotation { + annotation: Annotation { + annotation_type: DisplayAnnotationType::Error, + id: Some("E0001"), + label: vec![DisplayTextFragment { + content: "This is an error", + style: DisplayTextStyle::Regular, + }], + }, + source_aligned: true, + continuation: false, + })]); + + assert_eq!(dl.to_string(), " = error[E0001]: This is an error"); +} + +#[test] +fn test_raw_annotation_aligned_multiline() { + let dl = DisplayList::from(vec![ + DisplayLine::Raw(DisplayRawLine::Annotation { + annotation: Annotation { + annotation_type: DisplayAnnotationType::Warning, + id: Some("E0001"), + label: vec![DisplayTextFragment { + content: "This is an error", + style: DisplayTextStyle::Regular, + }], + }, + source_aligned: true, + continuation: false, + }), + DisplayLine::Raw(DisplayRawLine::Annotation { + annotation: Annotation { + annotation_type: DisplayAnnotationType::Warning, + id: Some("E0001"), + label: vec![DisplayTextFragment { + content: "Second line of the error", + style: DisplayTextStyle::Regular, + }], + }, + source_aligned: true, + continuation: true, + }), + ]); + + assert_eq!( + dl.to_string(), + " = warning[E0001]: This is an error\n Second line of the error" + ); +} + +#[test] +fn test_different_annotation_types() { + let dl = DisplayList::from(vec![ + DisplayLine::Raw(DisplayRawLine::Annotation { + annotation: Annotation { + annotation_type: DisplayAnnotationType::Note, + id: None, + label: vec![DisplayTextFragment { + content: "This is a note", + style: DisplayTextStyle::Regular, + }], + }, + source_aligned: false, + continuation: false, + }), + DisplayLine::Raw(DisplayRawLine::Annotation { + annotation: Annotation { + annotation_type: DisplayAnnotationType::None, + id: None, + label: vec![DisplayTextFragment { + content: "This is just a string", + style: DisplayTextStyle::Regular, + }], + }, + source_aligned: false, + continuation: false, + }), + DisplayLine::Raw(DisplayRawLine::Annotation { + annotation: Annotation { + annotation_type: DisplayAnnotationType::None, + id: None, + label: vec![DisplayTextFragment { + content: "Second line of none type annotation", + style: DisplayTextStyle::Regular, + }], + }, + source_aligned: false, + continuation: true, + }), + ]); + + assert_eq!( + dl.to_string(), + "note: This is a note\nThis is just a string\n Second line of none type annotation", + ); +} + +#[test] +fn test_inline_marks_empty_line() { + let dl = DisplayList::from(vec![DisplayLine::Source { + lineno: None, + inline_marks: vec![DisplayMark { + mark_type: DisplayMarkType::AnnotationThrough, + annotation_type: DisplayAnnotationType::Error, + }], + line: DisplaySourceLine::Empty, + }]); + + assert_eq!(dl.to_string(), " | |",); +} + +#[test] +fn test_anon_lines() { + let mut dl = DisplayList::from(vec![ + DisplayLine::Source { + lineno: Some(56), + inline_marks: vec![], + line: DisplaySourceLine::Content { + text: "This is an example", + range: (0, 19), + }, + }, + DisplayLine::Source { + lineno: Some(57), + inline_marks: vec![], + line: DisplaySourceLine::Content { + text: "of content lines", + range: (0, 19), + }, + }, + DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: DisplaySourceLine::Empty, + }, + DisplayLine::Source { + lineno: None, + inline_marks: vec![], + line: DisplaySourceLine::Content { + text: "abc", + range: (0, 19), + }, + }, + ]); + + dl.anonymized_line_numbers = true; + assert_eq!( + dl.to_string(), + "LL | This is an example\nLL | of content lines\n |\n | abc" + ); +} + +#[test] +fn test_raw_origin_initial_pos_anon_lines() { + let mut dl = DisplayList::from(vec![DisplayLine::Raw(DisplayRawLine::Origin { + path: "src/test.rs", + pos: Some((23, 15)), + header_type: DisplayHeaderType::Initial, + })]); + + // Using anonymized_line_numbers should not affect the inital position + dl.anonymized_line_numbers = true; + assert_eq!(dl.to_string(), "--> src/test.rs:23:15"); +} + +#[test] +fn test_i_29() { + let snippets = Snippet { + title: Some(snippet::Annotation { + id: None, + label: Some("oops"), + annotation_type: snippet::AnnotationType::Error, + }), + footer: vec![], + slices: vec![snippet::Slice { + source: "First line\r\nSecond oops line", + line_start: 1, + origin: Some("<current file>"), + annotations: vec![snippet::SourceAnnotation { + range: (19, 23), + label: "oops", + annotation_type: snippet::AnnotationType::Error, + }], + fold: true, + }], + opt: Default::default(), + }; + let expected = r#"error: oops + --> <current file>:2:8 + | +1 | First line +2 | Second oops line + | ^^^^ oops + |"#; + + assert_eq!(DisplayList::from(snippets).to_string(), expected); +} diff --git a/vendor/annotate-snippets-0.8.0/tests/snippet/mod.rs b/vendor/annotate-snippets-0.8.0/tests/snippet/mod.rs new file mode 100644 index 000000000..c3348741a --- /dev/null +++ b/vendor/annotate-snippets-0.8.0/tests/snippet/mod.rs @@ -0,0 +1,167 @@ +use serde::{Deserialize, Deserializer, Serialize}; + +use annotate_snippets::{ + display_list::FormatOptions, + snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation}, +}; + +#[derive(Deserialize)] +pub struct SnippetDef<'a> { + #[serde(deserialize_with = "deserialize_annotation")] + #[serde(default)] + #[serde(borrow)] + pub title: Option<Annotation<'a>>, + #[serde(deserialize_with = "deserialize_annotations")] + #[serde(default)] + #[serde(borrow)] + pub footer: Vec<Annotation<'a>>, + #[serde(deserialize_with = "deserialize_opt")] + #[serde(default)] + pub opt: FormatOptions, + #[serde(deserialize_with = "deserialize_slices")] + #[serde(borrow)] + pub slices: Vec<Slice<'a>>, +} + +impl<'a> Into<Snippet<'a>> for SnippetDef<'a> { + fn into(self) -> Snippet<'a> { + let SnippetDef { + title, + footer, + opt, + slices, + } = self; + Snippet { + title, + footer, + slices, + opt, + } + } +} + +fn deserialize_opt<'de, D>(deserializer: D) -> Result<FormatOptions, D::Error> +where + D: Deserializer<'de>, +{ + #[derive(Deserialize)] + struct Wrapper(#[serde(with = "FormatOptionsDef")] FormatOptions); + + Wrapper::deserialize(deserializer).map(|w| w.0) +} + +#[derive(Deserialize)] +#[serde(remote = "FormatOptions")] +pub struct FormatOptionsDef { + pub color: bool, + pub anonymized_line_numbers: bool, +} + +fn deserialize_slices<'de, D>(deserializer: D) -> Result<Vec<Slice<'de>>, D::Error> +where + D: Deserializer<'de>, +{ + #[derive(Deserialize)] + struct Wrapper<'a>( + #[serde(with = "SliceDef")] + #[serde(borrow)] + Slice<'a>, + ); + + let v = Vec::deserialize(deserializer)?; + Ok(v.into_iter().map(|Wrapper(a)| a).collect()) +} + +fn deserialize_annotation<'de, D>(deserializer: D) -> Result<Option<Annotation<'de>>, D::Error> +where + D: Deserializer<'de>, +{ + #[derive(Deserialize)] + struct Wrapper<'a>( + #[serde(with = "AnnotationDef")] + #[serde(borrow)] + Annotation<'a>, + ); + + Option::<Wrapper>::deserialize(deserializer) + .map(|opt_wrapped: Option<Wrapper>| opt_wrapped.map(|wrapped: Wrapper| wrapped.0)) +} + +fn deserialize_annotations<'de, D>(deserializer: D) -> Result<Vec<Annotation<'de>>, D::Error> +where + D: Deserializer<'de>, +{ + #[derive(Deserialize)] + struct Wrapper<'a>( + #[serde(with = "AnnotationDef")] + #[serde(borrow)] + Annotation<'a>, + ); + + let v = Vec::deserialize(deserializer)?; + Ok(v.into_iter().map(|Wrapper(a)| a).collect()) +} + +#[derive(Deserialize)] +#[serde(remote = "Slice")] +pub struct SliceDef<'a> { + #[serde(borrow)] + pub source: &'a str, + pub line_start: usize, + #[serde(borrow)] + pub origin: Option<&'a str>, + #[serde(deserialize_with = "deserialize_source_annotations")] + #[serde(borrow)] + pub annotations: Vec<SourceAnnotation<'a>>, + #[serde(default)] + pub fold: bool, +} + +fn deserialize_source_annotations<'de, D>( + deserializer: D, +) -> Result<Vec<SourceAnnotation<'de>>, D::Error> +where + D: Deserializer<'de>, +{ + #[derive(Deserialize)] + struct Wrapper<'a>( + #[serde(with = "SourceAnnotationDef")] + #[serde(borrow)] + SourceAnnotation<'a>, + ); + + let v = Vec::deserialize(deserializer)?; + Ok(v.into_iter().map(|Wrapper(a)| a).collect()) +} + +#[derive(Serialize, Deserialize)] +#[serde(remote = "SourceAnnotation")] +pub struct SourceAnnotationDef<'a> { + pub range: (usize, usize), + #[serde(borrow)] + pub label: &'a str, + #[serde(with = "AnnotationTypeDef")] + pub annotation_type: AnnotationType, +} + +#[derive(Serialize, Deserialize)] +#[serde(remote = "Annotation")] +pub struct AnnotationDef<'a> { + #[serde(borrow)] + pub id: Option<&'a str>, + #[serde(borrow)] + pub label: Option<&'a str>, + #[serde(with = "AnnotationTypeDef")] + pub annotation_type: AnnotationType, +} + +#[allow(dead_code)] +#[derive(Serialize, Deserialize)] +#[serde(remote = "AnnotationType")] +enum AnnotationTypeDef { + Error, + Warning, + Info, + Note, + Help, +} |