]> git.lizzy.rs Git - rust.git/blob - crates/ra_ide/src/syntax_highlighting/tests.rs
Merge #4423
[rust.git] / crates / ra_ide / src / syntax_highlighting / tests.rs
1 use std::fs;
2
3 use test_utils::{assert_eq_text, project_dir, read_text};
4
5 use crate::{
6     mock_analysis::{single_file, MockAnalysis},
7     FileRange, TextRange,
8 };
9
10 #[test]
11 fn test_highlighting() {
12     let (analysis, file_id) = single_file(
13         r#"
14 #[derive(Clone, Debug)]
15 struct Foo {
16     pub x: i32,
17     pub y: i32,
18 }
19
20 trait Bar {
21     fn bar(&self) -> i32;
22 }
23
24 impl Bar for Foo {
25     fn bar(&self) -> i32 {
26         self.x
27     }
28 }
29
30 static mut STATIC_MUT: i32 = 0;
31
32 fn foo<'a, T>() -> T {
33     foo::<'a, i32>()
34 }
35
36 macro_rules! def_fn {
37     ($($tt:tt)*) => {$($tt)*}
38 }
39
40 def_fn! {
41     fn bar() -> u32 {
42         100
43     }
44 }
45
46 // comment
47 fn main() {
48     println!("Hello, {}!", 92);
49
50     let mut vec = Vec::new();
51     if true {
52         let x = 92;
53         vec.push(Foo { x, y: 1 });
54     }
55     unsafe {
56         vec.set_len(0);
57         STATIC_MUT = 1;
58     }
59
60     for e in vec {
61         // Do nothing
62     }
63
64     let mut x = 42;
65     let y = &mut x;
66     let z = &y;
67
68     y;
69 }
70
71 enum Option<T> {
72     Some(T),
73     None,
74 }
75 use Option::*;
76
77 impl<T> Option<T> {
78     fn and<U>(self, other: Option<U>) -> Option<(T, U)> {
79         match other {
80             None => unimplemented!(),
81             Nope => Nope,
82         }
83     }
84 }
85 "#
86         .trim(),
87     );
88     let dst_file = project_dir().join("crates/ra_ide/src/snapshots/highlighting.html");
89     let actual_html = &analysis.highlight_as_html(file_id, false).unwrap();
90     let expected_html = &read_text(&dst_file);
91     fs::write(dst_file, &actual_html).unwrap();
92     assert_eq_text!(expected_html, actual_html);
93 }
94
95 #[test]
96 fn test_rainbow_highlighting() {
97     let (analysis, file_id) = single_file(
98         r#"
99 fn main() {
100     let hello = "hello";
101     let x = hello.to_string();
102     let y = hello.to_string();
103
104     let x = "other color please!";
105     let y = x.to_string();
106 }
107
108 fn bar() {
109     let mut hello = "hello";
110 }
111 "#
112         .trim(),
113     );
114     let dst_file = project_dir().join("crates/ra_ide/src/snapshots/rainbow_highlighting.html");
115     let actual_html = &analysis.highlight_as_html(file_id, true).unwrap();
116     let expected_html = &read_text(&dst_file);
117     fs::write(dst_file, &actual_html).unwrap();
118     assert_eq_text!(expected_html, actual_html);
119 }
120
121 #[test]
122 fn accidentally_quadratic() {
123     let file = project_dir().join("crates/ra_syntax/test_data/accidentally_quadratic");
124     let src = fs::read_to_string(file).unwrap();
125
126     let mut mock = MockAnalysis::new();
127     let file_id = mock.add_file("/main.rs", &src);
128     let host = mock.analysis_host();
129
130     // let t = std::time::Instant::now();
131     let _ = host.analysis().highlight(file_id).unwrap();
132     // eprintln!("elapsed: {:?}", t.elapsed());
133 }
134
135 #[test]
136 fn test_ranges() {
137     let (analysis, file_id) = single_file(
138         r#"
139             #[derive(Clone, Debug)]
140             struct Foo {
141                 pub x: i32,
142                 pub y: i32,
143             }"#,
144     );
145
146     // The "x"
147     let highlights = &analysis
148         .highlight_range(FileRange { file_id, range: TextRange::at(82.into(), 1.into()) })
149         .unwrap();
150
151     assert_eq!(&highlights[0].highlight.to_string(), "field.declaration");
152 }
153
154 #[test]
155 fn test_flattening() {
156     let (analysis, file_id) = single_file(
157         r##"
158 fn fixture(ra_fixture: &str) {}
159
160 fn main() {
161     fixture(r#"
162         trait Foo {
163             fn foo() {
164                 println!("2 + 2 = {}", 4);
165             }
166         }"#
167     );
168 }"##
169         .trim(),
170     );
171
172     let dst_file = project_dir().join("crates/ra_ide/src/snapshots/highlight_injection.html");
173     let actual_html = &analysis.highlight_as_html(file_id, false).unwrap();
174     let expected_html = &read_text(&dst_file);
175     fs::write(dst_file, &actual_html).unwrap();
176     assert_eq_text!(expected_html, actual_html);
177 }
178
179 #[test]
180 fn ranges_sorted() {
181     let (analysis, file_id) = single_file(
182         r#"
183 #[foo(bar = "bar")]
184 macro_rules! test {}
185 }"#
186         .trim(),
187     );
188     let _ = analysis.highlight(file_id).unwrap();
189 }
190
191 #[test]
192 fn test_string_highlighting() {
193     // The format string detection is based on macro-expansion,
194     // thus, we have to copy the macro definition from `std`
195     let (analysis, file_id) = single_file(
196         r#"
197 macro_rules! println {
198     ($($arg:tt)*) => ({
199         $crate::io::_print($crate::format_args_nl!($($arg)*));
200     })
201 }
202 #[rustc_builtin_macro]
203 macro_rules! format_args_nl {
204     ($fmt:expr) => {{ /* compiler built-in */ }};
205     ($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
206 }
207
208 fn main() {
209     // from https://doc.rust-lang.org/std/fmt/index.html
210     println!("Hello");                 // => "Hello"
211     println!("Hello, {}!", "world");   // => "Hello, world!"
212     println!("The number is {}", 1);   // => "The number is 1"
213     println!("{:?}", (3, 4));          // => "(3, 4)"
214     println!("{value}", value=4);      // => "4"
215     println!("{} {}", 1, 2);           // => "1 2"
216     println!("{:04}", 42);             // => "0042" with leading zerosV
217     println!("{1} {} {0} {}", 1, 2);   // => "2 1 1 2"
218     println!("{argument}", argument = "test");   // => "test"
219     println!("{name} {}", 1, name = 2);          // => "2 1"
220     println!("{a} {c} {b}", a="a", b='b', c=3);  // => "a 3 b"
221     println!("Hello {:5}!", "x");
222     println!("Hello {:1$}!", "x", 5);
223     println!("Hello {1:0$}!", 5, "x");
224     println!("Hello {:width$}!", "x", width = 5);
225     println!("Hello {:<5}!", "x");
226     println!("Hello {:-<5}!", "x");
227     println!("Hello {:^5}!", "x");
228     println!("Hello {:>5}!", "x");
229     println!("Hello {:+}!", 5);
230     println!("{:#x}!", 27);
231     println!("Hello {:05}!", 5);
232     println!("Hello {:05}!", -5);
233     println!("{:#010x}!", 27);
234     println!("Hello {0} is {1:.5}", "x", 0.01);
235     println!("Hello {1} is {2:.0$}", 5, "x", 0.01);
236     println!("Hello {0} is {2:.1$}", "x", 5, 0.01);
237     println!("Hello {} is {:.*}",    "x", 5, 0.01);
238     println!("Hello {} is {2:.*}",   "x", 5, 0.01);
239     println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
240     println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56);
241     println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56");
242     println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56");
243     println!("Hello {{}}");
244     println!("{{ Hello");
245
246     println!(r"Hello, {}!", "world");
247
248     println!("{\x41}", A = 92);
249     println!("{ничоси}", ничоси = 92);
250 }"#
251         .trim(),
252     );
253
254     let dst_file = project_dir().join("crates/ra_ide/src/snapshots/highlight_strings.html");
255     let actual_html = &analysis.highlight_as_html(file_id, false).unwrap();
256     let expected_html = &read_text(&dst_file);
257     fs::write(dst_file, &actual_html).unwrap();
258     assert_eq_text!(expected_html, actual_html);
259 }