1e73685ebSopenharmony_ciuse codespan_reporting::diagnostic::{Diagnostic, Label};
2e73685ebSopenharmony_ciuse codespan_reporting::files::{SimpleFile, SimpleFiles};
3e73685ebSopenharmony_ciuse codespan_reporting::term::{termcolor::Color, Config, DisplayStyle, Styles};
4e73685ebSopenharmony_ci
5e73685ebSopenharmony_cimod support;
6e73685ebSopenharmony_ci
7e73685ebSopenharmony_ciuse self::support::TestData;
8e73685ebSopenharmony_ci
9e73685ebSopenharmony_cilazy_static::lazy_static! {
10e73685ebSopenharmony_ci    static ref TEST_CONFIG: Config = Config {
11e73685ebSopenharmony_ci        // Always use blue so tests are consistent across platforms
12e73685ebSopenharmony_ci        styles: Styles::with_blue(Color::Blue),
13e73685ebSopenharmony_ci        ..Config::default()
14e73685ebSopenharmony_ci    };
15e73685ebSopenharmony_ci}
16e73685ebSopenharmony_ci
17e73685ebSopenharmony_cimacro_rules! test_emit {
18e73685ebSopenharmony_ci    (rich_color) => {
19e73685ebSopenharmony_ci        #[test]
20e73685ebSopenharmony_ci        fn rich_color() {
21e73685ebSopenharmony_ci            let config = Config {
22e73685ebSopenharmony_ci                display_style: DisplayStyle::Rich,
23e73685ebSopenharmony_ci                ..TEST_CONFIG.clone()
24e73685ebSopenharmony_ci            };
25e73685ebSopenharmony_ci
26e73685ebSopenharmony_ci            insta::assert_snapshot!(TEST_DATA.emit_color(&config));
27e73685ebSopenharmony_ci        }
28e73685ebSopenharmony_ci    };
29e73685ebSopenharmony_ci    (medium_color) => {
30e73685ebSopenharmony_ci        #[test]
31e73685ebSopenharmony_ci        fn medium_color() {
32e73685ebSopenharmony_ci            let config = Config {
33e73685ebSopenharmony_ci                display_style: DisplayStyle::Medium,
34e73685ebSopenharmony_ci                ..TEST_CONFIG.clone()
35e73685ebSopenharmony_ci            };
36e73685ebSopenharmony_ci
37e73685ebSopenharmony_ci            insta::assert_snapshot!(TEST_DATA.emit_color(&config));
38e73685ebSopenharmony_ci        }
39e73685ebSopenharmony_ci    };
40e73685ebSopenharmony_ci    (short_color) => {
41e73685ebSopenharmony_ci        #[test]
42e73685ebSopenharmony_ci        fn short_color() {
43e73685ebSopenharmony_ci            let config = Config {
44e73685ebSopenharmony_ci                display_style: DisplayStyle::Short,
45e73685ebSopenharmony_ci                ..TEST_CONFIG.clone()
46e73685ebSopenharmony_ci            };
47e73685ebSopenharmony_ci
48e73685ebSopenharmony_ci            insta::assert_snapshot!(TEST_DATA.emit_color(&config));
49e73685ebSopenharmony_ci        }
50e73685ebSopenharmony_ci    };
51e73685ebSopenharmony_ci    (rich_no_color) => {
52e73685ebSopenharmony_ci        #[test]
53e73685ebSopenharmony_ci        fn rich_no_color() {
54e73685ebSopenharmony_ci            let config = Config {
55e73685ebSopenharmony_ci                display_style: DisplayStyle::Rich,
56e73685ebSopenharmony_ci                ..TEST_CONFIG.clone()
57e73685ebSopenharmony_ci            };
58e73685ebSopenharmony_ci
59e73685ebSopenharmony_ci            insta::assert_snapshot!(TEST_DATA.emit_no_color(&config));
60e73685ebSopenharmony_ci        }
61e73685ebSopenharmony_ci    };
62e73685ebSopenharmony_ci    (medium_no_color) => {
63e73685ebSopenharmony_ci        #[test]
64e73685ebSopenharmony_ci        fn medium_no_color() {
65e73685ebSopenharmony_ci            let config = Config {
66e73685ebSopenharmony_ci                display_style: DisplayStyle::Medium,
67e73685ebSopenharmony_ci                ..TEST_CONFIG.clone()
68e73685ebSopenharmony_ci            };
69e73685ebSopenharmony_ci
70e73685ebSopenharmony_ci            insta::assert_snapshot!(TEST_DATA.emit_no_color(&config));
71e73685ebSopenharmony_ci        }
72e73685ebSopenharmony_ci    };
73e73685ebSopenharmony_ci    (short_no_color) => {
74e73685ebSopenharmony_ci        #[test]
75e73685ebSopenharmony_ci        fn short_no_color() {
76e73685ebSopenharmony_ci            let config = Config {
77e73685ebSopenharmony_ci                display_style: DisplayStyle::Short,
78e73685ebSopenharmony_ci                ..TEST_CONFIG.clone()
79e73685ebSopenharmony_ci            };
80e73685ebSopenharmony_ci
81e73685ebSopenharmony_ci            insta::assert_snapshot!(TEST_DATA.emit_no_color(&config));
82e73685ebSopenharmony_ci        }
83e73685ebSopenharmony_ci    };
84e73685ebSopenharmony_ci}
85e73685ebSopenharmony_ci
86e73685ebSopenharmony_cimod empty {
87e73685ebSopenharmony_ci    use super::*;
88e73685ebSopenharmony_ci
89e73685ebSopenharmony_ci    lazy_static::lazy_static! {
90e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFiles<&'static str, &'static str>> = {
91e73685ebSopenharmony_ci            let files = SimpleFiles::new();
92e73685ebSopenharmony_ci
93e73685ebSopenharmony_ci            let diagnostics = vec![
94e73685ebSopenharmony_ci                Diagnostic::bug(),
95e73685ebSopenharmony_ci                Diagnostic::error(),
96e73685ebSopenharmony_ci                Diagnostic::warning(),
97e73685ebSopenharmony_ci                Diagnostic::note(),
98e73685ebSopenharmony_ci                Diagnostic::help(),
99e73685ebSopenharmony_ci                Diagnostic::bug(),
100e73685ebSopenharmony_ci            ];
101e73685ebSopenharmony_ci
102e73685ebSopenharmony_ci            TestData { files, diagnostics }
103e73685ebSopenharmony_ci        };
104e73685ebSopenharmony_ci    }
105e73685ebSopenharmony_ci
106e73685ebSopenharmony_ci    test_emit!(rich_color);
107e73685ebSopenharmony_ci    test_emit!(medium_color);
108e73685ebSopenharmony_ci    test_emit!(short_color);
109e73685ebSopenharmony_ci    test_emit!(rich_no_color);
110e73685ebSopenharmony_ci    test_emit!(medium_no_color);
111e73685ebSopenharmony_ci    test_emit!(short_no_color);
112e73685ebSopenharmony_ci}
113e73685ebSopenharmony_ci
114e73685ebSopenharmony_ci/// Based on:
115e73685ebSopenharmony_ci/// - https://github.com/rust-lang/rust/blob/c20d7eecbc0928b57da8fe30b2ef8528e2bdd5be/src/test/ui/codemap_tests/one_line.stderr
116e73685ebSopenharmony_cimod same_line {
117e73685ebSopenharmony_ci    use super::*;
118e73685ebSopenharmony_ci
119e73685ebSopenharmony_ci    lazy_static::lazy_static! {
120e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFiles<&'static str, String>> = {
121e73685ebSopenharmony_ci            let mut files = SimpleFiles::new();
122e73685ebSopenharmony_ci
123e73685ebSopenharmony_ci            let file_id1 = files.add(
124e73685ebSopenharmony_ci                "one_line.rs",
125e73685ebSopenharmony_ci                unindent::unindent(r#"
126e73685ebSopenharmony_ci                    fn main() {
127e73685ebSopenharmony_ci                        let mut v = vec![Some("foo"), Some("bar")];
128e73685ebSopenharmony_ci                        v.push(v.pop().unwrap());
129e73685ebSopenharmony_ci                    }
130e73685ebSopenharmony_ci                "#),
131e73685ebSopenharmony_ci            );
132e73685ebSopenharmony_ci
133e73685ebSopenharmony_ci            let diagnostics = vec![
134e73685ebSopenharmony_ci                Diagnostic::error()
135e73685ebSopenharmony_ci                    .with_code("E0499")
136e73685ebSopenharmony_ci                    .with_message("cannot borrow `v` as mutable more than once at a time")
137e73685ebSopenharmony_ci                    .with_labels(vec![
138e73685ebSopenharmony_ci                        Label::primary(file_id1, 71..72)
139e73685ebSopenharmony_ci                            .with_message("second mutable borrow occurs here"),
140e73685ebSopenharmony_ci                        Label::secondary(file_id1, 64..65)
141e73685ebSopenharmony_ci                            .with_message("first borrow later used by call"),
142e73685ebSopenharmony_ci                        Label::secondary(file_id1, 66..70)
143e73685ebSopenharmony_ci                            .with_message("first mutable borrow occurs here"),
144e73685ebSopenharmony_ci                    ]),
145e73685ebSopenharmony_ci                Diagnostic::error()
146e73685ebSopenharmony_ci                    .with_message("aborting due to previous error")
147e73685ebSopenharmony_ci                    .with_notes(vec![
148e73685ebSopenharmony_ci                        "For more information about this error, try `rustc --explain E0499`.".to_owned(),
149e73685ebSopenharmony_ci                    ]),
150e73685ebSopenharmony_ci            ];
151e73685ebSopenharmony_ci
152e73685ebSopenharmony_ci            TestData { files, diagnostics }
153e73685ebSopenharmony_ci        };
154e73685ebSopenharmony_ci    }
155e73685ebSopenharmony_ci
156e73685ebSopenharmony_ci    test_emit!(rich_color);
157e73685ebSopenharmony_ci    test_emit!(medium_color);
158e73685ebSopenharmony_ci    test_emit!(short_color);
159e73685ebSopenharmony_ci    test_emit!(rich_no_color);
160e73685ebSopenharmony_ci    test_emit!(medium_no_color);
161e73685ebSopenharmony_ci    test_emit!(short_no_color);
162e73685ebSopenharmony_ci}
163e73685ebSopenharmony_ci
164e73685ebSopenharmony_ci/// Based on:
165e73685ebSopenharmony_ci/// - https://github.com/rust-lang/rust/blob/c20d7eecbc0928b57da8fe30b2ef8528e2bdd5be/src/test/ui/nested_impl_trait.stderr
166e73685ebSopenharmony_ci/// - https://github.com/rust-lang/rust/blob/c20d7eecbc0928b57da8fe30b2ef8528e2bdd5be/src/test/ui/typeck/typeck_type_placeholder_item.stderr
167e73685ebSopenharmony_ci/// - https://github.com/rust-lang/rust/blob/c20d7eecbc0928b57da8fe30b2ef8528e2bdd5be/src/test/ui/no_send_res_ports.stderr
168e73685ebSopenharmony_cimod overlapping {
169e73685ebSopenharmony_ci    use super::*;
170e73685ebSopenharmony_ci
171e73685ebSopenharmony_ci    lazy_static::lazy_static! {
172e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFiles<&'static str, String>> = {
173e73685ebSopenharmony_ci            let mut files = SimpleFiles::new();
174e73685ebSopenharmony_ci
175e73685ebSopenharmony_ci            let file_id1 = files.add(
176e73685ebSopenharmony_ci                "nested_impl_trait.rs",
177e73685ebSopenharmony_ci                unindent::unindent(r#"
178e73685ebSopenharmony_ci                    use std::fmt::Debug;
179e73685ebSopenharmony_ci
180e73685ebSopenharmony_ci                    fn fine(x: impl Into<u32>) -> impl Into<u32> { x }
181e73685ebSopenharmony_ci
182e73685ebSopenharmony_ci                    fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
183e73685ebSopenharmony_ci                "#),
184e73685ebSopenharmony_ci            );
185e73685ebSopenharmony_ci            let file_id2 = files.add(
186e73685ebSopenharmony_ci                "typeck_type_placeholder_item.rs",
187e73685ebSopenharmony_ci                unindent::unindent(r#"
188e73685ebSopenharmony_ci                    fn fn_test1() -> _ { 5 }
189e73685ebSopenharmony_ci                    fn fn_test2(x: i32) -> (_, _) { (x, x) }
190e73685ebSopenharmony_ci                "#),
191e73685ebSopenharmony_ci            );
192e73685ebSopenharmony_ci            let file_id3 = files.add(
193e73685ebSopenharmony_ci                "libstd/thread/mod.rs",
194e73685ebSopenharmony_ci                unindent::unindent(r#"
195e73685ebSopenharmony_ci                    #[stable(feature = "rust1", since = "1.0.0")]
196e73685ebSopenharmony_ci                    pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>>
197e73685ebSopenharmony_ci                    where
198e73685ebSopenharmony_ci                        F: FnOnce() -> T,
199e73685ebSopenharmony_ci                        F: Send + 'static,
200e73685ebSopenharmony_ci                        T: Send + 'static,
201e73685ebSopenharmony_ci                    {
202e73685ebSopenharmony_ci                        unsafe { self.spawn_unchecked(f) }
203e73685ebSopenharmony_ci                    }
204e73685ebSopenharmony_ci                "#),
205e73685ebSopenharmony_ci            );
206e73685ebSopenharmony_ci            let file_id4 = files.add(
207e73685ebSopenharmony_ci                "no_send_res_ports.rs",
208e73685ebSopenharmony_ci                unindent::unindent(r#"
209e73685ebSopenharmony_ci                    use std::thread;
210e73685ebSopenharmony_ci                    use std::rc::Rc;
211e73685ebSopenharmony_ci
212e73685ebSopenharmony_ci                    #[derive(Debug)]
213e73685ebSopenharmony_ci                    struct Port<T>(Rc<T>);
214e73685ebSopenharmony_ci
215e73685ebSopenharmony_ci                    fn main() {
216e73685ebSopenharmony_ci                        #[derive(Debug)]
217e73685ebSopenharmony_ci                        struct Foo {
218e73685ebSopenharmony_ci                            _x: Port<()>,
219e73685ebSopenharmony_ci                        }
220e73685ebSopenharmony_ci
221e73685ebSopenharmony_ci                        impl Drop for Foo {
222e73685ebSopenharmony_ci                            fn drop(&mut self) {}
223e73685ebSopenharmony_ci                        }
224e73685ebSopenharmony_ci
225e73685ebSopenharmony_ci                        fn foo(x: Port<()>) -> Foo {
226e73685ebSopenharmony_ci                            Foo {
227e73685ebSopenharmony_ci                                _x: x
228e73685ebSopenharmony_ci                            }
229e73685ebSopenharmony_ci                        }
230e73685ebSopenharmony_ci
231e73685ebSopenharmony_ci                        let x = foo(Port(Rc::new(())));
232e73685ebSopenharmony_ci
233e73685ebSopenharmony_ci                        thread::spawn(move|| {
234e73685ebSopenharmony_ci                            let y = x;
235e73685ebSopenharmony_ci                            println!("{:?}", y);
236e73685ebSopenharmony_ci                        });
237e73685ebSopenharmony_ci                    }
238e73685ebSopenharmony_ci                "#),
239e73685ebSopenharmony_ci            );
240e73685ebSopenharmony_ci
241e73685ebSopenharmony_ci            let diagnostics = vec![
242e73685ebSopenharmony_ci                Diagnostic::error()
243e73685ebSopenharmony_ci                    .with_code("E0666")
244e73685ebSopenharmony_ci                    .with_message("nested `impl Trait` is not allowed")
245e73685ebSopenharmony_ci                    .with_labels(vec![
246e73685ebSopenharmony_ci                        Label::primary(file_id1, 129..139)
247e73685ebSopenharmony_ci                            .with_message("nested `impl Trait` here"),
248e73685ebSopenharmony_ci                        Label::secondary(file_id1, 119..140)
249e73685ebSopenharmony_ci                            .with_message("outer `impl Trait`"),
250e73685ebSopenharmony_ci                    ]),
251e73685ebSopenharmony_ci                Diagnostic::error()
252e73685ebSopenharmony_ci                    .with_code("E0121")
253e73685ebSopenharmony_ci                    .with_message("the type placeholder `_` is not allowed within types on item signatures")
254e73685ebSopenharmony_ci                        .with_labels(vec![
255e73685ebSopenharmony_ci                            Label::primary(file_id2, 17..18)
256e73685ebSopenharmony_ci                                .with_message("not allowed in type signatures"),
257e73685ebSopenharmony_ci                            Label::secondary(file_id2, 17..18)
258e73685ebSopenharmony_ci                                .with_message("help: replace with the correct return type: `i32`"),
259e73685ebSopenharmony_ci                        ]),
260e73685ebSopenharmony_ci                Diagnostic::error()
261e73685ebSopenharmony_ci                    .with_code("E0121")
262e73685ebSopenharmony_ci                    .with_message("the type placeholder `_` is not allowed within types on item signatures")
263e73685ebSopenharmony_ci                        .with_labels(vec![
264e73685ebSopenharmony_ci                            Label::primary(file_id2, 49..50)
265e73685ebSopenharmony_ci                                .with_message("not allowed in type signatures"),
266e73685ebSopenharmony_ci                            Label::primary(file_id2, 52..53)
267e73685ebSopenharmony_ci                                .with_message("not allowed in type signatures"),
268e73685ebSopenharmony_ci                            Label::secondary(file_id2, 48..54)
269e73685ebSopenharmony_ci                                .with_message("help: replace with the correct return type: `(i32, i32)`"),
270e73685ebSopenharmony_ci                        ]),
271e73685ebSopenharmony_ci                Diagnostic::error()
272e73685ebSopenharmony_ci                    .with_code("E0277")
273e73685ebSopenharmony_ci                    .with_message("`std::rc::Rc<()>` cannot be sent between threads safely")
274e73685ebSopenharmony_ci                    .with_labels(vec![
275e73685ebSopenharmony_ci                        Label::primary(file_id4, 339..352)
276e73685ebSopenharmony_ci                            .with_message("`std::rc::Rc<()>` cannot be sent between threads safely"),
277e73685ebSopenharmony_ci                        Label::secondary(file_id4, 353..416)
278e73685ebSopenharmony_ci                            .with_message("within this `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`"),
279e73685ebSopenharmony_ci                        Label::secondary(file_id3, 141..145)
280e73685ebSopenharmony_ci                            .with_message("required by this bound in `std::thread::spawn`"),
281e73685ebSopenharmony_ci                    ])
282e73685ebSopenharmony_ci                    .with_notes(vec![
283e73685ebSopenharmony_ci                        "help: within `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`".to_owned(),
284e73685ebSopenharmony_ci                        "note: required because it appears within the type `Port<()>`".to_owned(),
285e73685ebSopenharmony_ci                        "note: required because it appears within the type `main::Foo`".to_owned(),
286e73685ebSopenharmony_ci                        "note: required because it appears within the type `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`".to_owned(),
287e73685ebSopenharmony_ci                    ]),
288e73685ebSopenharmony_ci                Diagnostic::error()
289e73685ebSopenharmony_ci                    .with_message("aborting due 5 previous errors")
290e73685ebSopenharmony_ci                    .with_notes(vec![
291e73685ebSopenharmony_ci                        "Some errors have detailed explanations: E0121, E0277, E0666.".to_owned(),
292e73685ebSopenharmony_ci                        "For more information about an error, try `rustc --explain E0121`.".to_owned(),
293e73685ebSopenharmony_ci                    ]),
294e73685ebSopenharmony_ci            ];
295e73685ebSopenharmony_ci
296e73685ebSopenharmony_ci            TestData { files, diagnostics }
297e73685ebSopenharmony_ci        };
298e73685ebSopenharmony_ci    }
299e73685ebSopenharmony_ci
300e73685ebSopenharmony_ci    test_emit!(rich_color);
301e73685ebSopenharmony_ci    test_emit!(medium_color);
302e73685ebSopenharmony_ci    test_emit!(short_color);
303e73685ebSopenharmony_ci    test_emit!(rich_no_color);
304e73685ebSopenharmony_ci    test_emit!(medium_no_color);
305e73685ebSopenharmony_ci    test_emit!(short_no_color);
306e73685ebSopenharmony_ci}
307e73685ebSopenharmony_ci
308e73685ebSopenharmony_cimod message {
309e73685ebSopenharmony_ci    use super::*;
310e73685ebSopenharmony_ci
311e73685ebSopenharmony_ci    lazy_static::lazy_static! {
312e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFiles<&'static str, &'static str>> = {
313e73685ebSopenharmony_ci            let files = SimpleFiles::new();
314e73685ebSopenharmony_ci
315e73685ebSopenharmony_ci            let diagnostics = vec![
316e73685ebSopenharmony_ci                Diagnostic::error().with_message("a message"),
317e73685ebSopenharmony_ci                Diagnostic::warning().with_message("a message"),
318e73685ebSopenharmony_ci                Diagnostic::note().with_message("a message"),
319e73685ebSopenharmony_ci                Diagnostic::help().with_message("a message"),
320e73685ebSopenharmony_ci            ];
321e73685ebSopenharmony_ci
322e73685ebSopenharmony_ci            TestData { files, diagnostics }
323e73685ebSopenharmony_ci        };
324e73685ebSopenharmony_ci    }
325e73685ebSopenharmony_ci
326e73685ebSopenharmony_ci    test_emit!(rich_color);
327e73685ebSopenharmony_ci    test_emit!(medium_color);
328e73685ebSopenharmony_ci    test_emit!(short_color);
329e73685ebSopenharmony_ci    test_emit!(rich_no_color);
330e73685ebSopenharmony_ci    test_emit!(medium_no_color);
331e73685ebSopenharmony_ci    test_emit!(short_no_color);
332e73685ebSopenharmony_ci}
333e73685ebSopenharmony_ci
334e73685ebSopenharmony_cimod message_and_notes {
335e73685ebSopenharmony_ci    use super::*;
336e73685ebSopenharmony_ci
337e73685ebSopenharmony_ci    lazy_static::lazy_static! {
338e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFiles<&'static str, &'static str>> = {
339e73685ebSopenharmony_ci            let files = SimpleFiles::new();
340e73685ebSopenharmony_ci
341e73685ebSopenharmony_ci            let diagnostics = vec![
342e73685ebSopenharmony_ci                Diagnostic::error().with_message("a message").with_notes(vec!["a note".to_owned()]),
343e73685ebSopenharmony_ci                Diagnostic::warning().with_message("a message").with_notes(vec!["a note".to_owned()]),
344e73685ebSopenharmony_ci                Diagnostic::note().with_message("a message").with_notes(vec!["a note".to_owned()]),
345e73685ebSopenharmony_ci                Diagnostic::help().with_message("a message").with_notes(vec!["a note".to_owned()]),
346e73685ebSopenharmony_ci            ];
347e73685ebSopenharmony_ci
348e73685ebSopenharmony_ci            TestData { files, diagnostics }
349e73685ebSopenharmony_ci        };
350e73685ebSopenharmony_ci    }
351e73685ebSopenharmony_ci
352e73685ebSopenharmony_ci    test_emit!(rich_color);
353e73685ebSopenharmony_ci    test_emit!(medium_color);
354e73685ebSopenharmony_ci    test_emit!(short_color);
355e73685ebSopenharmony_ci    test_emit!(rich_no_color);
356e73685ebSopenharmony_ci    test_emit!(medium_no_color);
357e73685ebSopenharmony_ci    test_emit!(short_no_color);
358e73685ebSopenharmony_ci}
359e73685ebSopenharmony_ci
360e73685ebSopenharmony_cimod message_errorcode {
361e73685ebSopenharmony_ci    use super::*;
362e73685ebSopenharmony_ci
363e73685ebSopenharmony_ci    lazy_static::lazy_static! {
364e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFiles<&'static str, &'static str>> = {
365e73685ebSopenharmony_ci            let files = SimpleFiles::new();
366e73685ebSopenharmony_ci
367e73685ebSopenharmony_ci            let diagnostics = vec![
368e73685ebSopenharmony_ci                Diagnostic::error().with_message("a message").with_code("E0001"),
369e73685ebSopenharmony_ci                Diagnostic::warning().with_message("a message").with_code("W001"),
370e73685ebSopenharmony_ci                Diagnostic::note().with_message("a message").with_code("N0815"),
371e73685ebSopenharmony_ci                Diagnostic::help().with_message("a message").with_code("H4711"),
372e73685ebSopenharmony_ci                Diagnostic::error().with_message("where did my errorcode go?").with_code(""),
373e73685ebSopenharmony_ci                Diagnostic::warning().with_message("where did my errorcode go?").with_code(""),
374e73685ebSopenharmony_ci                Diagnostic::note().with_message("where did my errorcode go?").with_code(""),
375e73685ebSopenharmony_ci                Diagnostic::help().with_message("where did my errorcode go?").with_code(""),
376e73685ebSopenharmony_ci            ];
377e73685ebSopenharmony_ci
378e73685ebSopenharmony_ci            TestData { files, diagnostics }
379e73685ebSopenharmony_ci        };
380e73685ebSopenharmony_ci    }
381e73685ebSopenharmony_ci
382e73685ebSopenharmony_ci    test_emit!(rich_no_color);
383e73685ebSopenharmony_ci    test_emit!(short_no_color);
384e73685ebSopenharmony_ci}
385e73685ebSopenharmony_ci
386e73685ebSopenharmony_cimod empty_ranges {
387e73685ebSopenharmony_ci    use super::*;
388e73685ebSopenharmony_ci
389e73685ebSopenharmony_ci    lazy_static::lazy_static! {
390e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFile<&'static str, &'static str>> = {
391e73685ebSopenharmony_ci            let file = SimpleFile::new("hello", "Hello world!\nBye world!\n   ");
392e73685ebSopenharmony_ci            let eof = file.source().len();
393e73685ebSopenharmony_ci
394e73685ebSopenharmony_ci            let diagnostics = vec![
395e73685ebSopenharmony_ci                Diagnostic::note()
396e73685ebSopenharmony_ci                    .with_message("middle")
397e73685ebSopenharmony_ci                    .with_labels(vec![Label::primary((), 6..6).with_message("middle")]),
398e73685ebSopenharmony_ci                Diagnostic::note()
399e73685ebSopenharmony_ci                    .with_message("end of line")
400e73685ebSopenharmony_ci                    .with_labels(vec![Label::primary((), 12..12).with_message("end of line")]),
401e73685ebSopenharmony_ci                Diagnostic::note()
402e73685ebSopenharmony_ci                    .with_message("end of line")
403e73685ebSopenharmony_ci                    .with_labels(vec![Label::primary((), 23..23).with_message("end of line")]),
404e73685ebSopenharmony_ci                Diagnostic::note()
405e73685ebSopenharmony_ci                    .with_message("end of file")
406e73685ebSopenharmony_ci                    .with_labels(vec![Label::primary((), eof..eof).with_message("end of file")]),
407e73685ebSopenharmony_ci            ];
408e73685ebSopenharmony_ci
409e73685ebSopenharmony_ci            TestData { files: file, diagnostics }
410e73685ebSopenharmony_ci        };
411e73685ebSopenharmony_ci    }
412e73685ebSopenharmony_ci
413e73685ebSopenharmony_ci    test_emit!(rich_color);
414e73685ebSopenharmony_ci    test_emit!(medium_color);
415e73685ebSopenharmony_ci    test_emit!(short_color);
416e73685ebSopenharmony_ci    test_emit!(rich_no_color);
417e73685ebSopenharmony_ci    test_emit!(medium_no_color);
418e73685ebSopenharmony_ci    test_emit!(short_no_color);
419e73685ebSopenharmony_ci}
420e73685ebSopenharmony_ci
421e73685ebSopenharmony_cimod same_ranges {
422e73685ebSopenharmony_ci    use super::*;
423e73685ebSopenharmony_ci
424e73685ebSopenharmony_ci    lazy_static::lazy_static! {
425e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFile<&'static str, &'static str>> = {
426e73685ebSopenharmony_ci            let file = SimpleFile::new("same_range", "::S { }");
427e73685ebSopenharmony_ci
428e73685ebSopenharmony_ci            let diagnostics = vec![
429e73685ebSopenharmony_ci                Diagnostic::error()
430e73685ebSopenharmony_ci                    .with_message("Unexpected token")
431e73685ebSopenharmony_ci                    .with_labels(vec![
432e73685ebSopenharmony_ci                        Label::primary((), 4..4).with_message("Unexpected '{'"),
433e73685ebSopenharmony_ci                        Label::secondary((), 4..4).with_message("Expected '('"),
434e73685ebSopenharmony_ci                    ]),
435e73685ebSopenharmony_ci            ];
436e73685ebSopenharmony_ci
437e73685ebSopenharmony_ci            TestData { files: file, diagnostics }
438e73685ebSopenharmony_ci        };
439e73685ebSopenharmony_ci    }
440e73685ebSopenharmony_ci
441e73685ebSopenharmony_ci    test_emit!(rich_color);
442e73685ebSopenharmony_ci    test_emit!(medium_color);
443e73685ebSopenharmony_ci    test_emit!(short_color);
444e73685ebSopenharmony_ci    test_emit!(rich_no_color);
445e73685ebSopenharmony_ci    test_emit!(medium_no_color);
446e73685ebSopenharmony_ci    test_emit!(short_no_color);
447e73685ebSopenharmony_ci}
448e73685ebSopenharmony_ci
449e73685ebSopenharmony_cimod multifile {
450e73685ebSopenharmony_ci    use super::*;
451e73685ebSopenharmony_ci
452e73685ebSopenharmony_ci    lazy_static::lazy_static! {
453e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFiles<&'static str, String>> = {
454e73685ebSopenharmony_ci            let mut files = SimpleFiles::new();
455e73685ebSopenharmony_ci
456e73685ebSopenharmony_ci            let file_id1 = files.add(
457e73685ebSopenharmony_ci                "Data/Nat.fun",
458e73685ebSopenharmony_ci                unindent::unindent(
459e73685ebSopenharmony_ci                    "
460e73685ebSopenharmony_ci                        module Data.Nat where
461e73685ebSopenharmony_ci
462e73685ebSopenharmony_ci                        data Nat : Type where
463e73685ebSopenharmony_ci                            zero : Nat
464e73685ebSopenharmony_ci                            succ : NatNat
465e73685ebSopenharmony_ci
466e73685ebSopenharmony_ci                        {-# BUILTIN NATRAL Nat #-}
467e73685ebSopenharmony_ci
468e73685ebSopenharmony_ci                        infixl 6 _+_ _-_
469e73685ebSopenharmony_ci
470e73685ebSopenharmony_ci                        _+_ : NatNatNat
471e73685ebSopenharmony_ci                        zero    + n₂ = n₂
472e73685ebSopenharmony_ci                        succ n₁ + n₂ = succ (n₁ + n₂)
473e73685ebSopenharmony_ci
474e73685ebSopenharmony_ci                        _-_ : NatNatNat
475e73685ebSopenharmony_ci                        n₁      - zero    = n₁
476e73685ebSopenharmony_ci                        zero    - succ n₂ = zero
477e73685ebSopenharmony_ci                        succ n₁ - succ n₂ = n₁ - n₂
478e73685ebSopenharmony_ci                    ",
479e73685ebSopenharmony_ci                ),
480e73685ebSopenharmony_ci            );
481e73685ebSopenharmony_ci
482e73685ebSopenharmony_ci            let file_id2 = files.add(
483e73685ebSopenharmony_ci                "Test.fun",
484e73685ebSopenharmony_ci                unindent::unindent(
485e73685ebSopenharmony_ci                    r#"
486e73685ebSopenharmony_ci                        module Test where
487e73685ebSopenharmony_ci
488e73685ebSopenharmony_ci                        _ : Nat
489e73685ebSopenharmony_ci                        _ = 123 + "hello"
490e73685ebSopenharmony_ci                    "#,
491e73685ebSopenharmony_ci                ),
492e73685ebSopenharmony_ci            );
493e73685ebSopenharmony_ci
494e73685ebSopenharmony_ci            let diagnostics = vec![
495e73685ebSopenharmony_ci                // Unknown builtin error
496e73685ebSopenharmony_ci                Diagnostic::error()
497e73685ebSopenharmony_ci                    .with_message("unknown builtin: `NATRAL`")
498e73685ebSopenharmony_ci                    .with_labels(vec![Label::primary(file_id1, 96..102).with_message("unknown builtin")])
499e73685ebSopenharmony_ci                    .with_notes(vec![
500e73685ebSopenharmony_ci                        "there is a builtin with a similar name: `NATURAL`".to_owned(),
501e73685ebSopenharmony_ci                    ]),
502e73685ebSopenharmony_ci                // Unused parameter warning
503e73685ebSopenharmony_ci                Diagnostic::warning()
504e73685ebSopenharmony_ci                    .with_message("unused parameter pattern: `n₂`")
505e73685ebSopenharmony_ci                    .with_labels(vec![Label::primary(file_id1, 285..289).with_message("unused parameter")])
506e73685ebSopenharmony_ci                    .with_notes(vec!["consider using a wildcard pattern: `_`".to_owned()]),
507e73685ebSopenharmony_ci                // Unexpected type error
508e73685ebSopenharmony_ci                Diagnostic::error()
509e73685ebSopenharmony_ci                    .with_message("unexpected type in application of `_+_`")
510e73685ebSopenharmony_ci                    .with_code("E0001")
511e73685ebSopenharmony_ci                    .with_labels(vec![
512e73685ebSopenharmony_ci                        Label::primary(file_id2, 37..44).with_message("expected `Nat`, found `String`"),
513e73685ebSopenharmony_ci                        Label::secondary(file_id1, 130..155).with_message("based on the definition of `_+_`"),
514e73685ebSopenharmony_ci                    ])
515e73685ebSopenharmony_ci                    .with_notes(vec![unindent::unindent(
516e73685ebSopenharmony_ci                        "
517e73685ebSopenharmony_ci                            expected type `Nat`
518e73685ebSopenharmony_ci                               found type `String`
519e73685ebSopenharmony_ci                        ",
520e73685ebSopenharmony_ci                    )]),
521e73685ebSopenharmony_ci            ];
522e73685ebSopenharmony_ci
523e73685ebSopenharmony_ci            TestData { files, diagnostics }
524e73685ebSopenharmony_ci        };
525e73685ebSopenharmony_ci    }
526e73685ebSopenharmony_ci
527e73685ebSopenharmony_ci    test_emit!(rich_color);
528e73685ebSopenharmony_ci    test_emit!(medium_color);
529e73685ebSopenharmony_ci    test_emit!(short_color);
530e73685ebSopenharmony_ci    test_emit!(rich_no_color);
531e73685ebSopenharmony_ci    test_emit!(medium_no_color);
532e73685ebSopenharmony_ci    test_emit!(short_no_color);
533e73685ebSopenharmony_ci}
534e73685ebSopenharmony_ci
535e73685ebSopenharmony_cimod fizz_buzz {
536e73685ebSopenharmony_ci    use super::*;
537e73685ebSopenharmony_ci
538e73685ebSopenharmony_ci    lazy_static::lazy_static! {
539e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFiles<&'static str, String>> = {
540e73685ebSopenharmony_ci            let mut files = SimpleFiles::new();
541e73685ebSopenharmony_ci
542e73685ebSopenharmony_ci            let file_id = files.add(
543e73685ebSopenharmony_ci                "FizzBuzz.fun",
544e73685ebSopenharmony_ci                unindent::unindent(
545e73685ebSopenharmony_ci                    r#"
546e73685ebSopenharmony_ci                        module FizzBuzz where
547e73685ebSopenharmony_ci
548e73685ebSopenharmony_ci                        fizz₁ : NatString
549e73685ebSopenharmony_ci                        fizznum = case (mod num 5) (mod num 3) of
550e73685ebSopenharmony_ci                            0 0 => "FizzBuzz"
551e73685ebSopenharmony_ci                            0 _ => "Fizz"
552e73685ebSopenharmony_ci                            _ 0 => "Buzz"
553e73685ebSopenharmony_ci                            _ _ => num
554e73685ebSopenharmony_ci
555e73685ebSopenharmony_ci                        fizz₂ : NatString
556e73685ebSopenharmony_ci                        fizznum =
557e73685ebSopenharmony_ci                            case (mod num 5) (mod num 3) of
558e73685ebSopenharmony_ci                                0 0 => "FizzBuzz"
559e73685ebSopenharmony_ci                                0 _ => "Fizz"
560e73685ebSopenharmony_ci                                _ 0 => "Buzz"
561e73685ebSopenharmony_ci                                _ _ => num
562e73685ebSopenharmony_ci                    "#,
563e73685ebSopenharmony_ci                ),
564e73685ebSopenharmony_ci            );
565e73685ebSopenharmony_ci
566e73685ebSopenharmony_ci            let diagnostics = vec![
567e73685ebSopenharmony_ci                // Incompatible match clause error
568e73685ebSopenharmony_ci                Diagnostic::error()
569e73685ebSopenharmony_ci                    .with_message("`case` clauses have incompatible types")
570e73685ebSopenharmony_ci                    .with_code("E0308")
571e73685ebSopenharmony_ci                    .with_labels(vec![
572e73685ebSopenharmony_ci                        Label::primary(file_id, 163..166).with_message("expected `String`, found `Nat`"),
573e73685ebSopenharmony_ci                        Label::secondary(file_id, 62..166).with_message("`case` clauses have incompatible types"),
574e73685ebSopenharmony_ci                        Label::secondary(file_id, 41..47).with_message("expected type `String` found here"),
575e73685ebSopenharmony_ci                    ])
576e73685ebSopenharmony_ci                    .with_notes(vec![unindent::unindent(
577e73685ebSopenharmony_ci                        "
578e73685ebSopenharmony_ci                            expected type `String`
579e73685ebSopenharmony_ci                               found type `Nat`
580e73685ebSopenharmony_ci                        ",
581e73685ebSopenharmony_ci                    )]),
582e73685ebSopenharmony_ci                // Incompatible match clause error
583e73685ebSopenharmony_ci                Diagnostic::error()
584e73685ebSopenharmony_ci                    .with_message("`case` clauses have incompatible types")
585e73685ebSopenharmony_ci                    .with_code("E0308")
586e73685ebSopenharmony_ci                    .with_labels(vec![
587e73685ebSopenharmony_ci                        Label::primary(file_id, 328..331).with_message("expected `String`, found `Nat`"),
588e73685ebSopenharmony_ci                        Label::secondary(file_id, 211..331).with_message("`case` clauses have incompatible types"),
589e73685ebSopenharmony_ci                        Label::secondary(file_id, 258..268).with_message("this is found to be of type `String`"),
590e73685ebSopenharmony_ci                        Label::secondary(file_id, 284..290).with_message("this is found to be of type `String`"),
591e73685ebSopenharmony_ci                        Label::secondary(file_id, 306..312).with_message("this is found to be of type `String`"),
592e73685ebSopenharmony_ci                        Label::secondary(file_id, 186..192).with_message("expected type `String` found here"),
593e73685ebSopenharmony_ci                    ])
594e73685ebSopenharmony_ci                    .with_notes(vec![unindent::unindent(
595e73685ebSopenharmony_ci                        "
596e73685ebSopenharmony_ci                            expected type `String`
597e73685ebSopenharmony_ci                               found type `Nat`
598e73685ebSopenharmony_ci                        ",
599e73685ebSopenharmony_ci                    )]),
600e73685ebSopenharmony_ci            ];
601e73685ebSopenharmony_ci
602e73685ebSopenharmony_ci            TestData { files, diagnostics }
603e73685ebSopenharmony_ci        };
604e73685ebSopenharmony_ci    }
605e73685ebSopenharmony_ci
606e73685ebSopenharmony_ci    test_emit!(rich_color);
607e73685ebSopenharmony_ci    test_emit!(medium_color);
608e73685ebSopenharmony_ci    test_emit!(short_color);
609e73685ebSopenharmony_ci    test_emit!(rich_no_color);
610e73685ebSopenharmony_ci    test_emit!(medium_no_color);
611e73685ebSopenharmony_ci    test_emit!(short_no_color);
612e73685ebSopenharmony_ci}
613e73685ebSopenharmony_ci
614e73685ebSopenharmony_cimod multiline_overlapping {
615e73685ebSopenharmony_ci    use super::*;
616e73685ebSopenharmony_ci
617e73685ebSopenharmony_ci    lazy_static::lazy_static! {
618e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFile<&'static str, String>> = {
619e73685ebSopenharmony_ci            let file = SimpleFile::new(
620e73685ebSopenharmony_ci                "codespan/src/file.rs",
621e73685ebSopenharmony_ci                [
622e73685ebSopenharmony_ci                    "        match line_index.compare(self.last_line_index()) {",
623e73685ebSopenharmony_ci                    "            Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]),",
624e73685ebSopenharmony_ci                    "            Ordering::Equal => Ok(self.source_span().end()),",
625e73685ebSopenharmony_ci                    "            Ordering::Greater => LineIndexOutOfBoundsError {",
626e73685ebSopenharmony_ci                    "                given: line_index,",
627e73685ebSopenharmony_ci                    "                max: self.last_line_index(),",
628e73685ebSopenharmony_ci                    "            },",
629e73685ebSopenharmony_ci                    "        }",
630e73685ebSopenharmony_ci                ].join("\n"),
631e73685ebSopenharmony_ci            );
632e73685ebSopenharmony_ci
633e73685ebSopenharmony_ci            let diagnostics = vec![
634e73685ebSopenharmony_ci                Diagnostic::error()
635e73685ebSopenharmony_ci                    .with_message("match arms have incompatible types")
636e73685ebSopenharmony_ci                    .with_code("E0308")
637e73685ebSopenharmony_ci                    .with_labels(vec![
638e73685ebSopenharmony_ci                        // this secondary label is before the primary label to test the locus calculation (see issue #259)
639e73685ebSopenharmony_ci                        Label::secondary((), 89..134).with_message("this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`"),
640e73685ebSopenharmony_ci                        Label::primary((), 230..351).with_message("expected enum `Result`, found struct `LineIndexOutOfBoundsError`"),
641e73685ebSopenharmony_ci                        Label::secondary((), 8..362).with_message("`match` arms have incompatible types"),
642e73685ebSopenharmony_ci                        Label::secondary((), 167..195).with_message("this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`"),
643e73685ebSopenharmony_ci                    ])
644e73685ebSopenharmony_ci                    .with_notes(vec![unindent::unindent(
645e73685ebSopenharmony_ci                        "
646e73685ebSopenharmony_ci                            expected type `Result<ByteIndex, LineIndexOutOfBoundsError>`
647e73685ebSopenharmony_ci                               found type `LineIndexOutOfBoundsError`
648e73685ebSopenharmony_ci                        ",
649e73685ebSopenharmony_ci                    )]),
650e73685ebSopenharmony_ci            ];
651e73685ebSopenharmony_ci
652e73685ebSopenharmony_ci            TestData { files: file, diagnostics }
653e73685ebSopenharmony_ci        };
654e73685ebSopenharmony_ci    }
655e73685ebSopenharmony_ci
656e73685ebSopenharmony_ci    test_emit!(rich_color);
657e73685ebSopenharmony_ci    test_emit!(medium_color);
658e73685ebSopenharmony_ci    test_emit!(short_color);
659e73685ebSopenharmony_ci    test_emit!(rich_no_color);
660e73685ebSopenharmony_ci    test_emit!(medium_no_color);
661e73685ebSopenharmony_ci    test_emit!(short_no_color);
662e73685ebSopenharmony_ci}
663e73685ebSopenharmony_ci
664e73685ebSopenharmony_cimod tabbed {
665e73685ebSopenharmony_ci    use super::*;
666e73685ebSopenharmony_ci
667e73685ebSopenharmony_ci    lazy_static::lazy_static! {
668e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFiles<&'static str, String>> = {
669e73685ebSopenharmony_ci            let mut files = SimpleFiles::new();
670e73685ebSopenharmony_ci
671e73685ebSopenharmony_ci            let file_id = files.add(
672e73685ebSopenharmony_ci                "tabbed",
673e73685ebSopenharmony_ci                [
674e73685ebSopenharmony_ci                    "Entity:",
675e73685ebSopenharmony_ci                    "\tArmament:",
676e73685ebSopenharmony_ci                    "\t\tWeapon: DogJaw",
677e73685ebSopenharmony_ci                    "\t\tReloadingCondition:\tattack-cooldown",
678e73685ebSopenharmony_ci                    "\tFoo: Bar",
679e73685ebSopenharmony_ci                ]
680e73685ebSopenharmony_ci                .join("\n"),
681e73685ebSopenharmony_ci            );
682e73685ebSopenharmony_ci
683e73685ebSopenharmony_ci            let diagnostics = vec![
684e73685ebSopenharmony_ci                Diagnostic::warning()
685e73685ebSopenharmony_ci                    .with_message("unknown weapon `DogJaw`")
686e73685ebSopenharmony_ci                    .with_labels(vec![Label::primary(file_id, 29..35).with_message("the weapon")]),
687e73685ebSopenharmony_ci                Diagnostic::warning()
688e73685ebSopenharmony_ci                    .with_message("unknown condition `attack-cooldown`")
689e73685ebSopenharmony_ci                    .with_labels(vec![Label::primary(file_id, 58..73).with_message("the condition")]),
690e73685ebSopenharmony_ci                Diagnostic::warning()
691e73685ebSopenharmony_ci                    .with_message("unknown field `Foo`")
692e73685ebSopenharmony_ci                    .with_labels(vec![Label::primary(file_id, 75..78).with_message("the field")]),
693e73685ebSopenharmony_ci            ];
694e73685ebSopenharmony_ci
695e73685ebSopenharmony_ci            TestData { files, diagnostics }
696e73685ebSopenharmony_ci        };
697e73685ebSopenharmony_ci    }
698e73685ebSopenharmony_ci
699e73685ebSopenharmony_ci    #[test]
700e73685ebSopenharmony_ci    fn tab_width_default_no_color() {
701e73685ebSopenharmony_ci        let config = TEST_CONFIG.clone();
702e73685ebSopenharmony_ci
703e73685ebSopenharmony_ci        insta::assert_snapshot!(TEST_DATA.emit_no_color(&config));
704e73685ebSopenharmony_ci    }
705e73685ebSopenharmony_ci
706e73685ebSopenharmony_ci    #[test]
707e73685ebSopenharmony_ci    fn tab_width_3_no_color() {
708e73685ebSopenharmony_ci        let config = Config {
709e73685ebSopenharmony_ci            tab_width: 3,
710e73685ebSopenharmony_ci            ..TEST_CONFIG.clone()
711e73685ebSopenharmony_ci        };
712e73685ebSopenharmony_ci
713e73685ebSopenharmony_ci        insta::assert_snapshot!(TEST_DATA.emit_no_color(&config));
714e73685ebSopenharmony_ci    }
715e73685ebSopenharmony_ci
716e73685ebSopenharmony_ci    #[test]
717e73685ebSopenharmony_ci    fn tab_width_6_no_color() {
718e73685ebSopenharmony_ci        let config = Config {
719e73685ebSopenharmony_ci            tab_width: 6,
720e73685ebSopenharmony_ci            ..TEST_CONFIG.clone()
721e73685ebSopenharmony_ci        };
722e73685ebSopenharmony_ci
723e73685ebSopenharmony_ci        insta::assert_snapshot!(TEST_DATA.emit_no_color(&config));
724e73685ebSopenharmony_ci    }
725e73685ebSopenharmony_ci}
726e73685ebSopenharmony_ci
727e73685ebSopenharmony_cimod tab_columns {
728e73685ebSopenharmony_ci    use super::*;
729e73685ebSopenharmony_ci
730e73685ebSopenharmony_ci    lazy_static::lazy_static! {
731e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFiles<&'static str, String>> = {
732e73685ebSopenharmony_ci            let mut files = SimpleFiles::new();
733e73685ebSopenharmony_ci
734e73685ebSopenharmony_ci            let source = [
735e73685ebSopenharmony_ci                "\thello",
736e73685ebSopenharmony_ci                "∙\thello",
737e73685ebSopenharmony_ci                "∙∙\thello",
738e73685ebSopenharmony_ci                "∙∙∙\thello",
739e73685ebSopenharmony_ci                "∙∙∙∙\thello",
740e73685ebSopenharmony_ci                "∙∙∙∙∙\thello",
741e73685ebSopenharmony_ci                "∙∙∙∙∙∙\thello",
742e73685ebSopenharmony_ci            ].join("\n");
743e73685ebSopenharmony_ci            let hello_ranges = source
744e73685ebSopenharmony_ci                .match_indices("hello")
745e73685ebSopenharmony_ci                .map(|(start, hello)| start..(start+hello.len()))
746e73685ebSopenharmony_ci                .collect::<Vec<_>>();
747e73685ebSopenharmony_ci
748e73685ebSopenharmony_ci            let file_id = files.add("tab_columns", source);
749e73685ebSopenharmony_ci
750e73685ebSopenharmony_ci            let diagnostics = vec![
751e73685ebSopenharmony_ci                Diagnostic::warning()
752e73685ebSopenharmony_ci                    .with_message("tab test")
753e73685ebSopenharmony_ci                    .with_labels(
754e73685ebSopenharmony_ci                        hello_ranges
755e73685ebSopenharmony_ci                            .into_iter()
756e73685ebSopenharmony_ci                            .map(|range| Label::primary(file_id, range))
757e73685ebSopenharmony_ci                            .collect(),
758e73685ebSopenharmony_ci                    ),
759e73685ebSopenharmony_ci            ];
760e73685ebSopenharmony_ci
761e73685ebSopenharmony_ci            TestData { files, diagnostics }
762e73685ebSopenharmony_ci        };
763e73685ebSopenharmony_ci    }
764e73685ebSopenharmony_ci
765e73685ebSopenharmony_ci    #[test]
766e73685ebSopenharmony_ci    fn tab_width_default_no_color() {
767e73685ebSopenharmony_ci        let config = TEST_CONFIG.clone();
768e73685ebSopenharmony_ci
769e73685ebSopenharmony_ci        insta::assert_snapshot!(TEST_DATA.emit_no_color(&config));
770e73685ebSopenharmony_ci    }
771e73685ebSopenharmony_ci
772e73685ebSopenharmony_ci    #[test]
773e73685ebSopenharmony_ci    fn tab_width_2_no_color() {
774e73685ebSopenharmony_ci        let config = Config {
775e73685ebSopenharmony_ci            tab_width: 2,
776e73685ebSopenharmony_ci            ..TEST_CONFIG.clone()
777e73685ebSopenharmony_ci        };
778e73685ebSopenharmony_ci
779e73685ebSopenharmony_ci        insta::assert_snapshot!(TEST_DATA.emit_no_color(&config));
780e73685ebSopenharmony_ci    }
781e73685ebSopenharmony_ci
782e73685ebSopenharmony_ci    #[test]
783e73685ebSopenharmony_ci    fn tab_width_3_no_color() {
784e73685ebSopenharmony_ci        let config = Config {
785e73685ebSopenharmony_ci            tab_width: 3,
786e73685ebSopenharmony_ci            ..TEST_CONFIG.clone()
787e73685ebSopenharmony_ci        };
788e73685ebSopenharmony_ci
789e73685ebSopenharmony_ci        insta::assert_snapshot!(TEST_DATA.emit_no_color(&config));
790e73685ebSopenharmony_ci    }
791e73685ebSopenharmony_ci
792e73685ebSopenharmony_ci    #[test]
793e73685ebSopenharmony_ci    fn tab_width_6_no_color() {
794e73685ebSopenharmony_ci        let config = Config {
795e73685ebSopenharmony_ci            tab_width: 6,
796e73685ebSopenharmony_ci            ..TEST_CONFIG.clone()
797e73685ebSopenharmony_ci        };
798e73685ebSopenharmony_ci
799e73685ebSopenharmony_ci        insta::assert_snapshot!(TEST_DATA.emit_no_color(&config));
800e73685ebSopenharmony_ci    }
801e73685ebSopenharmony_ci}
802e73685ebSopenharmony_ci
803e73685ebSopenharmony_ci/// Based on:
804e73685ebSopenharmony_ci/// - https://github.com/TheSamsa/rust/blob/75cf41afb468152611212271bae026948cd3ba46/src/test/ui/codemap_tests/unicode.stderr
805e73685ebSopenharmony_cimod unicode {
806e73685ebSopenharmony_ci    use super::*;
807e73685ebSopenharmony_ci
808e73685ebSopenharmony_ci    lazy_static::lazy_static! {
809e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFile<&'static str, String>> = {
810e73685ebSopenharmony_ci            let prefix = r#"extern "#;
811e73685ebSopenharmony_ci            let abi = r#""路濫狼á́́""#;
812e73685ebSopenharmony_ci            let suffix = r#" fn foo() {}"#;
813e73685ebSopenharmony_ci
814e73685ebSopenharmony_ci            let file = SimpleFile::new(
815e73685ebSopenharmony_ci                "unicode.rs",
816e73685ebSopenharmony_ci                format!("{}{}{}", prefix, abi, suffix),
817e73685ebSopenharmony_ci            );
818e73685ebSopenharmony_ci
819e73685ebSopenharmony_ci            let diagnostics = vec![
820e73685ebSopenharmony_ci                Diagnostic::error()
821e73685ebSopenharmony_ci                    .with_code("E0703")
822e73685ebSopenharmony_ci                    .with_message("invalid ABI: found `路濫狼á́́`")
823e73685ebSopenharmony_ci                    .with_labels(vec![
824e73685ebSopenharmony_ci                        Label::primary((), prefix.len()..(prefix.len() + abi.len()))
825e73685ebSopenharmony_ci                            .with_message("invalid ABI"),
826e73685ebSopenharmony_ci                    ])
827e73685ebSopenharmony_ci                    .with_notes(vec![unindent::unindent(
828e73685ebSopenharmony_ci                        "
829e73685ebSopenharmony_ci                            valid ABIs:
830e73685ebSopenharmony_ci                              - aapcs
831e73685ebSopenharmony_ci                              - amdgpu-kernel
832e73685ebSopenharmony_ci                              - C
833e73685ebSopenharmony_ci                              - cdecl
834e73685ebSopenharmony_ci                              - efiapi
835e73685ebSopenharmony_ci                              - fastcall
836e73685ebSopenharmony_ci                              - msp430-interrupt
837e73685ebSopenharmony_ci                              - platform-intrinsic
838e73685ebSopenharmony_ci                              - ptx-kernel
839e73685ebSopenharmony_ci                              - Rust
840e73685ebSopenharmony_ci                              - rust-call
841e73685ebSopenharmony_ci                              - rust-intrinsic
842e73685ebSopenharmony_ci                              - stdcall
843e73685ebSopenharmony_ci                              - system
844e73685ebSopenharmony_ci                              - sysv64
845e73685ebSopenharmony_ci                              - thiscall
846e73685ebSopenharmony_ci                              - unadjusted
847e73685ebSopenharmony_ci                              - vectorcall
848e73685ebSopenharmony_ci                              - win64
849e73685ebSopenharmony_ci                              - x86-interrupt
850e73685ebSopenharmony_ci                        ",
851e73685ebSopenharmony_ci                    )]),
852e73685ebSopenharmony_ci                Diagnostic::error()
853e73685ebSopenharmony_ci                    .with_message("aborting due to previous error")
854e73685ebSopenharmony_ci                    .with_notes(vec![
855e73685ebSopenharmony_ci                        "For more information about this error, try `rustc --explain E0703`.".to_owned(),
856e73685ebSopenharmony_ci                    ]),
857e73685ebSopenharmony_ci            ];
858e73685ebSopenharmony_ci
859e73685ebSopenharmony_ci            TestData { files: file, diagnostics }
860e73685ebSopenharmony_ci        };
861e73685ebSopenharmony_ci    }
862e73685ebSopenharmony_ci
863e73685ebSopenharmony_ci    test_emit!(rich_no_color);
864e73685ebSopenharmony_ci    test_emit!(medium_no_color);
865e73685ebSopenharmony_ci    test_emit!(short_no_color);
866e73685ebSopenharmony_ci}
867e73685ebSopenharmony_ci
868e73685ebSopenharmony_cimod unicode_spans {
869e73685ebSopenharmony_ci    use super::*;
870e73685ebSopenharmony_ci
871e73685ebSopenharmony_ci    lazy_static::lazy_static! {
872e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFile<&'static str, String>> = {
873e73685ebSopenharmony_ci            let moon_phases = format!("{}", r#"�����������������"#);
874e73685ebSopenharmony_ci            let invalid_start = 1;
875e73685ebSopenharmony_ci            let invalid_end = "�".len() - 1;
876e73685ebSopenharmony_ci            assert_eq!(moon_phases.is_char_boundary(invalid_start), false);
877e73685ebSopenharmony_ci            assert_eq!(moon_phases.is_char_boundary(invalid_end), false);
878e73685ebSopenharmony_ci            assert_eq!("�".len(), 4);
879e73685ebSopenharmony_ci            let file = SimpleFile::new(
880e73685ebSopenharmony_ci                "moon_jump.rs",
881e73685ebSopenharmony_ci                moon_phases,
882e73685ebSopenharmony_ci            );
883e73685ebSopenharmony_ci            let diagnostics = vec![
884e73685ebSopenharmony_ci                Diagnostic::error()
885e73685ebSopenharmony_ci                    .with_code("E01")
886e73685ebSopenharmony_ci                    .with_message("cow may not jump during new moon.")
887e73685ebSopenharmony_ci                    .with_labels(vec![
888e73685ebSopenharmony_ci                        Label::primary((), invalid_start..invalid_end)
889e73685ebSopenharmony_ci                            .with_message("Invalid jump"),
890e73685ebSopenharmony_ci                    ]),
891e73685ebSopenharmony_ci                Diagnostic::note()
892e73685ebSopenharmony_ci                    .with_message("invalid unicode range")
893e73685ebSopenharmony_ci                    .with_labels(vec![
894e73685ebSopenharmony_ci                        Label::secondary((), invalid_start.."�".len())
895e73685ebSopenharmony_ci                            .with_message("Cow range does not start at boundary."),
896e73685ebSopenharmony_ci                    ]),
897e73685ebSopenharmony_ci                Diagnostic::note()
898e73685ebSopenharmony_ci                    .with_message("invalid unicode range")
899e73685ebSopenharmony_ci                    .with_labels(vec![
900e73685ebSopenharmony_ci                        Label::secondary((), "��".len().."���".len() - 1)
901e73685ebSopenharmony_ci                            .with_message("Cow range does not end at boundary."),
902e73685ebSopenharmony_ci                    ]),
903e73685ebSopenharmony_ci                Diagnostic::note()
904e73685ebSopenharmony_ci                    .with_message("invalid unicode range")
905e73685ebSopenharmony_ci                    .with_labels(vec![
906e73685ebSopenharmony_ci                        Label::secondary((), invalid_start.."���".len() - 1)
907e73685ebSopenharmony_ci                            .with_message("Cow does not start or end at boundary."),
908e73685ebSopenharmony_ci                    ]),
909e73685ebSopenharmony_ci            ];
910e73685ebSopenharmony_ci            TestData{files: file, diagnostics }
911e73685ebSopenharmony_ci        };
912e73685ebSopenharmony_ci    }
913e73685ebSopenharmony_ci
914e73685ebSopenharmony_ci    test_emit!(rich_no_color);
915e73685ebSopenharmony_ci    test_emit!(medium_no_color);
916e73685ebSopenharmony_ci    test_emit!(short_no_color);
917e73685ebSopenharmony_ci}
918e73685ebSopenharmony_ci
919e73685ebSopenharmony_cimod position_indicator {
920e73685ebSopenharmony_ci    use super::*;
921e73685ebSopenharmony_ci
922e73685ebSopenharmony_ci    lazy_static::lazy_static! {
923e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFile<&'static str, String>> = {
924e73685ebSopenharmony_ci            let file = SimpleFile::new(
925e73685ebSopenharmony_ci                "tests/main.js",
926e73685ebSopenharmony_ci                [
927e73685ebSopenharmony_ci                    "\"use strict\";",
928e73685ebSopenharmony_ci                    "let zero=0;",
929e73685ebSopenharmony_ci                    "function foo() {",
930e73685ebSopenharmony_ci                    "  \"use strict\";",
931e73685ebSopenharmony_ci                    "  one=1;",
932e73685ebSopenharmony_ci                    "}",
933e73685ebSopenharmony_ci                ].join("\n"),
934e73685ebSopenharmony_ci            );
935e73685ebSopenharmony_ci            let diagnostics = vec![
936e73685ebSopenharmony_ci                Diagnostic::warning()
937e73685ebSopenharmony_ci                    .with_code("ParserWarning")
938e73685ebSopenharmony_ci                    .with_message("The strict mode declaration in the body of function `foo` is redundant, as the outer scope is already in strict mode")
939e73685ebSopenharmony_ci                    .with_labels(vec![
940e73685ebSopenharmony_ci                        Label::primary((), 45..57)
941e73685ebSopenharmony_ci                            .with_message("This strict mode declaration is redundant"),
942e73685ebSopenharmony_ci                        Label::secondary((), 0..12)
943e73685ebSopenharmony_ci                            .with_message("Strict mode is first declared here"),
944e73685ebSopenharmony_ci                    ]),
945e73685ebSopenharmony_ci            ];
946e73685ebSopenharmony_ci            TestData{files: file, diagnostics }
947e73685ebSopenharmony_ci        };
948e73685ebSopenharmony_ci    }
949e73685ebSopenharmony_ci
950e73685ebSopenharmony_ci    test_emit!(rich_no_color);
951e73685ebSopenharmony_ci    test_emit!(medium_no_color);
952e73685ebSopenharmony_ci    test_emit!(short_no_color);
953e73685ebSopenharmony_ci}
954e73685ebSopenharmony_ci
955e73685ebSopenharmony_cimod multiline_omit {
956e73685ebSopenharmony_ci    use super::*;
957e73685ebSopenharmony_ci
958e73685ebSopenharmony_ci    lazy_static::lazy_static! {
959e73685ebSopenharmony_ci        static ref TEST_CONFIG: Config = Config {
960e73685ebSopenharmony_ci            styles: Styles::with_blue(Color::Blue),
961e73685ebSopenharmony_ci            start_context_lines: 2,
962e73685ebSopenharmony_ci            end_context_lines: 1,
963e73685ebSopenharmony_ci            ..Config::default()
964e73685ebSopenharmony_ci        };
965e73685ebSopenharmony_ci
966e73685ebSopenharmony_ci        static ref TEST_DATA: TestData<'static, SimpleFiles<&'static str, String>> = {
967e73685ebSopenharmony_ci            let mut files = SimpleFiles::new();
968e73685ebSopenharmony_ci
969e73685ebSopenharmony_ci            let file_id1 = files.add(
970e73685ebSopenharmony_ci                "empty_if_comments.lua",
971e73685ebSopenharmony_ci                [
972e73685ebSopenharmony_ci                    "elseif 3 then", // primary label starts here
973e73685ebSopenharmony_ci                    "",              // context line
974e73685ebSopenharmony_ci                    "",
975e73685ebSopenharmony_ci                    "",
976e73685ebSopenharmony_ci                    "",
977e73685ebSopenharmony_ci                    "",
978e73685ebSopenharmony_ci                    "",
979e73685ebSopenharmony_ci                    "",
980e73685ebSopenharmony_ci                    "",     // context line
981e73685ebSopenharmony_ci                    "else", // primary label ends here
982e73685ebSopenharmony_ci                ]
983e73685ebSopenharmony_ci                .join("\n"),
984e73685ebSopenharmony_ci            );
985e73685ebSopenharmony_ci
986e73685ebSopenharmony_ci            let file_id2 = files.add(
987e73685ebSopenharmony_ci                "src/lib.rs",
988e73685ebSopenharmony_ci                [
989e73685ebSopenharmony_ci                    "fn main() {",
990e73685ebSopenharmony_ci                    "    1",   // primary label starts here
991e73685ebSopenharmony_ci                    "    + 1", // context line
992e73685ebSopenharmony_ci                    "    + 1", // skip
993e73685ebSopenharmony_ci                    "    + 1", // skip
994e73685ebSopenharmony_ci                    "    + 1", // skip
995e73685ebSopenharmony_ci                    "    +1",  // secondary label here
996e73685ebSopenharmony_ci                    "    + 1", // this single line will not be skipped; the previously filtered out label must be retrieved
997e73685ebSopenharmony_ci                    "    + 1", // context line
998e73685ebSopenharmony_ci                    "    + 1", // primary label ends here
999e73685ebSopenharmony_ci                    "}",
1000e73685ebSopenharmony_ci                ]
1001e73685ebSopenharmony_ci                .join("\n"),
1002e73685ebSopenharmony_ci            );
1003e73685ebSopenharmony_ci
1004e73685ebSopenharmony_ci            let diagnostics = vec![
1005e73685ebSopenharmony_ci                Diagnostic::error()
1006e73685ebSopenharmony_ci                    .with_message("empty elseif block")
1007e73685ebSopenharmony_ci                    .with_code("empty_if")
1008e73685ebSopenharmony_ci                    .with_labels(vec![
1009e73685ebSopenharmony_ci                        Label::primary(file_id1, 0..23),
1010e73685ebSopenharmony_ci                        Label::secondary(file_id1, 15..21).with_message("content should be in here"),
1011e73685ebSopenharmony_ci                    ]),
1012e73685ebSopenharmony_ci                Diagnostic::error()
1013e73685ebSopenharmony_ci                    .with_message("mismatched types")
1014e73685ebSopenharmony_ci                    .with_code("E0308")
1015e73685ebSopenharmony_ci                    .with_labels(vec![
1016e73685ebSopenharmony_ci                        Label::primary(file_id2, 17..80).with_message("expected (), found integer"),
1017e73685ebSopenharmony_ci                        Label::secondary(file_id2, 55..55).with_message("missing whitespace"),
1018e73685ebSopenharmony_ci                    ])
1019e73685ebSopenharmony_ci                    .with_notes(vec![
1020e73685ebSopenharmony_ci                        "note:\texpected type `()`\n\tfound type `{integer}`".to_owned()
1021e73685ebSopenharmony_ci                    ]),
1022e73685ebSopenharmony_ci            ];
1023e73685ebSopenharmony_ci
1024e73685ebSopenharmony_ci            TestData { files, diagnostics }
1025e73685ebSopenharmony_ci        };
1026e73685ebSopenharmony_ci    }
1027e73685ebSopenharmony_ci
1028e73685ebSopenharmony_ci    test_emit!(rich_no_color);
1029e73685ebSopenharmony_ci}
1030