diff options
Diffstat (limited to 'crates/tools/src/main.rs')
-rw-r--r-- | crates/tools/src/main.rs | 77 |
1 files changed, 47 insertions, 30 deletions
diff --git a/crates/tools/src/main.rs b/crates/tools/src/main.rs index 8e5e2036d..7edf8f52d 100644 --- a/crates/tools/src/main.rs +++ b/crates/tools/src/main.rs | |||
@@ -7,10 +7,11 @@ use std::{ | |||
7 | use clap::{App, Arg, SubCommand}; | 7 | use clap::{App, Arg, SubCommand}; |
8 | use failure::bail; | 8 | use failure::bail; |
9 | 9 | ||
10 | use tools::{collect_tests, generate, install_format_hook, run, run_rustfmt, Mode, Overwrite, Result, Test, Verify}; | 10 | use tools::{collect_tests, generate, install_format_hook, run, run_rustfmt, Mode, Overwrite, Result, Test, Verify, project_root}; |
11 | 11 | ||
12 | const GRAMMAR_DIR: &str = "./crates/ra_syntax/src/grammar"; | 12 | const GRAMMAR_DIR: &str = "crates/ra_syntax/src/grammar"; |
13 | const INLINE_TESTS_DIR: &str = "./crates/ra_syntax/tests/data/parser/inline"; | 13 | const OK_INLINE_TESTS_DIR: &str = "crates/ra_syntax/tests/data/parser/inline/ok"; |
14 | const ERR_INLINE_TESTS_DIR: &str = "crates/ra_syntax/tests/data/parser/inline/err"; | ||
14 | 15 | ||
15 | fn main() -> Result<()> { | 16 | fn main() -> Result<()> { |
16 | let matches = App::new("tasks") | 17 | let matches = App::new("tasks") |
@@ -48,34 +49,43 @@ fn main() -> Result<()> { | |||
48 | 49 | ||
49 | fn gen_tests(mode: Mode) -> Result<()> { | 50 | fn gen_tests(mode: Mode) -> Result<()> { |
50 | let tests = tests_from_dir(Path::new(GRAMMAR_DIR))?; | 51 | let tests = tests_from_dir(Path::new(GRAMMAR_DIR))?; |
52 | fn install_tests(tests: &HashMap<String, Test>, into: &str, mode: Mode) -> Result<()> { | ||
53 | let tests_dir = project_root().join(into); | ||
54 | if !tests_dir.is_dir() { | ||
55 | fs::create_dir_all(&tests_dir)?; | ||
56 | } | ||
57 | // ok is never actually read, but it needs to be specified to create a Test in existing_tests | ||
58 | let existing = existing_tests(&tests_dir, true)?; | ||
59 | for t in existing.keys().filter(|&t| !tests.contains_key(t)) { | ||
60 | panic!("Test is deleted: {}", t); | ||
61 | } | ||
51 | 62 | ||
52 | let inline_tests_dir = Path::new(INLINE_TESTS_DIR); | 63 | let mut new_idx = existing.len() + 1; |
53 | if !inline_tests_dir.is_dir() { | 64 | for (name, test) in tests { |
54 | fs::create_dir_all(inline_tests_dir)?; | 65 | let path = match existing.get(name) { |
55 | } | 66 | Some((path, _test)) => path.clone(), |
56 | let existing = existing_tests(inline_tests_dir)?; | 67 | None => { |
57 | 68 | let file_name = format!("{:04}_{}.rs", new_idx, name); | |
58 | for t in existing.keys().filter(|&t| !tests.contains_key(t)) { | 69 | new_idx += 1; |
59 | panic!("Test is deleted: {}", t); | 70 | tests_dir.join(file_name) |
71 | } | ||
72 | }; | ||
73 | teraron::update(&path, &test.text, mode)?; | ||
74 | } | ||
75 | Ok(()) | ||
60 | } | 76 | } |
77 | install_tests(&tests.ok, OK_INLINE_TESTS_DIR, mode)?; | ||
78 | install_tests(&tests.err, ERR_INLINE_TESTS_DIR, mode) | ||
79 | } | ||
61 | 80 | ||
62 | let mut new_idx = existing.len() + 2; | 81 | #[derive(Default, Debug)] |
63 | for (name, test) in tests { | 82 | struct Tests { |
64 | let path = match existing.get(&name) { | 83 | pub ok: HashMap<String, Test>, |
65 | Some((path, _test)) => path.clone(), | 84 | pub err: HashMap<String, Test>, |
66 | None => { | ||
67 | let file_name = format!("{:04}_{}.rs", new_idx, name); | ||
68 | new_idx += 1; | ||
69 | inline_tests_dir.join(file_name) | ||
70 | } | ||
71 | }; | ||
72 | teraron::update(&path, &test.text, mode)?; | ||
73 | } | ||
74 | Ok(()) | ||
75 | } | 85 | } |
76 | 86 | ||
77 | fn tests_from_dir(dir: &Path) -> Result<HashMap<String, Test>> { | 87 | fn tests_from_dir(dir: &Path) -> Result<Tests> { |
78 | let mut res = HashMap::new(); | 88 | let mut res = Tests::default(); |
79 | for entry in ::walkdir::WalkDir::new(dir) { | 89 | for entry in ::walkdir::WalkDir::new(dir) { |
80 | let entry = entry.unwrap(); | 90 | let entry = entry.unwrap(); |
81 | if !entry.file_type().is_file() { | 91 | if !entry.file_type().is_file() { |
@@ -89,19 +99,25 @@ fn tests_from_dir(dir: &Path) -> Result<HashMap<String, Test>> { | |||
89 | let grammar_rs = dir.parent().unwrap().join("grammar.rs"); | 99 | let grammar_rs = dir.parent().unwrap().join("grammar.rs"); |
90 | process_file(&mut res, &grammar_rs)?; | 100 | process_file(&mut res, &grammar_rs)?; |
91 | return Ok(res); | 101 | return Ok(res); |
92 | fn process_file(res: &mut HashMap<String, Test>, path: &Path) -> Result<()> { | 102 | fn process_file(res: &mut Tests, path: &Path) -> Result<()> { |
93 | let text = fs::read_to_string(path)?; | 103 | let text = fs::read_to_string(path)?; |
94 | 104 | ||
95 | for (_, test) in collect_tests(&text) { | 105 | for (_, test) in collect_tests(&text) { |
96 | if let Some(old_test) = res.insert(test.name.clone(), test) { | 106 | if test.ok { |
97 | bail!("Duplicate test: {}", old_test.name) | 107 | if let Some(old_test) = res.ok.insert(test.name.clone(), test) { |
108 | bail!("Duplicate test: {}", old_test.name) | ||
109 | } | ||
110 | } else { | ||
111 | if let Some(old_test) = res.err.insert(test.name.clone(), test) { | ||
112 | bail!("Duplicate test: {}", old_test.name) | ||
113 | } | ||
98 | } | 114 | } |
99 | } | 115 | } |
100 | Ok(()) | 116 | Ok(()) |
101 | } | 117 | } |
102 | } | 118 | } |
103 | 119 | ||
104 | fn existing_tests(dir: &Path) -> Result<HashMap<String, (PathBuf, Test)>> { | 120 | fn existing_tests(dir: &Path, ok: bool) -> Result<HashMap<String, (PathBuf, Test)>> { |
105 | let mut res = HashMap::new(); | 121 | let mut res = HashMap::new(); |
106 | for file in fs::read_dir(dir)? { | 122 | for file in fs::read_dir(dir)? { |
107 | let file = file?; | 123 | let file = file?; |
@@ -117,6 +133,7 @@ fn existing_tests(dir: &Path) -> Result<HashMap<String, (PathBuf, Test)>> { | |||
117 | let test = Test { | 133 | let test = Test { |
118 | name: name.clone(), | 134 | name: name.clone(), |
119 | text, | 135 | text, |
136 | ok, | ||
120 | }; | 137 | }; |
121 | if let Some(old) = res.insert(name, (path, test)) { | 138 | if let Some(old) = res.insert(name, (path, test)) { |
122 | println!("Duplicate test: {:?}", old); | 139 | println!("Duplicate test: {:?}", old); |