diff --git a/src/source.rs b/src/source.rs index 69aea3f..9038ee4 100644 --- a/src/source.rs +++ b/src/source.rs @@ -108,6 +108,22 @@ impl> From for Source { /// /// Note that this function can be expensive for long strings. Use an implementor of [`Cache`] where possible. fn from(input: I) -> Self { + // `input.split_inclusive()` will not iterate at all, + // but an empty input still ought to count as a single empty line. + if input.as_ref().is_empty() { + return Self { + text: input, + lines: vec![Line { + offset: 0, + char_len: 0, + byte_offset: 0, + byte_len: 0, + }], + len: 0, + byte_len: 0, + }; + } + let mut char_offset = 0; let mut byte_offset = 0; let mut lines = Vec::new(); @@ -383,7 +399,7 @@ mod tests { #[test] fn source_from_empty() { - test_with_lines(vec![]); // Empty string + test_with_lines(vec![""]); // Empty string } #[test] diff --git a/src/write.rs b/src/write.rs index c867518..c667fa1 100644 --- a/src/write.rs +++ b/src/write.rs @@ -1097,6 +1097,102 @@ mod tests { "###); } + #[test] + fn empty_input() { + let source = ""; + let msg = Report::>::build(ReportKind::Error, (), 0) + .with_config(no_color_and_ascii()) + .with_message("unexpected end of file") + .with_label(Label::new(0..0).with_message("No more fruit!")) + .finish() + .write_to_string(Source::from(source)); + + assert_snapshot!(msg, @r###" + Error: unexpected end of file + ,-[:1:1] + | + 1 | + | | + | `- No more fruit! + ---' + "###); + } + + #[test] + fn empty_input_help() { + let source = ""; + let msg = Report::>::build(ReportKind::Error, (), 0) + .with_config(no_color_and_ascii()) + .with_message("unexpected end of file") + .with_label(Label::new(0..0).with_message("No more fruit!")) + .with_help("have you tried going to the farmer's market?") + .finish() + .write_to_string(Source::from(source)); + + assert_snapshot!(msg, @r###" + Error: unexpected end of file + ,-[:1:1] + | + 1 | + | | + | `- No more fruit! + | + | Help: have you tried going to the farmer's market? + ---' + "###); + } + + #[test] + fn empty_input_note() { + let source = ""; + let msg = Report::>::build(ReportKind::Error, (), 0) + .with_config(no_color_and_ascii()) + .with_message("unexpected end of file") + .with_label(Label::new(0..0).with_message("No more fruit!")) + .with_note("eat your greens!") + .finish() + .write_to_string(Source::from(source)); + + assert_snapshot!(msg, @r###" + Error: unexpected end of file + ,-[:1:1] + | + 1 | + | | + | `- No more fruit! + | + | Note: eat your greens! + ---' + "###); + } + + #[test] + fn empty_input_help_note() { + let source = ""; + let msg = Report::>::build(ReportKind::Error, (), 0) + .with_config(no_color_and_ascii()) + .with_message("unexpected end of file") + .with_label(Label::new(0..0).with_message("No more fruit!")) + .with_note("eat your greens!") + .with_help("have you tried going to the farmer's market?") + .finish() + .write_to_string(Source::from(source)); + + assert_snapshot!(msg, @r###" + Error: unexpected end of file + ,-[:1:1] + | + 1 | + | | + | `- No more fruit! + | + | Help: have you tried going to the farmer's market? + | + | Note: eat your greens! + ---' + "###); + } + #[test] fn byte_spans_never_crash() { let source = "apple\np\n\nempty\n";