Skip to content

Commit

Permalink
test: add snapshot tests (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
not-my-profile committed Aug 16, 2023
1 parent 1356421 commit e9e1c43
Show file tree
Hide file tree
Showing 2 changed files with 286 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ auto-color = ["concolor", "concolor/auto"]
yansi = "0.5"
unicode-width = "0.1.9"
concolor = { version = "0.1", optional = true }

[dev-dependencies]
insta = "1.31.0"
283 changes: 283 additions & 0 deletions src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -794,3 +794,286 @@ impl<S: Span> Label<S> {
self.span.end().saturating_sub(1).max(self.span.start())
}
}

#[cfg(test)]
mod tests {
//! These tests use [insta](https://insta.rs/). If you do `cargo install cargo-insta` you can
//! automatically update the snapshots with `cargo insta review` or `cargo insta accept`.
//!
//! When adding new tests you can leave the string in the `assert_snapshot!` macro call empty:
//!
//! assert_snapshot!(msg, @"");
//!
//! and insta will fill it in.

use std::ops::Range;

use insta::assert_snapshot;

use crate::{Cache, CharSet, Config, Label, Report, ReportKind, Source, Span};

impl<S: Span> Report<'_, S> {
fn write_to_string<C: Cache<S::SourceId>>(&self, cache: C) -> String {
let mut vec = Vec::new();
self.write(cache, &mut vec).unwrap();
String::from_utf8(vec).unwrap()
}
}

fn no_color_and_ascii() -> Config {
Config::default()
.with_color(false)
// Using Ascii so that the inline snapshots display correctly
// even with fonts where characters like '┬' take up more space.
.with_char_set(CharSet::Ascii)
}

