aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/test_utils/Cargo.toml4
-rw-r--r--crates/test_utils/src/lib.rs98
2 files changed, 101 insertions, 1 deletions
diff --git a/crates/test_utils/Cargo.toml b/crates/test_utils/Cargo.toml
index 8ec986bcb..4d185b01c 100644
--- a/crates/test_utils/Cargo.toml
+++ b/crates/test_utils/Cargo.toml
@@ -11,3 +11,7 @@ doctest = false
11difference = "2.0.0" 11difference = "2.0.0"
12text-size = "1.0.0" 12text-size = "1.0.0"
13serde_json = "1.0.48" 13serde_json = "1.0.48"
14relative-path = "1.0.0"
15rustc-hash = "1.1.0"
16
17ra_cfg = { path = "../ra_cfg" } \ No newline at end of file
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index b1e3c328f..12ae5f451 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -14,8 +14,12 @@ use std::{
14 path::{Path, PathBuf}, 14 path::{Path, PathBuf},
15}; 15};
16 16
17pub use ra_cfg::CfgOptions;
18
17use serde_json::Value; 19use serde_json::Value;
18use text_size::{TextRange, TextSize}; 20use text_size::{TextRange, TextSize};
21pub use relative_path::{RelativePath, RelativePathBuf};
22pub use rustc_hash::FxHashMap;
19 23
20pub use difference::Changeset as __Changeset; 24pub use difference::Changeset as __Changeset;
21 25
@@ -159,6 +163,33 @@ pub fn add_cursor(text: &str, offset: TextSize) -> String {
159pub struct FixtureEntry { 163pub struct FixtureEntry {
160 pub meta: String, 164 pub meta: String,
161 pub text: String, 165 pub text: String,
166
167 pub parsed_meta: FixtureMeta,
168}
169
170#[derive(Debug, Eq, PartialEq)]
171pub enum FixtureMeta {
172 Root { path: RelativePathBuf },
173 File(FileMeta),
174}
175
176#[derive(Debug, Eq, PartialEq)]
177pub struct FileMeta {
178 pub path: RelativePathBuf,
179 pub krate: Option<String>,
180 pub deps: Vec<String>,
181 pub cfg: ra_cfg::CfgOptions,
182 pub edition: Option<String>,
183 pub env: FxHashMap<String, String>,
184}
185
186impl FixtureMeta {
187 pub fn path(&self) -> &RelativePath {
188 match self {
189 FixtureMeta::Root { path } => &path,
190 FixtureMeta::File(f) => &f.path,
191 }
192 }
162} 193}
163 194
164/// Parses text which looks like this: 195/// Parses text which looks like this:
@@ -200,7 +231,8 @@ The offending line: {:?}"#,
200 for line in lines.by_ref() { 231 for line in lines.by_ref() {
201 if line.starts_with("//-") { 232 if line.starts_with("//-") {
202 let meta = line["//-".len()..].trim().to_string(); 233 let meta = line["//-".len()..].trim().to_string();
203 res.push(FixtureEntry { meta, text: String::new() }) 234 let parsed_meta = parse_meta(&meta);
235 res.push(FixtureEntry { meta, parsed_meta, text: String::new() })
204 } else if let Some(entry) = res.last_mut() { 236 } else if let Some(entry) = res.last_mut() {
205 entry.text.push_str(line); 237 entry.text.push_str(line);
206 entry.text.push('\n'); 238 entry.text.push('\n');
@@ -209,6 +241,58 @@ The offending line: {:?}"#,
209 res 241 res
210} 242}
211 243
244//- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo
245fn parse_meta(meta: &str) -> FixtureMeta {
246 let components = meta.split_ascii_whitespace().collect::<Vec<_>>();
247
248 if components[0] == "root" {
249 let path: RelativePathBuf = components[1].into();
250 assert!(path.starts_with("/") && path.ends_with("/"));
251 return FixtureMeta::Root { path };
252 }
253
254 let path: RelativePathBuf = components[0].into();
255 assert!(path.starts_with("/"));
256
257 let mut krate = None;
258 let mut deps = Vec::new();
259 let mut edition = None;
260 let mut cfg = CfgOptions::default();
261 let mut env = FxHashMap::default();
262 for component in components[1..].iter() {
263 let (key, value) = split1(component, ':').unwrap();
264 match key {
265 "crate" => krate = Some(value.to_string()),
266 "deps" => deps = value.split(',').map(|it| it.to_string()).collect(),
267 "edition" => edition = Some(value.to_string()),
268 "cfg" => {
269 for key in value.split(',') {
270 match split1(key, '=') {
271 None => cfg.insert_atom(key.into()),
272 Some((k, v)) => cfg.insert_key_value(k.into(), v.into()),
273 }
274 }
275 }
276 "env" => {
277 for key in value.split(',') {
278 if let Some((k, v)) = split1(key, '=') {
279 env.insert(k.into(), v.into());
280 }
281 }
282 }
283 _ => panic!("bad component: {:?}", component),
284 }
285 }
286
287 FixtureMeta::File(FileMeta { path, krate, deps, edition, cfg, env })
288}
289
290fn split1(haystack: &str, delim: char) -> Option<(&str, &str)> {
291 let idx = haystack.find(delim)?;
292 Some((&haystack[..idx], &haystack[idx + delim.len_utf8()..]))
293}
294
295
212/// Adjusts the indentation of the first line to the minimum indentation of the rest of the lines. 296/// Adjusts the indentation of the first line to the minimum indentation of the rest of the lines.
213/// This allows fixtures to start off in a different indentation, e.g. to align the first line with 297/// This allows fixtures to start off in a different indentation, e.g. to align the first line with
214/// the other lines visually: 298/// the other lines visually:
@@ -288,6 +372,18 @@ struct Bar;
288 ) 372 )
289} 373}
290 374
375#[test]
376fn parse_fixture_gets_full_meta() {
377 let fixture = r"
378 //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b,atom env:OUTDIR=path/to,OTHER=foo
379 ";
380 let parsed = parse_fixture(fixture);
381 assert_eq!(1, parsed.len());
382
383 let parsed = &parsed[0];
384 assert_eq!("\n", parsed.text);
385}
386
291/// Same as `parse_fixture`, except it allow empty fixture 387/// Same as `parse_fixture`, except it allow empty fixture
292pub fn parse_single_fixture(fixture: &str) -> Option<FixtureEntry> { 388pub fn parse_single_fixture(fixture: &str) -> Option<FixtureEntry> {
293 if !fixture.lines().any(|it| it.trim_start().starts_with("//-")) { 389 if !fixture.lines().any(|it| it.trim_start().starts_with("//-")) {