diff options
Diffstat (limited to 'crates/libeditor/tests/test.rs')
-rw-r--r-- | crates/libeditor/tests/test.rs | 369 |
1 files changed, 0 insertions, 369 deletions
diff --git a/crates/libeditor/tests/test.rs b/crates/libeditor/tests/test.rs deleted file mode 100644 index 440afe92d..000000000 --- a/crates/libeditor/tests/test.rs +++ /dev/null | |||
@@ -1,369 +0,0 @@ | |||
1 | extern crate libeditor; | ||
2 | extern crate libsyntax2; | ||
3 | #[macro_use] | ||
4 | extern crate test_utils; | ||
5 | |||
6 | use test_utils::{assert_eq_dbg, add_cursor, extract_offset, extract_range}; | ||
7 | use libsyntax2::{File, TextUnit, TextRange}; | ||
8 | use libeditor::{ | ||
9 | ActionResult, | ||
10 | highlight, runnables, extend_selection, file_structure, | ||
11 | flip_comma, add_derive, add_impl, matching_brace, | ||
12 | join_lines, on_eq_typed, scope_completion, | ||
13 | }; | ||
14 | |||
15 | #[test] | ||
16 | fn test_extend_selection() { | ||
17 | fn do_check(before: &str, afters: &[&str]) { | ||
18 | let (cursor, before) = extract_offset(before); | ||
19 | let file = file(&before); | ||
20 | let mut range = TextRange::offset_len(cursor, 0.into()); | ||
21 | for &after in afters { | ||
22 | range = extend_selection(&file, range) | ||
23 | .unwrap(); | ||
24 | let actual = &before[range]; | ||
25 | assert_eq!(after, actual); | ||
26 | } | ||
27 | } | ||
28 | |||
29 | do_check( | ||
30 | r#"fn foo() { <|>1 + 1 }"#, | ||
31 | &["1", "1 + 1", "{ 1 + 1 }"], | ||
32 | ); | ||
33 | |||
34 | do_check( | ||
35 | r#" | ||
36 | impl S { | ||
37 | <|> fn foo() { | ||
38 | |||
39 | } | ||
40 | }"#, | ||
41 | &["fn foo() {\n\n }"] | ||
42 | ); | ||
43 | do_check( | ||
44 | r#" | ||
45 | fn bar(){} | ||
46 | |||
47 | // fn foo() { | ||
48 | // 1 + <|>1 | ||
49 | // } | ||
50 | |||
51 | // fn foo(){} | ||
52 | "#, | ||
53 | &["// 1 + 1", "// fn foo() {\n// 1 + 1\n// }"] | ||
54 | ); | ||
55 | } | ||
56 | |||
57 | #[test] | ||
58 | fn test_highlighting() { | ||
59 | let file = file(r#" | ||
60 | // comment | ||
61 | fn main() {} | ||
62 | println!("Hello, {}!", 92); | ||
63 | "#); | ||
64 | let hls = highlight(&file); | ||
65 | assert_eq_dbg( | ||
66 | r#"[HighlightedRange { range: [1; 11), tag: "comment" }, | ||
67 | HighlightedRange { range: [12; 14), tag: "keyword" }, | ||
68 | HighlightedRange { range: [15; 19), tag: "function" }, | ||
69 | HighlightedRange { range: [29; 36), tag: "text" }, | ||
70 | HighlightedRange { range: [38; 50), tag: "string" }, | ||
71 | HighlightedRange { range: [52; 54), tag: "literal" }]"#, | ||
72 | &hls, | ||
73 | ); | ||
74 | } | ||
75 | |||
76 | #[test] | ||
77 | fn test_runnables() { | ||
78 | let file = file(r#" | ||
79 | fn main() {} | ||
80 | |||
81 | #[test] | ||
82 | fn test_foo() {} | ||
83 | |||
84 | #[test] | ||
85 | #[ignore] | ||
86 | fn test_foo() {} | ||
87 | "#); | ||
88 | let runnables = runnables(&file); | ||
89 | assert_eq_dbg( | ||
90 | r#"[Runnable { range: [1; 13), kind: Bin }, | ||
91 | Runnable { range: [15; 39), kind: Test { name: "test_foo" } }, | ||
92 | Runnable { range: [41; 75), kind: Test { name: "test_foo" } }]"#, | ||
93 | &runnables, | ||
94 | ) | ||
95 | } | ||
96 | |||
97 | #[test] | ||
98 | fn test_file_structure() { | ||
99 | let file = file(r#" | ||
100 | struct Foo { | ||
101 | x: i32 | ||
102 | } | ||
103 | |||
104 | mod m { | ||
105 | fn bar() {} | ||
106 | } | ||
107 | |||
108 | enum E { X, Y(i32) } | ||
109 | type T = (); | ||
110 | static S: i32 = 92; | ||
111 | const C: i32 = 92; | ||
112 | |||
113 | impl E {} | ||
114 | |||
115 | impl fmt::Debug for E {} | ||
116 | "#); | ||
117 | let symbols = file_structure(&file); | ||
118 | assert_eq_dbg( | ||
119 | r#"[StructureNode { parent: None, label: "Foo", navigation_range: [8; 11), node_range: [1; 26), kind: STRUCT_DEF }, | ||
120 | StructureNode { parent: Some(0), label: "x", navigation_range: [18; 19), node_range: [18; 24), kind: NAMED_FIELD_DEF }, | ||
121 | StructureNode { parent: None, label: "m", navigation_range: [32; 33), node_range: [28; 53), kind: MODULE }, | ||
122 | StructureNode { parent: Some(2), label: "bar", navigation_range: [43; 46), node_range: [40; 51), kind: FN_DEF }, | ||
123 | StructureNode { parent: None, label: "E", navigation_range: [60; 61), node_range: [55; 75), kind: ENUM_DEF }, | ||
124 | StructureNode { parent: None, label: "T", navigation_range: [81; 82), node_range: [76; 88), kind: TYPE_DEF }, | ||
125 | StructureNode { parent: None, label: "S", navigation_range: [96; 97), node_range: [89; 108), kind: STATIC_DEF }, | ||
126 | StructureNode { parent: None, label: "C", navigation_range: [115; 116), node_range: [109; 127), kind: CONST_DEF }, | ||
127 | StructureNode { parent: None, label: "impl E", navigation_range: [134; 135), node_range: [129; 138), kind: IMPL_ITEM }, | ||
128 | StructureNode { parent: None, label: "impl fmt::Debug for E", navigation_range: [160; 161), node_range: [140; 164), kind: IMPL_ITEM }]"#, | ||
129 | &symbols, | ||
130 | ) | ||
131 | } | ||
132 | |||
133 | #[test] | ||
134 | fn test_swap_comma() { | ||
135 | check_action( | ||
136 | "fn foo(x: i32,<|> y: Result<(), ()>) {}", | ||
137 | "fn foo(y: Result<(), ()>,<|> x: i32) {}", | ||
138 | |file, off| flip_comma(file, off).map(|f| f()), | ||
139 | ) | ||
140 | } | ||
141 | |||
142 | #[test] | ||
143 | fn test_add_derive() { | ||
144 | check_action( | ||
145 | "struct Foo { a: i32, <|>}", | ||
146 | "#[derive(<|>)]\nstruct Foo { a: i32, }", | ||
147 | |file, off| add_derive(file, off).map(|f| f()), | ||
148 | ); | ||
149 | check_action( | ||
150 | "struct Foo { <|> a: i32, }", | ||
151 | "#[derive(<|>)]\nstruct Foo { a: i32, }", | ||
152 | |file, off| add_derive(file, off).map(|f| f()), | ||
153 | ); | ||
154 | check_action( | ||
155 | "#[derive(Clone)]\nstruct Foo { a: i32<|>, }", | ||
156 | "#[derive(Clone<|>)]\nstruct Foo { a: i32, }", | ||
157 | |file, off| add_derive(file, off).map(|f| f()), | ||
158 | ); | ||
159 | } | ||
160 | |||
161 | #[test] | ||
162 | fn test_add_impl() { | ||
163 | check_action( | ||
164 | "struct Foo {<|>}\n", | ||
165 | "struct Foo {}\n\nimpl Foo {\n<|>\n}\n", | ||
166 | |file, off| add_impl(file, off).map(|f| f()), | ||
167 | ); | ||
168 | check_action( | ||
169 | "struct Foo<T: Clone> {<|>}", | ||
170 | "struct Foo<T: Clone> {}\n\nimpl<T: Clone> Foo<T> {\n<|>\n}", | ||
171 | |file, off| add_impl(file, off).map(|f| f()), | ||
172 | ); | ||
173 | } | ||
174 | |||
175 | #[test] | ||
176 | fn test_matching_brace() { | ||
177 | fn do_check(before: &str, after: &str) { | ||
178 | let (pos, before) = extract_offset(before); | ||
179 | let file = file(&before); | ||
180 | let new_pos = match matching_brace(&file, pos) { | ||
181 | None => pos, | ||
182 | Some(pos) => pos, | ||
183 | }; | ||
184 | let actual = add_cursor(&before, new_pos); | ||
185 | assert_eq_text!(after, &actual); | ||
186 | } | ||
187 | |||
188 | do_check( | ||
189 | "struct Foo { a: i32, }<|>", | ||
190 | "struct Foo <|>{ a: i32, }", | ||
191 | ); | ||
192 | } | ||
193 | |||
194 | #[test] | ||
195 | fn test_join_lines_cursor() { | ||
196 | fn do_check(before: &str, after: &str) { | ||
197 | check_action(before, after, |file, offset| { | ||
198 | let range = TextRange::offset_len(offset, 0.into()); | ||
199 | let res = join_lines(file, range); | ||
200 | Some(res) | ||
201 | }) | ||
202 | } | ||
203 | |||
204 | do_check(r" | ||
205 | fn foo() { | ||
206 | <|>foo(1, | ||
207 | ) | ||
208 | } | ||
209 | ", r" | ||
210 | fn foo() { | ||
211 | <|>foo(1) | ||
212 | } | ||
213 | "); | ||
214 | do_check(r" | ||
215 | pub fn reparse(&self, edit: &AtomEdit) -> File { | ||
216 | <|>self.incremental_reparse(edit).unwrap_or_else(|| { | ||
217 | self.full_reparse(edit) | ||
218 | }) | ||
219 | } | ||
220 | ", r" | ||
221 | pub fn reparse(&self, edit: &AtomEdit) -> File { | ||
222 | <|>self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) | ||
223 | } | ||
224 | "); | ||
225 | do_check(r" | ||
226 | fn foo() { | ||
227 | foo(<|>{ | ||
228 | 92 | ||
229 | }) | ||
230 | }", r" | ||
231 | fn foo() { | ||
232 | foo(<|>92) | ||
233 | }"); | ||
234 | } | ||
235 | |||
236 | #[test] | ||
237 | fn test_join_lines_selection() { | ||
238 | fn do_check(before: &str, after: &str) { | ||
239 | let (sel, before) = extract_range(before); | ||
240 | let file = file(&before); | ||
241 | let result = join_lines(&file, sel); | ||
242 | let actual = result.edit.apply(&before); | ||
243 | assert_eq_text!(after, &actual); | ||
244 | } | ||
245 | |||
246 | do_check(r" | ||
247 | fn foo() { | ||
248 | <|>foo(1, | ||
249 | 2, | ||
250 | 3, | ||
251 | <|>) | ||
252 | } | ||
253 | ", r" | ||
254 | fn foo() { | ||
255 | foo(1, 2, 3) | ||
256 | } | ||
257 | "); | ||
258 | |||
259 | do_check(r" | ||
260 | struct Foo <|>{ | ||
261 | f: u32, | ||
262 | }<|> | ||
263 | ", r" | ||
264 | struct Foo { f: u32 } | ||
265 | "); | ||
266 | } | ||
267 | |||
268 | #[test] | ||
269 | fn test_on_eq_typed() { | ||
270 | fn do_check(before: &str, after: &str) { | ||
271 | let (offset, before) = extract_offset(before); | ||
272 | let file = file(&before); | ||
273 | let result = on_eq_typed(&file, offset).unwrap(); | ||
274 | let actual = result.edit.apply(&before); | ||
275 | assert_eq_text!(after, &actual); | ||
276 | } | ||
277 | |||
278 | // do_check(r" | ||
279 | // fn foo() { | ||
280 | // let foo =<|> | ||
281 | // } | ||
282 | // ", r" | ||
283 | // fn foo() { | ||
284 | // let foo =; | ||
285 | // } | ||
286 | // "); | ||
287 | do_check(r" | ||
288 | fn foo() { | ||
289 | let foo =<|> 1 + 1 | ||
290 | } | ||
291 | ", r" | ||
292 | fn foo() { | ||
293 | let foo = 1 + 1; | ||
294 | } | ||
295 | "); | ||
296 | // do_check(r" | ||
297 | // fn foo() { | ||
298 | // let foo =<|> | ||
299 | // let bar = 1; | ||
300 | // } | ||
301 | // ", r" | ||
302 | // fn foo() { | ||
303 | // let foo =; | ||
304 | // let bar = 1; | ||
305 | // } | ||
306 | // "); | ||
307 | |||
308 | } | ||
309 | |||
310 | #[test] | ||
311 | fn test_completion() { | ||
312 | fn do_check(code: &str, expected_completions: &str) { | ||
313 | let (off, code) = extract_offset(&code); | ||
314 | let file = file(&code); | ||
315 | let completions = scope_completion(&file, off).unwrap(); | ||
316 | assert_eq_dbg(expected_completions, &completions); | ||
317 | } | ||
318 | |||
319 | do_check(r" | ||
320 | fn quux(x: i32) { | ||
321 | let y = 92; | ||
322 | 1 + <|>; | ||
323 | let z = (); | ||
324 | } | ||
325 | ", r#"[CompletionItem { name: "y" }, | ||
326 | CompletionItem { name: "x" }]"#); | ||
327 | |||
328 | do_check(r" | ||
329 | fn quux() { | ||
330 | if let Some(x) = foo() { | ||
331 | let y = 92; | ||
332 | }; | ||
333 | if let Some(a) = bar() { | ||
334 | let b = 62; | ||
335 | 1 + <|> | ||
336 | } | ||
337 | } | ||
338 | ", r#"[CompletionItem { name: "b" }, | ||
339 | CompletionItem { name: "a" }]"#); | ||
340 | |||
341 | do_check(r" | ||
342 | fn quux() { | ||
343 | for x in &[1, 2, 3] { | ||
344 | <|> | ||
345 | } | ||
346 | } | ||
347 | ", r#"[CompletionItem { name: "x" }]"#); | ||
348 | } | ||
349 | |||
350 | fn file(text: &str) -> File { | ||
351 | File::parse(text) | ||
352 | } | ||
353 | |||
354 | fn check_action<F: Fn(&File, TextUnit) -> Option<ActionResult>>( | ||
355 | before: &str, | ||
356 | after: &str, | ||
357 | f: F, | ||
358 | ) { | ||
359 | let (before_cursor_pos, before) = extract_offset(before); | ||
360 | let file = file(&before); | ||
361 | let result = f(&file, before_cursor_pos).expect("code action is not applicable"); | ||
362 | let actual = result.edit.apply(&before); | ||
363 | let actual_cursor_pos = match result.cursor_position { | ||
364 | None => result.edit.apply_to_offset(before_cursor_pos).unwrap(), | ||
365 | Some(off) => off, | ||
366 | }; | ||
367 | let actual = add_cursor(&actual, actual_cursor_pos); | ||
368 | assert_eq_text!(after, &actual); | ||
369 | } | ||