#[test]
fn one_message() {
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
.with_config(no_color_and_ascii())
.with_message("can't compare apples with oranges")
.finish()
.write_to_string(Source::from(""));
assert_snapshot!(msg, @r###"
Error: can't compare apples with oranges
"###)
}

#[test]
fn two_labels_without_messages() {
let source = "apple == orange;";
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
.with_config(no_color_and_ascii())
.with_message("can't compare apples with oranges")
.with_label(Label::new(0..5))
.with_label(Label::new(9..15))
.finish()
.write_to_string(Source::from(source));
// TODO: it would be nice if these spans still showed up (like codespan-reporting does)
assert_snapshot!(msg, @r###"
Error: can't compare apples with oranges
,-[<unknown>:1:1]
|
1 | apple == orange;
---'
"###);
}

#[test]
fn two_labels_with_messages() {
let source = "apple == orange;";
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
.with_config(no_color_and_ascii())
.with_message("can't compare apples with oranges")
.with_label(Label::new(0..5).with_message("This is an apple"))
.with_label(Label::new(9..15).with_message("This is an orange"))
.finish()
.write_to_string(Source::from(source));
// TODO: it would be nice if these lines didn't cross
assert_snapshot!(msg, @r###"
Error: can't compare apples with oranges
,-[<unknown>:1:1]
|
1 | apple == orange;
| ^^|^^ ^^^|^^
| `-------------- This is an apple
| |
| `---- This is an orange
---'
"###);
}

#[test]
#[should_panic]
fn backwards_label_should_panic() {
let _ = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
.with_label(Label::new(5..0))
.finish()
.write_to_string(Source::from(""));
}

#[test]
fn label_at_end_of_long_line() {
let source = format!("{}orange", "apple == ".repeat(100));
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
.with_config(no_color_and_ascii())
.with_message("can't compare apples with oranges")
.with_label(
Label::new(source.len() - 5..source.len()).with_message("This is an orange"),
)
.finish()
.write_to_string(Source::from(source));
// TODO: it would be nice if the start of long lines would be omitted (like rustc does)
assert_snapshot!(msg, @r###"
Error: can't compare apples with oranges
,-[<unknown>:1:1]
|
1 | apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == apple == orange
| ^^|^^
| `---- This is an orange
---'
"###);
}

#[test]
fn multiline_label() {
let source = "apple\n==\norange";
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
.with_config(no_color_and_ascii())
.with_label(Label::new(0..source.len()).with_message("illegal comparison"))
.finish()
.write_to_string(Source::from(source));
// TODO: it would be nice if the 2nd line wasn't omitted
assert_snapshot!(msg, @r###"
Error:
,-[<unknown>:1:1]
|
1 | ,-> apple
: :
3 | |-> orange
| |
| `----------- illegal comparison
---'
"###);
}

#[test]
fn partially_overlapping_labels() {
let source = "https://example.com/";
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
.with_config(no_color_and_ascii())
.with_label(Label::new(0..source.len()).with_message("URL"))
.with_label(Label::new(0..source.find(':').unwrap()).with_message("scheme"))
.finish()
.write_to_string(Source::from(source));
// TODO: it would be nice if you could tell where the spans start and end.
assert_snapshot!(msg, @r###"
Error:
,-[<unknown>:1:1]
|
1 | https://example.com/
| ^^|^^^^^^^|^^^^^^^^^
| `------------------- scheme
| |
| `----------- URL
---'
"###);
}

#[test]
fn multiple_labels_same_span() {
let source = "apple == orange;";
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
.with_config(no_color_and_ascii())
.with_message("can't compare apples with oranges")
.with_label(Label::new(0..5).with_message("This is an apple"))
.with_label(Label::new(0..5).with_message("Have I mentioned that this is an apple?"))
.with_label(Label::new(0..5).with_message("No really, have I mentioned that?"))
.with_label(Label::new(9..15).with_message("This is an orange"))
.with_label(Label::new(9..15).with_message("Have I mentioned that this is an orange?"))
.with_label(Label::new(9..15).with_message("No really, have I mentioned that?"))
.finish()
.write_to_string(Source::from(source));
assert_snapshot!(msg, @r###"
Error: can't compare apples with oranges
,-[<unknown>:1:1]
|
1 | apple == orange;
| ^^|^^ ^^^|^^
| `-------------- This is an apple
| | |
| `-------------- Have I mentioned that this is an apple?
| | |
| `-------------- No really, have I mentioned that?
| |
| `---- This is an orange
| |
| `---- Have I mentioned that this is an orange?
| |
| `---- No really, have I mentioned that?
---'
"###)
}

#[test]
fn note() {
let source = "apple == orange;";
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
.with_config(no_color_and_ascii())
.with_message("can't compare apples with oranges")
.with_label(Label::new(0..5).with_message("This is an apple"))
.with_label(Label::new(9..15).with_message("This is an orange"))
.with_note("stop trying ... this is a fruitless endeavor")
.finish()
.write_to_string(Source::from(source));
assert_snapshot!(msg, @r###"
Error: can't compare apples with oranges
,-[<unknown>:1:1]
|
1 | apple == orange;
| ^^|^^ ^^^|^^
| `-------------- This is an apple
| |
| `---- This is an orange
|
| Note: stop trying ... this is a fruitless endeavor
---'
"###)
}

#[test]
fn help() {
let source = "apple == orange;";
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
.with_config(no_color_and_ascii())
.with_message("can't compare apples with oranges")
.with_label(Label::new(0..5).with_message("This is an apple"))
.with_label(Label::new(9..15).with_message("This is an orange"))
.with_help("have you tried peeling the orange?")
.finish()
.write_to_string(Source::from(source));
assert_snapshot!(msg, @r###"
Error: can't compare apples with oranges
,-[<unknown>:1:1]
|
1 | apple == orange;
| ^^|^^ ^^^|^^
| `-------------- This is an apple
| |
| `---- This is an orange
|
| Help: have you tried peeling the orange?
---'
"###)
}

#[test]
fn help_and_note() {
let source = "apple == orange;";
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
.with_config(no_color_and_ascii())
.with_message("can't compare apples with oranges")
.with_label(Label::new(0..5).with_message("This is an apple"))
.with_label(Label::new(9..15).with_message("This is an orange"))
.with_help("have you tried peeling the orange?")
.with_note("stop trying ... this is a fruitless endeavor")
.finish()
.write_to_string(Source::from(source));
assert_snapshot!(msg, @r###"
Error: can't compare apples with oranges
,-[<unknown>:1:1]
|
1 | apple == orange;
| ^^|^^ ^^^|^^
| `-------------- This is an apple
| |
| `---- This is an orange
|
| Help: have you tried peeling the orange?
|
| Note: stop trying ... this is a fruitless endeavor
---'
"###)
}
}

0 comments on commit e9e1c43

Please sign in to comment.