Skip to content

Commit e9e1c43

Browse files
test: add snapshot tests (#84)
1 parent 1356421 commit e9e1c43

File tree

2 files changed

+286
-0
lines changed

2 files changed

+286
-0
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@ auto-color = ["concolor", "concolor/auto"]
2121
yansi = "0.5"
2222
unicode-width = "0.1.9"
2323
concolor = { version = "0.1", optional = true }
24+
25+
[dev-dependencies]
26+
insta = "1.31.0"

src/write.rs

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,3 +794,286 @@ impl<S: Span> Label<S> {
794794
self.span.end().saturating_sub(1).max(self.span.start())
795795
}
796796
}
797+
798+
#[cfg(test)]
799+
mod tests {
800+
//! These tests use [insta](https://insta.rs/). If you do `cargo install cargo-insta` you can
801+
//! automatically update the snapshots with `cargo insta review` or `cargo insta accept`.
802+
//!
803+
//! When adding new tests you can leave the string in the `assert_snapshot!` macro call empty:
804+
//!
805+
//! assert_snapshot!(msg, @"");
806+
//!
807+
//! and insta will fill it in.
808+
809+
use std::ops::Range;
810+
811+
use insta::assert_snapshot;
812+
813+
use crate::{Cache, CharSet, Config, Label, Report, ReportKind, Source, Span};
814+
815+
impl<S: Span> Report<'_, S> {
816+
fn write_to_string<C: Cache<S::SourceId>>(&self, cache: C) -> String {
817+
let mut vec = Vec::new();
818+
self.write(cache, &mut vec).unwrap();
819+
String::from_utf8(vec).unwrap()
820+
}
821+
}
822+
823+
fn no_color_and_ascii() -> Config {
824+
Config::default()
825+
.with_color(false)
826+
// Using Ascii so that the inline snapshots display correctly
827+
// even with fonts where characters like '┬' take up more space.
828+
.with_char_set(CharSet::Ascii)
829+
}
830+
831+
#[test]
832+
fn one_message() {
833+
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
834+
.with_config(no_color_and_ascii())
835+
.with_message("can't compare apples with oranges")
836+
.finish()
837+
.write_to_string(Source::from(""));
838+
assert_snapshot!(msg, @r###"
839+
Error: can't compare apples with oranges
840+
"###)
841+
}
842+
843+
#[test]
844+
fn two_labels_without_messages() {
845+
let source = "apple == orange;";
846+
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
847+
.with_config(no_color_and_ascii())
848+
.with_message("can't compare apples with oranges")
849+
.with_label(Label::new(0..5))
850+
.with_label(Label::new(9..15))
851+
.finish()
852+
.write_to_string(Source::from(source));
853+
// TODO: it would be nice if these spans still showed up (like codespan-reporting does)
854+
assert_snapshot!(msg, @r###"
855+
Error: can't compare apples with oranges
856+
,-[<unknown>:1:1]
857+
|
858+
1 | apple == orange;
859+
---'
860+
"###);
861+
}
862+
863+
#[test]
864+
fn two_labels_with_messages() {
865+
let source = "apple == orange;";
866+
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
867+
.with_config(no_color_and_ascii())
868+
.with_message("can't compare apples with oranges")
869+
.with_label(Label::new(0..5).with_message("This is an apple"))
870+
.with_label(Label::new(9..15).with_message("This is an orange"))
871+
.finish()
872+
.write_to_string(Source::from(source));
873+
// TODO: it would be nice if these lines didn't cross
874+
assert_snapshot!(msg, @r###"
875+
Error: can't compare apples with oranges
876+
,-[<unknown>:1:1]
877+
|
878+
1 | apple == orange;
879+
| ^^|^^ ^^^|^^
880+
| `-------------- This is an apple
881+
| |
882+
| `---- This is an orange
883+
---'
884+
"###);
885+
}
886+
887+
#[test]
888+
#[should_panic]
889+
fn backwards_label_should_panic() {
890+
let _ = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
891+
.with_label(Label::new(5..0))
892+
.finish()
893+
.write_to_string(Source::from(""));
894+
}
895+
896+
#[test]
897+
fn label_at_end_of_long_line() {
898+
let source = format!("{}orange", "apple == ".repeat(100));
899+
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
900+
.with_config(no_color_and_ascii())
901+
.with_message("can't compare apples with oranges")
902+
.with_label(
903+
Label::new(source.len() - 5..source.len()).with_message("This is an orange"),
904+
)
905+
.finish()
906+
.write_to_string(Source::from(source));
907+
// TODO: it would be nice if the start of long lines would be omitted (like rustc does)
908+
assert_snapshot!(msg, @r###"
909+
Error: can't compare apples with oranges
910+
,-[<unknown>:1:1]
911+
|
912+
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
913+
| ^^|^^
914+
| `---- This is an orange
915+
---'
916+
"###);
917+
}
918+
919+
#[test]
920+
fn multiline_label() {
921+
let source = "apple\n==\norange";
922+
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
923+
.with_config(no_color_and_ascii())
924+
.with_label(Label::new(0..source.len()).with_message("illegal comparison"))
925+
.finish()
926+
.write_to_string(Source::from(source));
927+
// TODO: it would be nice if the 2nd line wasn't omitted
928+
assert_snapshot!(msg, @r###"
929+
Error:
930+
,-[<unknown>:1:1]
931+
|
932+
1 | ,-> apple
933+
: :
934+
3 | |-> orange
935+
| |
936+
| `----------- illegal comparison
937+
---'
938+
"###);
939+
}
940+
941+
#[test]
942+
fn partially_overlapping_labels() {
943+
let source = "https://example.com/";
944+
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
945+
.with_config(no_color_and_ascii())
946+
.with_label(Label::new(0..source.len()).with_message("URL"))
947+
.with_label(Label::new(0..source.find(':').unwrap()).with_message("scheme"))
948+
.finish()
949+
.write_to_string(Source::from(source));
950+
// TODO: it would be nice if you could tell where the spans start and end.
951+
assert_snapshot!(msg, @r###"
952+
Error:
953+
,-[<unknown>:1:1]
954+
|
955+
1 | https://example.com/
956+
| ^^|^^^^^^^|^^^^^^^^^
957+
| `------------------- scheme
958+
| |
959+
| `----------- URL
960+
---'
961+
"###);
962+
}
963+
964+
#[test]
965+
fn multiple_labels_same_span() {
966+
let source = "apple == orange;";
967+
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
968+
.with_config(no_color_and_ascii())
969+
.with_message("can't compare apples with oranges")
970+
.with_label(Label::new(0..5).with_message("This is an apple"))
971+
.with_label(Label::new(0..5).with_message("Have I mentioned that this is an apple?"))
972+
.with_label(Label::new(0..5).with_message("No really, have I mentioned that?"))
973+
.with_label(Label::new(9..15).with_message("This is an orange"))
974+
.with_label(Label::new(9..15).with_message("Have I mentioned that this is an orange?"))
975+
.with_label(Label::new(9..15).with_message("No really, have I mentioned that?"))
976+
.finish()
977+
.write_to_string(Source::from(source));
978+
assert_snapshot!(msg, @r###"
979+
Error: can't compare apples with oranges
980+
,-[<unknown>:1:1]
981+
|
982+
1 | apple == orange;
983+
| ^^|^^ ^^^|^^
984+
| `-------------- This is an apple
985+
| | |
986+
| `-------------- Have I mentioned that this is an apple?
987+
| | |
988+
| `-------------- No really, have I mentioned that?
989+
| |
990+
| `---- This is an orange
991+
| |
992+
| `---- Have I mentioned that this is an orange?
993+
| |
994+
| `---- No really, have I mentioned that?
995+
---'
996+
"###)
997+
}
998+
999+
#[test]
1000+
fn note() {
1001+
let source = "apple == orange;";
1002+
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
1003+
.with_config(no_color_and_ascii())
1004+
.with_message("can't compare apples with oranges")
1005+
.with_label(Label::new(0..5).with_message("This is an apple"))
1006+
.with_label(Label::new(9..15).with_message("This is an orange"))
1007+
.with_note("stop trying ... this is a fruitless endeavor")
1008+
.finish()
1009+
.write_to_string(Source::from(source));
1010+
assert_snapshot!(msg, @r###"
1011+
Error: can't compare apples with oranges
1012+
,-[<unknown>:1:1]
1013+
|
1014+
1 | apple == orange;
1015+
| ^^|^^ ^^^|^^
1016+
| `-------------- This is an apple
1017+
| |
1018+
| `---- This is an orange
1019+
|
1020+
| Note: stop trying ... this is a fruitless endeavor
1021+
---'
1022+
"###)
1023+
}
1024+
1025+
#[test]
1026+
fn help() {
1027+
let source = "apple == orange;";
1028+
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
1029+
.with_config(no_color_and_ascii())
1030+
.with_message("can't compare apples with oranges")
1031+
.with_label(Label::new(0..5).with_message("This is an apple"))
1032+
.with_label(Label::new(9..15).with_message("This is an orange"))
1033+
.with_help("have you tried peeling the orange?")
1034+
.finish()
1035+
.write_to_string(Source::from(source));
1036+
assert_snapshot!(msg, @r###"
1037+
Error: can't compare apples with oranges
1038+
,-[<unknown>:1:1]
1039+
|
1040+
1 | apple == orange;
1041+
| ^^|^^ ^^^|^^
1042+
| `-------------- This is an apple
1043+
| |
1044+
| `---- This is an orange
1045+
|
1046+
| Help: have you tried peeling the orange?
1047+
---'
1048+
"###)
1049+
}
1050+
1051+
#[test]
1052+
fn help_and_note() {
1053+
let source = "apple == orange;";
1054+
let msg = Report::<Range<usize>>::build(ReportKind::Error, (), 0)
1055+
.with_config(no_color_and_ascii())
1056+
.with_message("can't compare apples with oranges")
1057+
.with_label(Label::new(0..5).with_message("This is an apple"))
1058+
.with_label(Label::new(9..15).with_message("This is an orange"))
1059+
.with_help("have you tried peeling the orange?")
1060+
.with_note("stop trying ... this is a fruitless endeavor")
1061+
.finish()
1062+
.write_to_string(Source::from(source));
1063+
assert_snapshot!(msg, @r###"
1064+
Error: can't compare apples with oranges
1065+
,-[<unknown>:1:1]
1066+
|
1067+
1 | apple == orange;
1068+
| ^^|^^ ^^^|^^
1069+
| `-------------- This is an apple
1070+
| |
1071+
| `---- This is an orange
1072+
|
1073+
| Help: have you tried peeling the orange?
1074+
|
1075+
| Note: stop trying ... this is a fruitless endeavor
1076+
---'
1077+
"###)
1078+
}
1079+
}

0 commit comments

Comments
 (0)