aboutsummaryrefslogtreecommitdiff
path: root/crates/tools/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/tools/src/main.rs')
-rw-r--r--crates/tools/src/main.rs77
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::{
7use clap::{App, Arg, SubCommand}; 7use clap::{App, Arg, SubCommand};
8use failure::bail; 8use failure::bail;
9 9
10use tools::{collect_tests, generate, install_format_hook, run, run_rustfmt, Mode, Overwrite, Result, Test, Verify}; 10use tools::{collect_tests, generate, install_format_hook, run, run_rustfmt, Mode, Overwrite, Result, Test, Verify, project_root};
11 11
12const GRAMMAR_DIR: &str = "./crates/ra_syntax/src/grammar"; 12const GRAMMAR_DIR: &str = "crates/ra_syntax/src/grammar";
13const INLINE_TESTS_DIR: &str = "./crates/ra_syntax/tests/data/parser/inline"; 13const OK_INLINE_TESTS_DIR: &str = "crates/ra_syntax/tests/data/parser/inline/ok";
14const ERR_INLINE_TESTS_DIR: &str = "crates/ra_syntax/tests/data/parser/inline/err";
14 15
15fn main() -> Result<()> { 16fn main() -> Result<()> {
16 let matches = App::new("tasks") 17 let matches = App::new("tasks")
@@ -48,34 +49,43 @@ fn main() -> Result<()> {
48 49
49fn gen_tests(mode: Mode) -> Result<()> { 50fn 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 { 82struct 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
77fn tests_from_dir(dir: &Path) -> Result<HashMap<String, Test>> { 87fn 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
104fn existing_tests(dir: &Path) -> Result<HashMap<String, (PathBuf, Test)>> { 120fn 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);