diff options
author | Aleksey Kladov <[email protected]> | 2019-11-27 18:32:33 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-11-27 18:35:06 +0000 |
commit | 757e593b253b4df7e6fc8bf15a4d4f34c9d484c5 (patch) | |
tree | d972d3a7e6457efdb5e0c558a8350db1818d07ae /crates/ra_ide_api/src/runnables.rs | |
parent | d9a36a736bfb91578a36505e7237212959bb55fe (diff) |
rename ra_ide_api -> ra_ide
Diffstat (limited to 'crates/ra_ide_api/src/runnables.rs')
-rw-r--r-- | crates/ra_ide_api/src/runnables.rs | 242 |
1 files changed, 0 insertions, 242 deletions
diff --git a/crates/ra_ide_api/src/runnables.rs b/crates/ra_ide_api/src/runnables.rs deleted file mode 100644 index 8039a5164..000000000 --- a/crates/ra_ide_api/src/runnables.rs +++ /dev/null | |||
@@ -1,242 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use hir::Source; | ||
4 | use itertools::Itertools; | ||
5 | use ra_db::SourceDatabase; | ||
6 | use ra_syntax::{ | ||
7 | ast::{self, AstNode, AttrsOwner, ModuleItemOwner, NameOwner}, | ||
8 | match_ast, SyntaxNode, TextRange, | ||
9 | }; | ||
10 | |||
11 | use crate::{db::RootDatabase, FileId}; | ||
12 | |||
13 | #[derive(Debug)] | ||
14 | pub struct Runnable { | ||
15 | pub range: TextRange, | ||
16 | pub kind: RunnableKind, | ||
17 | } | ||
18 | |||
19 | #[derive(Debug)] | ||
20 | pub enum RunnableKind { | ||
21 | Test { name: String }, | ||
22 | TestMod { path: String }, | ||
23 | Bench { name: String }, | ||
24 | Bin, | ||
25 | } | ||
26 | |||
27 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { | ||
28 | let parse = db.parse(file_id); | ||
29 | parse.tree().syntax().descendants().filter_map(|i| runnable(db, file_id, i)).collect() | ||
30 | } | ||
31 | |||
32 | fn runnable(db: &RootDatabase, file_id: FileId, item: SyntaxNode) -> Option<Runnable> { | ||
33 | match_ast! { | ||
34 | match item { | ||
35 | ast::FnDef(it) => { runnable_fn(it) }, | ||
36 | ast::Module(it) => { runnable_mod(db, file_id, it) }, | ||
37 | _ => { None }, | ||
38 | } | ||
39 | } | ||
40 | } | ||
41 | |||
42 | fn runnable_fn(fn_def: ast::FnDef) -> Option<Runnable> { | ||
43 | let name = fn_def.name()?.text().clone(); | ||
44 | let kind = if name == "main" { | ||
45 | RunnableKind::Bin | ||
46 | } else if fn_def.has_atom_attr("test") { | ||
47 | RunnableKind::Test { name: name.to_string() } | ||
48 | } else if fn_def.has_atom_attr("bench") { | ||
49 | RunnableKind::Bench { name: name.to_string() } | ||
50 | } else { | ||
51 | return None; | ||
52 | }; | ||
53 | Some(Runnable { range: fn_def.syntax().text_range(), kind }) | ||
54 | } | ||
55 | |||
56 | fn runnable_mod(db: &RootDatabase, file_id: FileId, module: ast::Module) -> Option<Runnable> { | ||
57 | let has_test_function = module | ||
58 | .item_list()? | ||
59 | .items() | ||
60 | .filter_map(|it| match it { | ||
61 | ast::ModuleItem::FnDef(it) => Some(it), | ||
62 | _ => None, | ||
63 | }) | ||
64 | .any(|f| f.has_atom_attr("test")); | ||
65 | if !has_test_function { | ||
66 | return None; | ||
67 | } | ||
68 | let range = module.syntax().text_range(); | ||
69 | let src = hir::ModuleSource::from_child_node(db, Source::new(file_id.into(), &module.syntax())); | ||
70 | let module = hir::Module::from_definition(db, Source::new(file_id.into(), src))?; | ||
71 | |||
72 | let path = module.path_to_root(db).into_iter().rev().filter_map(|it| it.name(db)).join("::"); | ||
73 | Some(Runnable { range, kind: RunnableKind::TestMod { path } }) | ||
74 | } | ||
75 | |||
76 | #[cfg(test)] | ||
77 | mod tests { | ||
78 | use insta::assert_debug_snapshot; | ||
79 | |||
80 | use crate::mock_analysis::analysis_and_position; | ||
81 | |||
82 | #[test] | ||
83 | fn test_runnables() { | ||
84 | let (analysis, pos) = analysis_and_position( | ||
85 | r#" | ||
86 | //- /lib.rs | ||
87 | <|> //empty | ||
88 | fn main() {} | ||
89 | |||
90 | #[test] | ||
91 | fn test_foo() {} | ||
92 | |||
93 | #[test] | ||
94 | #[ignore] | ||
95 | fn test_foo() {} | ||
96 | "#, | ||
97 | ); | ||
98 | let runnables = analysis.runnables(pos.file_id).unwrap(); | ||
99 | assert_debug_snapshot!(&runnables, | ||
100 | @r###" | ||
101 | [ | ||
102 | Runnable { | ||
103 | range: [1; 21), | ||
104 | kind: Bin, | ||
105 | }, | ||
106 | Runnable { | ||
107 | range: [22; 46), | ||
108 | kind: Test { | ||
109 | name: "test_foo", | ||
110 | }, | ||
111 | }, | ||
112 | Runnable { | ||
113 | range: [47; 81), | ||
114 | kind: Test { | ||
115 | name: "test_foo", | ||
116 | }, | ||
117 | }, | ||
118 | ] | ||
119 | "### | ||
120 | ); | ||
121 | } | ||
122 | |||
123 | #[test] | ||
124 | fn test_runnables_module() { | ||
125 | let (analysis, pos) = analysis_and_position( | ||
126 | r#" | ||
127 | //- /lib.rs | ||
128 | <|> //empty | ||
129 | mod test_mod { | ||
130 | #[test] | ||
131 | fn test_foo1() {} | ||
132 | } | ||
133 | "#, | ||
134 | ); | ||
135 | let runnables = analysis.runnables(pos.file_id).unwrap(); | ||
136 | assert_debug_snapshot!(&runnables, | ||
137 | @r###" | ||
138 | [ | ||
139 | Runnable { | ||
140 | range: [1; 59), | ||
141 | kind: TestMod { | ||
142 | path: "test_mod", | ||
143 | }, | ||
144 | }, | ||
145 | Runnable { | ||
146 | range: [28; 57), | ||
147 | kind: Test { | ||
148 | name: "test_foo1", | ||
149 | }, | ||
150 | }, | ||
151 | ] | ||
152 | "### | ||
153 | ); | ||
154 | } | ||
155 | |||
156 | #[test] | ||
157 | fn test_runnables_one_depth_layer_module() { | ||
158 | let (analysis, pos) = analysis_and_position( | ||
159 | r#" | ||
160 | //- /lib.rs | ||
161 | <|> //empty | ||
162 | mod foo { | ||
163 | mod test_mod { | ||
164 | #[test] | ||
165 | fn test_foo1() {} | ||
166 | } | ||
167 | } | ||
168 | "#, | ||
169 | ); | ||
170 | let runnables = analysis.runnables(pos.file_id).unwrap(); | ||
171 | assert_debug_snapshot!(&runnables, | ||
172 | @r###" | ||
173 | [ | ||
174 | Runnable { | ||
175 | range: [23; 85), | ||
176 | kind: TestMod { | ||
177 | path: "foo::test_mod", | ||
178 | }, | ||
179 | }, | ||
180 | Runnable { | ||
181 | range: [46; 79), | ||
182 | kind: Test { | ||
183 | name: "test_foo1", | ||
184 | }, | ||
185 | }, | ||
186 | ] | ||
187 | "### | ||
188 | ); | ||
189 | } | ||
190 | |||
191 | #[test] | ||
192 | fn test_runnables_multiple_depth_module() { | ||
193 | let (analysis, pos) = analysis_and_position( | ||
194 | r#" | ||
195 | //- /lib.rs | ||
196 | <|> //empty | ||
197 | mod foo { | ||
198 | mod bar { | ||
199 | mod test_mod { | ||
200 | #[test] | ||
201 | fn test_foo1() {} | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | "#, | ||
206 | ); | ||
207 | let runnables = analysis.runnables(pos.file_id).unwrap(); | ||
208 | assert_debug_snapshot!(&runnables, | ||
209 | @r###" | ||
210 | [ | ||
211 | Runnable { | ||
212 | range: [41; 115), | ||
213 | kind: TestMod { | ||
214 | path: "foo::bar::test_mod", | ||
215 | }, | ||
216 | }, | ||
217 | Runnable { | ||
218 | range: [68; 105), | ||
219 | kind: Test { | ||
220 | name: "test_foo1", | ||
221 | }, | ||
222 | }, | ||
223 | ] | ||
224 | "### | ||
225 | ); | ||
226 | } | ||
227 | |||
228 | #[test] | ||
229 | fn test_runnables_no_test_function_in_module() { | ||
230 | let (analysis, pos) = analysis_and_position( | ||
231 | r#" | ||
232 | //- /lib.rs | ||
233 | <|> //empty | ||
234 | mod test_mod { | ||
235 | fn foo1() {} | ||
236 | } | ||
237 | "#, | ||
238 | ); | ||
239 | let runnables = analysis.runnables(pos.file_id).unwrap(); | ||
240 | assert!(runnables.is_empty()) | ||
241 | } | ||
242 | } | ||