aboutsummaryrefslogtreecommitdiff
path: root/crates/tools/src
diff options
context:
space:
mode:
authorDJMcNab <[email protected]>2018-12-20 15:09:22 +0000
committerDJMcNab <[email protected]>2018-12-20 15:09:22 +0000
commit63ca8bc91a2e34009a7e274a3105223040db6a37 (patch)
tree1b384353a887c7094977128ccd52b8577169b317 /crates/tools/src
parente2a7e9451881d3b9d1eba7336c657d56558f812e (diff)
Change parser tests dir to inline/ok and inline/err
Diffstat (limited to 'crates/tools/src')
-rw-r--r--crates/tools/src/lib.rs8
-rw-r--r--crates/tools/src/main.rs77
2 files changed, 54 insertions, 31 deletions
diff --git a/crates/tools/src/lib.rs b/crates/tools/src/lib.rs
index 95d6e08f0..66fca5bef 100644
--- a/crates/tools/src/lib.rs
+++ b/crates/tools/src/lib.rs
@@ -21,6 +21,7 @@ const TOOLCHAIN: &str = "1.31.0";
21pub struct Test { 21pub struct Test {
22 pub name: String, 22 pub name: String,
23 pub text: String, 23 pub text: String,
24 pub ok: bool,
24} 25}
25 26
26pub fn collect_tests(s: &str) -> Vec<(usize, Test)> { 27pub fn collect_tests(s: &str) -> Vec<(usize, Test)> {
@@ -38,11 +39,16 @@ pub fn collect_tests(s: &str) -> Vec<(usize, Test)> {
38 } 39 }
39 let mut block = block.map(|(idx, line)| (idx, &line[prefix.len()..])); 40 let mut block = block.map(|(idx, line)| (idx, &line[prefix.len()..]));
40 41
42 let mut ok = true;
41 let (start_line, name) = loop { 43 let (start_line, name) = loop {
42 match block.next() { 44 match block.next() {
43 Some((idx, line)) if line.starts_with("test ") => { 45 Some((idx, line)) if line.starts_with("test ") => {
44 break (idx, line["test ".len()..].to_string()); 46 break (idx, line["test ".len()..].to_string());
45 } 47 }
48 Some((idx, line)) if line.starts_with("test_fail ") => {
49 ok = false;
50 break (idx, line["test_fail ".len()..].to_string());
51 }
46 Some(_) => (), 52 Some(_) => (),
47 None => continue 'outer, 53 None => continue 'outer,
48 } 54 }
@@ -52,7 +58,7 @@ pub fn collect_tests(s: &str) -> Vec<(usize, Test)> {
52 "\n", 58 "\n",
53 ); 59 );
54 assert!(!text.trim().is_empty() && text.ends_with('\n')); 60 assert!(!text.trim().is_empty() && text.ends_with('\n'));
55 res.push((start_line, Test { name, text })) 61 res.push((start_line, Test { name, text, ok }))
56 } 62 }
57 res 63 res
58} 64}
diff --git a/crates/tools/src/main.rs b/crates/tools/src/main.rs
index 8e5e2036d..08b21f7af 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 is 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() + 2;
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);