(tests: &HashMap<String, Test>, target_dir: &str)
| 99 | } |
| 100 | |
| 101 | fn install_tests(tests: &HashMap<String, Test>, target_dir: &str) -> Result<TestFiles> { |
| 102 | let root_dir = project_root(); |
| 103 | let tests_dir = root_dir.join(target_dir); |
| 104 | if !tests_dir.is_dir() { |
| 105 | fs::create_dir_all(&tests_dir)?; |
| 106 | } |
| 107 | |
| 108 | // Test kind is irrelevant for existing test cases. |
| 109 | let existing = existing_tests(&tests_dir)?; |
| 110 | |
| 111 | let mut updated_files = vec![]; |
| 112 | // Sort so `TestFiles` reports generated files that need updating deterministically. |
| 113 | let mut sorted_tests = tests.iter().collect::<Vec<_>>(); |
| 114 | sorted_tests.sort_unstable_by_key(|(name, _)| *name); |
| 115 | |
| 116 | for (name, test) in sorted_tests { |
| 117 | let path = match existing.get(name) { |
| 118 | Some(path) => path.clone(), |
| 119 | None => tests_dir.join(name).with_extension("py"), |
| 120 | }; |
| 121 | match fs::read_to_string(&path) { |
| 122 | Ok(old_contents) if old_contents == test.contents => continue, |
| 123 | _ => {} |
| 124 | } |
| 125 | fs::write(&path, &test.contents) |
| 126 | .with_context(|| format!("Failed to write to {:?}", path.display()))?; |
| 127 | updated_files.push(path); |
| 128 | } |
| 129 | |
| 130 | let mut unreferenced = existing |
| 131 | .into_iter() |
| 132 | .filter(|(name, _)| !tests.contains_key(name)) |
| 133 | .map(|(_, path)| path) |
| 134 | .collect::<Vec<_>>(); |
| 135 | unreferenced.sort_unstable(); |
| 136 | |
| 137 | Ok(TestFiles { |
| 138 | unreferenced, |
| 139 | updated: updated_files, |
| 140 | }) |
| 141 | } |
| 142 | |
| 143 | #[derive(Default, Debug)] |
| 144 | struct TestCollection { |
no test coverage detected