Reads the source sections of a golden test description file.
(path: &Path)
| 58 | |
| 59 | /// Reads the source sections of a golden test description file. |
| 60 | fn read_sources(path: &Path) -> io::Result<Tests> { |
| 61 | let file = File::open(path).expect("Failed to open golden data file"); |
| 62 | let reader = BufReader::new(file); |
| 63 | |
| 64 | fn add_test(tests: &mut Tests, name: String, sources: Vec<String>) -> io::Result<()> { |
| 65 | if sources.is_empty() { |
| 66 | Err(io::Error::new( |
| 67 | io::ErrorKind::InvalidData, |
| 68 | format!("Test case '{}' has no Source section", name), |
| 69 | )) |
| 70 | } else { |
| 71 | tests.push(Test { name, sources }); |
| 72 | Ok(()) |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | fn finish_source(sources: &mut Vec<String>, source: &mut Option<String>) { |
| 77 | if let Some(source) = source.take() { |
| 78 | sources.push(source.trim_end().to_owned()); |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | #[derive(Clone, Copy, Eq, PartialEq)] |
| 83 | enum Section { |
| 84 | Other, |
| 85 | Source, |
| 86 | } |
| 87 | |
| 88 | let mut tests = vec![]; |
| 89 | let mut current_test = None; |
| 90 | let mut current_section = Section::Other; |
| 91 | let mut sources = vec![]; |
| 92 | let mut source: Option<String> = None; |
| 93 | for line in reader.lines() { |
| 94 | let line = line?; |
| 95 | |
| 96 | // Deal with CRLF. I'd do this on Windows only, but keeping it unconditional helps |
| 97 | // with cross-platform testing (per the unit tests below). |
| 98 | let line = line.trim_end_matches('\r'); |
| 99 | |
| 100 | if let Some(stripped) = line.strip_prefix("# Test: ") { |
| 101 | finish_source(&mut sources, &mut source); |
| 102 | if let Some(name) = current_test.take() { |
| 103 | add_test(&mut tests, name, std::mem::take(&mut sources))?; |
| 104 | } |
| 105 | current_test = Some(stripped.to_owned()); |
| 106 | current_section = Section::Other; |
| 107 | continue; |
| 108 | } else if line.starts_with("# ") { |
| 109 | return Err(io::Error::new( |
| 110 | io::ErrorKind::InvalidData, |
| 111 | format!("Unexpected section header {}", line), |
| 112 | )); |
| 113 | } else if is_source_header(line) { |
| 114 | current_section = Section::Source; |
| 115 | continue; |
| 116 | } else if line.starts_with("## ") { |
| 117 | finish_source(&mut sources, &mut source); |
no test coverage detected