diff --git a/src/eyreish/wrapper.rs b/src/eyreish/wrapper.rs index 6e65eb72..01f64f09 100644 --- a/src/eyreish/wrapper.rs +++ b/src/eyreish/wrapper.rs @@ -283,7 +283,7 @@ mod tests { report .source_code() .unwrap() - .read_span(&(0..5).into(), 0, 0) + .read_span(&(0..5).into(), None, None) .unwrap() .data() .to_vec(), diff --git a/src/handlers/graphical.rs b/src/handlers/graphical.rs index 362aaf60..bc8226c8 100644 --- a/src/handlers/graphical.rs +++ b/src/handlers/graphical.rs @@ -28,7 +28,7 @@ pub struct GraphicalReportHandler { pub(crate) termwidth: usize, pub(crate) theme: GraphicalTheme, pub(crate) footer: Option, - pub(crate) context_lines: usize, + pub(crate) context_lines: Option, pub(crate) tab_width: usize, pub(crate) with_cause_chain: bool, pub(crate) wrap_lines: bool, @@ -55,7 +55,7 @@ impl GraphicalReportHandler { termwidth: 200, theme: GraphicalTheme::default(), footer: None, - context_lines: 1, + context_lines: Some(1), tab_width: 4, with_cause_chain: true, wrap_lines: true, @@ -74,7 +74,7 @@ impl GraphicalReportHandler { termwidth: 200, theme, footer: None, - context_lines: 1, + context_lines: Some(1), tab_width: 4, wrap_lines: true, with_cause_chain: true, @@ -159,7 +159,7 @@ impl GraphicalReportHandler { self } - /// Sets the word splitter to usewhen wrapping. + /// Sets the word splitter to use when wrapping. pub fn with_word_splitter(mut self, word_splitter: textwrap::WordSplitter) -> Self { self.word_splitter = Some(word_splitter); self @@ -172,7 +172,22 @@ impl GraphicalReportHandler { } /// Sets the number of lines of context to show around each error. - pub fn with_context_lines(mut self, lines: usize) -> Self { + /// + /// If `0`, then only the span content will be shown (equivalent to + /// `with_opt_context_lines(None)`).\ + /// Use `with_opt_context_lines(Some(0))` if you want the whole line + /// containing the error without extra context. + pub fn with_context_lines(self, lines: usize) -> Self { + self.with_opt_context_lines((lines != 0).then_some(lines)) + } + + /// Sets the number of lines of context to show around each error. + /// + /// `None` means only the span content (and possibly the content in between + /// multiple adjacent labels) will be shown.\ + /// `Some(0)` will show the whole line containing the label.\ + /// `Some(n)` will show the whole line plus n line before and after the label. + pub fn with_opt_context_lines(mut self, lines: Option) -> Self { self.context_lines = lines; self } @@ -559,7 +574,7 @@ impl GraphicalReportHandler { // as the reference point for line/column information. let primary_contents = match primary_label { Some(label) => source - .read_span(label.inner(), 0, 0) + .read_span(label.inner(), None, None) .map_err(|_| fmt::Error)?, None => contents, }; diff --git a/src/handlers/json.rs b/src/handlers/json.rs index 0b4a405b..1ae06d35 100644 --- a/src/handlers/json.rs +++ b/src/handlers/json.rs @@ -159,7 +159,7 @@ impl JSONReportHandler { ) -> fmt::Result { if let Some(mut labels) = diagnostic.labels() { if let Some(label) = labels.next() { - if let Ok(span_content) = source.read_span(label.inner(), 0, 0) { + if let Ok(span_content) = source.read_span(label.inner(), None, None) { let filename = span_content.name().unwrap_or_default(); return write!(f, r#""filename": "{}","#, escape(filename)); } diff --git a/src/handlers/narratable.rs b/src/handlers/narratable.rs index 0855affe..23bba852 100644 --- a/src/handlers/narratable.rs +++ b/src/handlers/narratable.rs @@ -13,7 +13,7 @@ non-graphical environments, such as non-TTY output. */ #[derive(Debug, Clone)] pub struct NarratableReportHandler { - context_lines: usize, + context_lines: Option, with_cause_chain: bool, footer: Option, } @@ -24,7 +24,7 @@ impl NarratableReportHandler { pub const fn new() -> Self { Self { footer: None, - context_lines: 1, + context_lines: Some(1), with_cause_chain: true, } } @@ -49,7 +49,22 @@ impl NarratableReportHandler { } /// Sets the number of lines of context to show around each error. - pub const fn with_context_lines(mut self, lines: usize) -> Self { + /// + /// If `0`, then only the span content will be shown (equivalent to + /// `with_opt_context_lines(None)`).\ + /// Use `with_opt_context_lines(Some(0))` if you want the whole line + /// containing the error without extra context. + pub fn with_context_lines(self, lines: usize) -> Self { + self.with_opt_context_lines((lines != 0).then_some(lines)) + } + + /// Sets the number of lines of context to show around each error. + /// + /// `None` means only the span content (and possibly the content in between + /// multiple adjacent labels) will be shown.\ + /// `Some(0)` will show the whole line containing the label.\ + /// `Some(n)` will show the whole line plus n line before and after the label. + pub fn with_opt_context_lines(mut self, lines: Option) -> Self { self.context_lines = lines; self } diff --git a/src/named_source.rs b/src/named_source.rs index ea11cd2c..371a6706 100644 --- a/src/named_source.rs +++ b/src/named_source.rs @@ -56,8 +56,8 @@ impl SourceCode for NamedSource { fn read_span<'a>( &'a self, span: &crate::SourceSpan, - context_lines_before: usize, - context_lines_after: usize, + context_lines_before: Option, + context_lines_after: Option, ) -> Result + 'a>, MietteError> { let inner_contents = self.inner() diff --git a/src/protocol.rs b/src/protocol.rs index 589cd0b5..f02a4b55 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -247,11 +247,16 @@ gigabytes or larger in size. pub trait SourceCode: Send + Sync { /// Read the bytes for a specific span from this `SourceCode`, keeping a /// certain number of lines before and after the span as context. + /// When the `context_lines_before` (resp. `context_lines_after`) is set to + /// `None`, the span content must start (resp. stop) at the **span** boundary. + /// When set to `Some(0)`, the content should start (resp. stop) at the + /// **line** boundary. When set to `Some(n)`, the content should include the + /// _n_ lines before (resp. after) the span. fn read_span<'a>( &'a self, span: &SourceSpan, - context_lines_before: usize, - context_lines_after: usize, + context_lines_before: Option, + context_lines_after: Option, ) -> Result + 'a>, MietteError>; } diff --git a/src/source_impls.rs b/src/source_impls.rs index ef18a9d0..08f64d74 100644 --- a/src/source_impls.rs +++ b/src/source_impls.rs @@ -15,8 +15,8 @@ struct LineInfo { fn context_info<'a>( input: &'a [u8], span: &SourceSpan, - context_lines_before: usize, - context_lines_after: usize, + context_lines_before: Option, + context_lines_after: Option, ) -> Result, MietteError> { let mut iter = input .split_inclusive(|b| *b == b'\n') @@ -52,14 +52,14 @@ fn context_info<'a>( Some(info) => info, }; - if line_starts.len() > context_lines_before { + if line_starts.len() > context_lines_before.unwrap_or(0) { line_starts.pop_front(); } line_starts.push_back(line_info); } let (start_lineno, start_offset, start_column) = { let start_info = line_starts.pop_front().unwrap(); - if context_lines_before > 0 { + if context_lines_before.is_some() { (start_info.line_no, start_info.start, 0) } else { ( @@ -79,13 +79,13 @@ fn context_info<'a>( } // Get the "after" lines - if let Some(last) = iter.take(context_lines_after).last() { + if let Some(last) = iter.take(context_lines_after.unwrap_or(0)).last() { line_info = last; } if span.offset() + span.len() > line_info.end { return Err(MietteError::OutOfBounds); } - let (end_lineno, end_offset) = if context_lines_after > 0 { + let (end_lineno, end_offset) = if context_lines_after.is_some() { (line_info.line_no, line_info.end) } else { (line_info.line_no, span.offset() + span.len()) @@ -104,8 +104,8 @@ impl SourceCode for [u8] { fn read_span<'a>( &'a self, span: &SourceSpan, - context_lines_before: usize, - context_lines_after: usize, + context_lines_before: Option, + context_lines_after: Option, ) -> Result + 'a>, MietteError> { let contents = context_info(self, span, context_lines_before, context_lines_after)?; Ok(Box::new(contents)) @@ -116,8 +116,8 @@ impl<'src> SourceCode for &'src [u8] { fn read_span<'a>( &'a self, span: &SourceSpan, - context_lines_before: usize, - context_lines_after: usize, + context_lines_before: Option, + context_lines_after: Option, ) -> Result + 'a>, MietteError> { <[u8] as SourceCode>::read_span(self, span, context_lines_before, context_lines_after) } @@ -127,8 +127,8 @@ impl SourceCode for Vec { fn read_span<'a>( &'a self, span: &SourceSpan, - context_lines_before: usize, - context_lines_after: usize, + context_lines_before: Option, + context_lines_after: Option, ) -> Result + 'a>, MietteError> { <[u8] as SourceCode>::read_span(self, span, context_lines_before, context_lines_after) } @@ -138,8 +138,8 @@ impl SourceCode for str { fn read_span<'a>( &'a self, span: &SourceSpan, - context_lines_before: usize, - context_lines_after: usize, + context_lines_before: Option, + context_lines_after: Option, ) -> Result + 'a>, MietteError> { <[u8] as SourceCode>::read_span( self.as_bytes(), @@ -155,8 +155,8 @@ impl<'s> SourceCode for &'s str { fn read_span<'a>( &'a self, span: &SourceSpan, - context_lines_before: usize, - context_lines_after: usize, + context_lines_before: Option, + context_lines_after: Option, ) -> Result + 'a>, MietteError> { ::read_span(self, span, context_lines_before, context_lines_after) } @@ -166,8 +166,8 @@ impl SourceCode for String { fn read_span<'a>( &'a self, span: &SourceSpan, - context_lines_before: usize, - context_lines_after: usize, + context_lines_before: Option, + context_lines_after: Option, ) -> Result + 'a>, MietteError> { ::read_span(self, span, context_lines_before, context_lines_after) } @@ -177,8 +177,8 @@ impl SourceCode for Arc { fn read_span<'a>( &'a self, span: &SourceSpan, - context_lines_before: usize, - context_lines_after: usize, + context_lines_before: Option, + context_lines_after: Option, ) -> Result + 'a>, MietteError> { self.as_ref() .read_span(span, context_lines_before, context_lines_after) @@ -197,8 +197,8 @@ where fn read_span<'a>( &'a self, span: &SourceSpan, - context_lines_before: usize, - context_lines_after: usize, + context_lines_before: Option, + context_lines_after: Option, ) -> Result + 'a>, MietteError> { self.as_ref() .read_span(span, context_lines_before, context_lines_after) @@ -212,7 +212,7 @@ mod tests { #[test] fn basic() -> Result<(), MietteError> { let src = String::from("foo\n"); - let contents = src.read_span(&(0, 4).into(), 0, 0)?; + let contents = src.read_span(&(0, 4).into(), None, None)?; assert_eq!("foo\n", std::str::from_utf8(contents.data()).unwrap()); assert_eq!(SourceSpan::from((0, 4)), *contents.span()); assert_eq!(0, contents.line()); @@ -224,7 +224,7 @@ mod tests { #[test] fn shifted() -> Result<(), MietteError> { let src = String::from("foobar"); - let contents = src.read_span(&(3, 3).into(), 1, 1)?; + let contents = src.read_span(&(3, 3).into(), Some(1), Some(1))?; assert_eq!("foobar", std::str::from_utf8(contents.data()).unwrap()); assert_eq!(SourceSpan::from((0, 6)), *contents.span()); assert_eq!(0, contents.line()); @@ -236,7 +236,7 @@ mod tests { #[test] fn middle() -> Result<(), MietteError> { let src = String::from("foo\nbar\nbaz\n"); - let contents = src.read_span(&(4, 4).into(), 0, 0)?; + let contents = src.read_span(&(4, 4).into(), None, None)?; assert_eq!("bar\n", std::str::from_utf8(contents.data()).unwrap()); assert_eq!(SourceSpan::from((4, 4)), *contents.span()); assert_eq!(1, contents.line()); @@ -248,7 +248,7 @@ mod tests { #[test] fn middle_of_line() -> Result<(), MietteError> { let src = String::from("foo\nbarbar\nbaz\n"); - let contents = src.read_span(&(7, 4).into(), 0, 0)?; + let contents = src.read_span(&(7, 4).into(), None, None)?; assert_eq!("bar\n", std::str::from_utf8(contents.data()).unwrap()); assert_eq!(SourceSpan::from((7, 4)), *contents.span()); assert_eq!(1, contents.line()); @@ -260,7 +260,7 @@ mod tests { #[test] fn end_of_line_before_newline() -> Result<(), MietteError> { let src = String::from("foo\nbar\nbaz\n"); - let contents = src.read_span(&(7, 0).into(), 0, 0)?; + let contents = src.read_span(&(7, 0).into(), None, None)?; assert_eq!("", std::str::from_utf8(contents.data()).unwrap()); assert_eq!(SourceSpan::from((7, 0)), *contents.span()); assert_eq!(1, contents.line()); @@ -272,7 +272,7 @@ mod tests { #[test] fn end_of_line_after_newline() -> Result<(), MietteError> { let src = String::from("foo\nbar\nbaz\n"); - let contents = src.read_span(&(8, 0).into(), 0, 0)?; + let contents = src.read_span(&(8, 0).into(), None, None)?; assert_eq!("", std::str::from_utf8(contents.data()).unwrap()); assert_eq!(SourceSpan::from((8, 0)), *contents.span()); assert_eq!(2, contents.line()); @@ -284,7 +284,7 @@ mod tests { #[test] fn end_of_file_with_newline() -> Result<(), MietteError> { let src = String::from("foo\nbar\nbaz\n"); - let contents = src.read_span(&(12, 0).into(), 0, 0)?; + let contents = src.read_span(&(12, 0).into(), None, None)?; assert_eq!("", std::str::from_utf8(contents.data()).unwrap()); assert_eq!(SourceSpan::from((12, 0)), *contents.span()); assert_eq!(2, contents.line()); @@ -296,7 +296,7 @@ mod tests { #[test] fn end_of_file_without_newline() -> Result<(), MietteError> { let src = String::from("foo\nbar\nbaz"); - let contents = src.read_span(&(11, 0).into(), 0, 0)?; + let contents = src.read_span(&(11, 0).into(), None, None)?; assert_eq!("", std::str::from_utf8(contents.data()).unwrap()); assert_eq!(SourceSpan::from((11, 0)), *contents.span()); assert_eq!(2, contents.line()); @@ -308,7 +308,7 @@ mod tests { #[test] fn with_crlf() -> Result<(), MietteError> { let src = String::from("foo\r\nbar\r\nbaz\r\n"); - let contents = src.read_span(&(5, 5).into(), 0, 0)?; + let contents = src.read_span(&(5, 5).into(), None, None)?; assert_eq!("bar\r\n", std::str::from_utf8(contents.data()).unwrap()); assert_eq!(SourceSpan::from((5, 5)), *contents.span()); assert_eq!(1, contents.line()); @@ -320,7 +320,7 @@ mod tests { #[test] fn with_context() -> Result<(), MietteError> { let src = String::from("xxx\nfoo\nbar\nbaz\n\nyyy\n"); - let contents = src.read_span(&(8, 3).into(), 1, 1)?; + let contents = src.read_span(&(8, 3).into(), Some(1), Some(1))?; assert_eq!( "foo\nbar\nbaz\n", std::str::from_utf8(contents.data()).unwrap() @@ -335,7 +335,7 @@ mod tests { #[test] fn multiline_with_context() -> Result<(), MietteError> { let src = String::from("aaa\nxxx\n\nfoo\nbar\nbaz\n\nyyy\nbbb\n"); - let contents = src.read_span(&(9, 11).into(), 1, 1)?; + let contents = src.read_span(&(9, 11).into(), Some(1), Some(1))?; assert_eq!( "\nfoo\nbar\nbaz\n\n", std::str::from_utf8(contents.data()).unwrap() @@ -352,7 +352,7 @@ mod tests { #[test] fn multiline_with_context_line_start() -> Result<(), MietteError> { let src = String::from("one\ntwo\n\nthree\nfour\nfive\n\nsix\nseven\n"); - let contents = src.read_span(&(2, 0).into(), 2, 2)?; + let contents = src.read_span(&(2, 0).into(), Some(2), Some(2))?; assert_eq!( "one\ntwo\n\n", std::str::from_utf8(contents.data()).unwrap() @@ -370,7 +370,7 @@ mod tests { fn empty_source() -> Result<(), MietteError> { let src = String::from(""); - let contents = src.read_span(&(0, 0).into(), 0, 0)?; + let contents = src.read_span(&(0, 0).into(), None, None)?; assert_eq!("", std::str::from_utf8(contents.data()).unwrap()); assert_eq!(SourceSpan::from((0, 0)), *contents.span()); assert_eq!(0, contents.line()); @@ -384,22 +384,22 @@ mod tests { fn empty_source_out_of_bounds() { let src = String::from(""); - let contents = src.read_span(&(0, 1).into(), 0, 0); + let contents = src.read_span(&(0, 1).into(), None, None); assert!(matches!(contents, Err(MietteError::OutOfBounds))); - let contents = src.read_span(&(0, 2).into(), 0, 0); + let contents = src.read_span(&(0, 2).into(), None, None); assert!(matches!(contents, Err(MietteError::OutOfBounds))); - let contents = src.read_span(&(1, 0).into(), 0, 0); + let contents = src.read_span(&(1, 0).into(), None, None); assert!(matches!(contents, Err(MietteError::OutOfBounds))); - let contents = src.read_span(&(1, 1).into(), 0, 0); + let contents = src.read_span(&(1, 1).into(), None, None); assert!(matches!(contents, Err(MietteError::OutOfBounds))); - let contents = src.read_span(&(2, 0).into(), 0, 0); + let contents = src.read_span(&(2, 0).into(), None, None); assert!(matches!(contents, Err(MietteError::OutOfBounds))); - let contents = src.read_span(&(2, 1).into(), 0, 0); + let contents = src.read_span(&(2, 1).into(), None, None); assert!(matches!(contents, Err(MietteError::OutOfBounds))); } } diff --git a/tests/graphical.rs b/tests/graphical.rs index 47631171..32b9c020 100644 --- a/tests/graphical.rs +++ b/tests/graphical.rs @@ -2196,3 +2196,254 @@ Error: oops::my::inner assert_eq!(expected, &out); Ok(()) } + +#[test] +fn zero_length_no_context() -> Result<(), MietteError> { + #[derive(Debug, Diagnostic, Error)] + #[error("oops!")] + #[diagnostic(code(oops::my::bad), help("try doing it better next time?"))] + struct MyBad { + #[source_code] + src: NamedSource, + #[label("this bit here")] + highlight: SourceSpan, + } + + let src = "one\ntwoo\nthree".to_string(); + let err = MyBad { + src: NamedSource::new("bad_file.rs", src), + highlight: (6, 0).into(), + }; + + let out = fmt_report_with_settings(err.into(), |handler| { + handler + .with_opt_context_lines(None) + .without_syntax_highlighting() + }); + let expected = r#"oops::my::bad + + × oops! + ╭─[bad_file.rs:2:3] + ╰──── + help: try doing it better next time? +"# + .trim_start() + .to_string(); + assert_eq!(expected, out); + Ok(()) +} + +#[test] +fn multi_adjacent_zero_length_no_context() -> Result<(), MietteError> { + #[derive(Debug, Diagnostic, Error)] + #[error("oops!")] + #[diagnostic(code(oops::my::bad), help("try doing it better next time?"))] + struct MyBad { + #[source_code] + src: NamedSource, + #[label("this bit here")] + highlight: SourceSpan, + #[label("and here")] + highlight2: SourceSpan, + } + + let src = "one\ntwoo\nthree\nfour".to_string(); + let err = MyBad { + src: NamedSource::new("bad_file.rs", src), + highlight: (6, 0).into(), + highlight2: (12, 0).into(), + }; + + let out = fmt_report_with_settings(err.into(), |handler| { + handler + .with_opt_context_lines(None) + .without_syntax_highlighting() + }); + let expected = r#"oops::my::bad + + × oops! + ╭─[bad_file.rs:2:3] + 2 │ oo + · ▲ + · ╰── this bit here + 3 │ thr + ╰──── + help: try doing it better next time? +"# + .trim_start() + .to_string(); + assert_eq!(expected, out); + Ok(()) +} + +#[test] +fn multi_separated_zero_length_no_context() -> Result<(), MietteError> { + #[derive(Debug, Diagnostic, Error)] + #[error("oops!")] + #[diagnostic(code(oops::my::bad), help("try doing it better next time?"))] + struct MyBad { + #[source_code] + src: NamedSource, + #[label("this bit here")] + highlight: SourceSpan, + #[label("and here")] + highlight2: SourceSpan, + } + + let src = "one\ntwoo\nthree\nfour".to_string(); + let err = MyBad { + src: NamedSource::new("bad_file.rs", src), + highlight: (6, 0).into(), + highlight2: (17, 0).into(), + }; + + let out = fmt_report_with_settings(err.into(), |handler| { + handler + .with_opt_context_lines(None) + .without_syntax_highlighting() + }); + let expected = r#"oops::my::bad + + × oops! + ╭─[bad_file.rs:2:3] + ╰──── + ╭─[bad_file.rs:4:3] + ╰──── + help: try doing it better next time? +"# + .trim_start() + .to_string(); + assert_eq!(expected, out); + Ok(()) +} + +#[test] +fn zero_length_zero_context() -> Result<(), MietteError> { + #[derive(Debug, Diagnostic, Error)] + #[error("oops!")] + #[diagnostic(code(oops::my::bad), help("try doing it better next time?"))] + struct MyBad { + #[source_code] + src: NamedSource, + #[label("this bit here")] + highlight: SourceSpan, + } + + let src = "one\ntwoo\nthree".to_string(); + let err = MyBad { + src: NamedSource::new("bad_file.rs", src), + highlight: (6, 0).into(), + }; + + let out = fmt_report_with_settings(err.into(), |handler| { + handler + .with_opt_context_lines(Some(0)) + .without_syntax_highlighting() + }); + let expected = r#"oops::my::bad + + × oops! + ╭─[bad_file.rs:2:3] + 2 │ twoo + · ▲ + · ╰── this bit here + ╰──── + help: try doing it better next time? +"# + .trim_start() + .to_string(); + assert_eq!(expected, out); + Ok(()) +} + +#[test] +fn multi_adjacent_zero_length_zero_context() -> Result<(), MietteError> { + #[derive(Debug, Diagnostic, Error)] + #[error("oops!")] + #[diagnostic(code(oops::my::bad), help("try doing it better next time?"))] + struct MyBad { + #[source_code] + src: NamedSource, + #[label("this bit here")] + highlight: SourceSpan, + #[label("and here")] + highlight2: SourceSpan, + } + + let src = "one\ntwoo\nthree\nfour".to_string(); + let err = MyBad { + src: NamedSource::new("bad_file.rs", src), + highlight: (6, 0).into(), + highlight2: (12, 0).into(), + }; + + let out = fmt_report_with_settings(err.into(), |handler| { + handler + .with_opt_context_lines(Some(0)) + .without_syntax_highlighting() + }); + let expected = r#"oops::my::bad + + × oops! + ╭─[bad_file.rs:2:3] + 2 │ twoo + · ▲ + · ╰── this bit here + 3 │ three + · ▲ + · ╰── and here + ╰──── + help: try doing it better next time? +"# + .trim_start() + .to_string(); + assert_eq!(expected, out); + Ok(()) +} + +#[test] +fn multi_separated_zero_length_zero_context() -> Result<(), MietteError> { + #[derive(Debug, Diagnostic, Error)] + #[error("oops!")] + #[diagnostic(code(oops::my::bad), help("try doing it better next time?"))] + struct MyBad { + #[source_code] + src: NamedSource, + #[label("this bit here")] + highlight: SourceSpan, + #[label("and here")] + highlight2: SourceSpan, + } + + let src = "one\ntwoo\nthree\nfour".to_string(); + let err = MyBad { + src: NamedSource::new("bad_file.rs", src), + highlight: (6, 0).into(), + highlight2: (17, 0).into(), + }; + + let out = fmt_report_with_settings(err.into(), |handler| { + handler + .with_opt_context_lines(Some(0)) + .without_syntax_highlighting() + }); + let expected = r#"oops::my::bad + + × oops! + ╭─[bad_file.rs:2:3] + 2 │ twoo + · ▲ + · ╰── this bit here + ╰──── + ╭─[bad_file.rs:4:3] + 4 │ four + · ▲ + · ╰── and here + ╰──── + help: try doing it better next time? +"# + .trim_start() + .to_string(); + assert_eq!(expected, out); + Ok(()) +} diff --git a/tests/test_boxed.rs b/tests/test_boxed.rs index d6fa6f80..edafefaa 100644 --- a/tests/test_boxed.rs +++ b/tests/test_boxed.rs @@ -188,7 +188,7 @@ fn test_boxed_custom_diagnostic() { let span = SourceSpan::from(0..CustomDiagnostic::SOURCE_CODE.len()); assert_eq!( report.source_code().map(|source_code| source_code - .read_span(&span, 0, 0) + .read_span(&span, None, None) .expect("read data from source code successfully") .data() .to_owned()),