mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-10 06:35:07 +00:00

This merely adds the crate to our repository. Some cosmetic changes are made to make it work in our repo and follow our conventions, such as changing the name to `ruff_annotate_snippets`. We retain the original license information. We do drop some things, such as benchmarks, but keep tests and examples.
783 lines
17 KiB
Rust
783 lines
17 KiB
Rust
//! These tests have been adapted from [Rust's parser tests][parser-tests].
|
|
//!
|
|
//! [parser-tests]: https://github.com/rust-lang/rust/blob/894f7a4ba6554d3797404bbf550d9919df060b97/compiler/rustc_parse/src/parser/tests.rs
|
|
|
|
use ruff_annotate_snippets::{Level, Renderer, Snippet};
|
|
|
|
use snapbox::{assert_data_eq, str};
|
|
|
|
#[test]
|
|
fn ends_on_col0() {
|
|
let source = r#"
|
|
fn foo() {
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(10..13).label("test")),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:2:10
|
|
|
|
|
2 | fn foo() {
|
|
| __________^
|
|
3 | | }
|
|
| |_^ test
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn ends_on_col2() {
|
|
let source = r#"
|
|
fn foo() {
|
|
|
|
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(10..17).label("test")),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:2:10
|
|
|
|
|
2 | fn foo() {
|
|
| __________^
|
|
3 | |
|
|
4 | |
|
|
5 | | }
|
|
| |___^ test
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn non_nested() {
|
|
let source = r#"
|
|
fn foo() {
|
|
X0 Y0
|
|
X1 Y1
|
|
X2 Y2
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(14..32).label("`X` is a good letter"))
|
|
.annotation(
|
|
Level::Warning
|
|
.span(17..35)
|
|
.label("`Y` is a good letter too"),
|
|
),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:3
|
|
|
|
|
3 | X0 Y0
|
|
| ____^ -
|
|
| | ______|
|
|
4 | || X1 Y1
|
|
5 | || X2 Y2
|
|
| ||____^__- `Y` is a good letter too
|
|
| |_____|
|
|
| `X` is a good letter
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn nested() {
|
|
let source = r#"
|
|
fn foo() {
|
|
X0 Y0
|
|
Y1 X1
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(14..27).label("`X` is a good letter"))
|
|
.annotation(
|
|
Level::Warning
|
|
.span(17..24)
|
|
.label("`Y` is a good letter too"),
|
|
),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:3
|
|
|
|
|
3 | X0 Y0
|
|
| ____^ -
|
|
| | ______|
|
|
4 | || Y1 X1
|
|
| ||____-__^ `X` is a good letter
|
|
| |____|
|
|
| `Y` is a good letter too
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn different_overlap() {
|
|
let source = r#"
|
|
fn foo() {
|
|
X0 Y0 Z0
|
|
X1 Y1 Z1
|
|
X2 Y2 Z2
|
|
X3 Y3 Z3
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(17..38).label("`X` is a good letter"))
|
|
.annotation(
|
|
Level::Warning
|
|
.span(31..49)
|
|
.label("`Y` is a good letter too"),
|
|
),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:6
|
|
|
|
|
3 | X0 Y0 Z0
|
|
| _______^
|
|
4 | | X1 Y1 Z1
|
|
| | _________-
|
|
5 | || X2 Y2 Z2
|
|
| ||____^ `X` is a good letter
|
|
6 | | X3 Y3 Z3
|
|
| |____- `Y` is a good letter too
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn triple_overlap() {
|
|
let source = r#"
|
|
fn foo() {
|
|
X0 Y0 Z0
|
|
X1 Y1 Z1
|
|
X2 Y2 Z2
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(14..38).label("`X` is a good letter"))
|
|
.annotation(
|
|
Level::Warning
|
|
.span(17..41)
|
|
.label("`Y` is a good letter too"),
|
|
)
|
|
.annotation(Level::Warning.span(20..44).label("`Z` label")),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:3
|
|
|
|
|
3 | X0 Y0 Z0
|
|
| _____^ - -
|
|
| | _______| |
|
|
| || _________|
|
|
4 | ||| X1 Y1 Z1
|
|
5 | ||| X2 Y2 Z2
|
|
| |||____^__-__- `Z` label
|
|
| ||_____|__|
|
|
| |______| `Y` is a good letter too
|
|
| `X` is a good letter
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn triple_exact_overlap() {
|
|
let source = r#"
|
|
fn foo() {
|
|
X0 Y0 Z0
|
|
X1 Y1 Z1
|
|
X2 Y2 Z2
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(14..38).label("`X` is a good letter"))
|
|
.annotation(
|
|
Level::Warning
|
|
.span(14..38)
|
|
.label("`Y` is a good letter too"),
|
|
)
|
|
.annotation(Level::Warning.span(14..38).label("`Z` label")),
|
|
);
|
|
|
|
// This should have a `^` but we currently don't support the idea of a
|
|
// "primary" annotation, which would solve this
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:3
|
|
|
|
|
3 | / X0 Y0 Z0
|
|
4 | | X1 Y1 Z1
|
|
5 | | X2 Y2 Z2
|
|
| | -
|
|
| |____|
|
|
| `X` is a good letter
|
|
| `Y` is a good letter too
|
|
| `Z` label
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn minimum_depth() {
|
|
let source = r#"
|
|
fn foo() {
|
|
X0 Y0 Z0
|
|
X1 Y1 Z1
|
|
X2 Y2 Z2
|
|
X3 Y3 Z3
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(17..27).label("`X` is a good letter"))
|
|
.annotation(
|
|
Level::Warning
|
|
.span(28..44)
|
|
.label("`Y` is a good letter too"),
|
|
)
|
|
.annotation(Level::Warning.span(36..52).label("`Z`")),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:6
|
|
|
|
|
3 | X0 Y0 Z0
|
|
| _______^
|
|
4 | | X1 Y1 Z1
|
|
| | ____^_-
|
|
| ||____|
|
|
| | `X` is a good letter
|
|
5 | | X2 Y2 Z2
|
|
| |___-______- `Y` is a good letter too
|
|
| ___|
|
|
| |
|
|
6 | | X3 Y3 Z3
|
|
| |_______- `Z`
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn non_overlapping() {
|
|
let source = r#"
|
|
fn foo() {
|
|
X0 Y0 Z0
|
|
X1 Y1 Z1
|
|
X2 Y2 Z2
|
|
X3 Y3 Z3
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(14..27).label("`X` is a good letter"))
|
|
.annotation(
|
|
Level::Warning
|
|
.span(39..55)
|
|
.label("`Y` is a good letter too"),
|
|
),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:3
|
|
|
|
|
3 | / X0 Y0 Z0
|
|
4 | | X1 Y1 Z1
|
|
| |____^ `X` is a good letter
|
|
5 | X2 Y2 Z2
|
|
| ______-
|
|
6 | | X3 Y3 Z3
|
|
| |__________- `Y` is a good letter too
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn overlapping_start_and_end() {
|
|
let source = r#"
|
|
fn foo() {
|
|
X0 Y0 Z0
|
|
X1 Y1 Z1
|
|
X2 Y2 Z2
|
|
X3 Y3 Z3
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(17..27).label("`X` is a good letter"))
|
|
.annotation(
|
|
Level::Warning
|
|
.span(31..55)
|
|
.label("`Y` is a good letter too"),
|
|
),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:6
|
|
|
|
|
3 | X0 Y0 Z0
|
|
| _______^
|
|
4 | | X1 Y1 Z1
|
|
| | ____^____-
|
|
| ||____|
|
|
| | `X` is a good letter
|
|
5 | | X2 Y2 Z2
|
|
6 | | X3 Y3 Z3
|
|
| |__________- `Y` is a good letter too
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn multiple_labels_primary_without_message() {
|
|
let source = r#"
|
|
fn foo() {
|
|
a { b { c } d }
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(18..25).label(""))
|
|
.annotation(Level::Warning.span(14..27).label("`a` is a good letter"))
|
|
.annotation(Level::Warning.span(22..23).label("")),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:7
|
|
|
|
|
3 | a { b { c } d }
|
|
| ----^^^^-^^-- `a` is a good letter
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn multiple_labels_secondary_without_message() {
|
|
let source = r#"
|
|
fn foo() {
|
|
a { b { c } d }
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(14..27).label("`a` is a good letter"))
|
|
.annotation(Level::Warning.span(18..25).label("")),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:3
|
|
|
|
|
3 | a { b { c } d }
|
|
| ^^^^-------^^ `a` is a good letter
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn multiple_labels_primary_without_message_2() {
|
|
let source = r#"
|
|
fn foo() {
|
|
a { b { c } d }
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(18..25).label("`b` is a good letter"))
|
|
.annotation(Level::Warning.span(14..27).label(""))
|
|
.annotation(Level::Warning.span(22..23).label("")),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:7
|
|
|
|
|
3 | a { b { c } d }
|
|
| ----^^^^-^^--
|
|
| |
|
|
| `b` is a good letter
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn multiple_labels_secondary_without_message_2() {
|
|
let source = r#"
|
|
fn foo() {
|
|
a { b { c } d }
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(14..27).label(""))
|
|
.annotation(Level::Warning.span(18..25).label("`b` is a good letter")),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:3
|
|
|
|
|
3 | a { b { c } d }
|
|
| ^^^^-------^^
|
|
| |
|
|
| `b` is a good letter
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn multiple_labels_secondary_without_message_3() {
|
|
let source = r#"
|
|
fn foo() {
|
|
a bc d
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(14..18).label("`a` is a good letter"))
|
|
.annotation(Level::Warning.span(18..22).label("")),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:3
|
|
|
|
|
3 | a bc d
|
|
| ^^^^----
|
|
| |
|
|
| `a` is a good letter
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn multiple_labels_without_message() {
|
|
let source = r#"
|
|
fn foo() {
|
|
a { b { c } d }
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(14..27).label(""))
|
|
.annotation(Level::Warning.span(18..25).label("")),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:3
|
|
|
|
|
3 | a { b { c } d }
|
|
| ^^^^-------^^
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn multiple_labels_without_message_2() {
|
|
let source = r#"
|
|
fn foo() {
|
|
a { b { c } d }
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(18..25).label(""))
|
|
.annotation(Level::Warning.span(14..27).label(""))
|
|
.annotation(Level::Warning.span(22..23).label("")),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:7
|
|
|
|
|
3 | a { b { c } d }
|
|
| ----^^^^-^^--
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn multiple_labels_with_message() {
|
|
let source = r#"
|
|
fn foo() {
|
|
a { b { c } d }
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(14..27).label("`a` is a good letter"))
|
|
.annotation(Level::Warning.span(18..25).label("`b` is a good letter")),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:3
|
|
|
|
|
3 | a { b { c } d }
|
|
| ^^^^-------^^
|
|
| | |
|
|
| | `b` is a good letter
|
|
| `a` is a good letter
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn ingle_label_with_message() {
|
|
let source = r#"
|
|
fn foo() {
|
|
a { b { c } d }
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(14..27).label("`a` is a good letter")),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:3
|
|
|
|
|
3 | a { b { c } d }
|
|
| ^^^^^^^^^^^^^ `a` is a good letter
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn single_label_without_message() {
|
|
let source = r#"
|
|
fn foo() {
|
|
a { b { c } d }
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(14..27).label("")),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:3
|
|
|
|
|
3 | a { b { c } d }
|
|
| ^^^^^^^^^^^^^
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn long_snippet() {
|
|
let source = r#"
|
|
fn foo() {
|
|
X0 Y0 Z0
|
|
X1 Y1 Z1
|
|
1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6
|
|
7
|
|
8
|
|
9
|
|
10
|
|
X2 Y2 Z2
|
|
X3 Y3 Z3
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(17..27).label("`X` is a good letter"))
|
|
.annotation(
|
|
Level::Warning
|
|
.span(31..76)
|
|
.label("`Y` is a good letter too"),
|
|
),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:6
|
|
|
|
|
3 | X0 Y0 Z0
|
|
| _______^
|
|
4 | | X1 Y1 Z1
|
|
| | ____^____-
|
|
| ||____|
|
|
| | `X` is a good letter
|
|
5 | | 1
|
|
... |
|
|
15 | | X2 Y2 Z2
|
|
16 | | X3 Y3 Z3
|
|
| |__________- `Y` is a good letter too
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|
|
#[test]
|
|
fn long_snippet_multiple_spans() {
|
|
let source = r#"
|
|
fn foo() {
|
|
X0 Y0 Z0
|
|
1
|
|
2
|
|
3
|
|
X1 Y1 Z1
|
|
4
|
|
5
|
|
6
|
|
X2 Y2 Z2
|
|
7
|
|
8
|
|
9
|
|
10
|
|
X3 Y3 Z3
|
|
}
|
|
"#;
|
|
let input = Level::Error.title("foo").snippet(
|
|
Snippet::source(source)
|
|
.line_start(1)
|
|
.origin("test.rs")
|
|
.fold(true)
|
|
.annotation(Level::Error.span(17..73).label("`Y` is a good letter"))
|
|
.annotation(
|
|
Level::Warning
|
|
.span(37..56)
|
|
.label("`Z` is a good letter too"),
|
|
),
|
|
);
|
|
|
|
let expected = str![[r#"
|
|
error: foo
|
|
--> test.rs:3:6
|
|
|
|
|
3 | X0 Y0 Z0
|
|
| _______^
|
|
4 | | 1
|
|
5 | | 2
|
|
6 | | 3
|
|
7 | | X1 Y1 Z1
|
|
| | _________-
|
|
8 | || 4
|
|
9 | || 5
|
|
10 | || 6
|
|
11 | || X2 Y2 Z2
|
|
| ||__________- `Z` is a good letter too
|
|
12 | | 7
|
|
... |
|
|
15 | | 10
|
|
16 | | X3 Y3 Z3
|
|
| |________^ `Y` is a good letter
|
|
|
|
|
"#]];
|
|
let renderer = Renderer::plain();
|
|
assert_data_eq!(renderer.render(input).to_string(), expected);
|
|
}
|