(header: &str)
| 160 | } |
| 161 | |
| 162 | fn parse_header(header: &str) -> Result<TestMeta, String> { |
| 163 | let mut description = String::new(); |
| 164 | let mut feature = None; |
| 165 | let mut expect = Vec::new(); |
| 166 | let mut expect_absent = Vec::new(); |
| 167 | let mut expect_hover = Vec::new(); |
| 168 | let mut expect_definition = Vec::new(); |
| 169 | let mut expect_sig_label = None; |
| 170 | let mut expect_sig_active = None; |
| 171 | let mut expect_sig_params = Vec::new(); |
| 172 | let mut ignore = None; |
| 173 | |
| 174 | for line in header.lines() { |
| 175 | let line = line.trim(); |
| 176 | if let Some(val) = line.strip_prefix("// test:") { |
| 177 | description = val.trim().to_string(); |
| 178 | } else if let Some(val) = line.strip_prefix("// feature:") { |
| 179 | feature = Some(match val.trim() { |
| 180 | "completion" => Feature::Completion, |
| 181 | "hover" => Feature::Hover, |
| 182 | "definition" => Feature::Definition, |
| 183 | "signature_help" => Feature::SignatureHelp, |
| 184 | other => return Err(format!("Unknown feature: {other}")), |
| 185 | }); |
| 186 | } else if let Some(val) = line.strip_prefix("// expect:") { |
| 187 | expect.push(val.trim().to_string()); |
| 188 | } else if let Some(val) = line.strip_prefix("// expect_absent:") { |
| 189 | expect_absent.push(val.trim().to_string()); |
| 190 | } else if let Some(val) = line.strip_prefix("// expect_hover:") { |
| 191 | // Format: `symbol => substring` |
| 192 | if let Some((sym, sub)) = val.split_once("=>") { |
| 193 | expect_hover.push((sym.trim().to_string(), sub.trim().to_string())); |
| 194 | } else { |
| 195 | return Err(format!("Invalid expect_hover format: {val}")); |
| 196 | } |
| 197 | } else if let Some(val) = line.strip_prefix("// expect_definition:") { |
| 198 | expect_definition.push(val.trim().to_string()); |
| 199 | } else if let Some(val) = line.strip_prefix("// expect_sig_label:") { |
| 200 | expect_sig_label = Some(val.trim().to_string()); |
| 201 | } else if let Some(val) = line.strip_prefix("// expect_sig_active:") { |
| 202 | expect_sig_active = Some( |
| 203 | val.trim() |
| 204 | .parse::<u32>() |
| 205 | .map_err(|e| format!("Invalid expect_sig_active: {e}"))?, |
| 206 | ); |
| 207 | } else if let Some(val) = line.strip_prefix("// expect_sig_param:") { |
| 208 | expect_sig_params.push(val.trim().to_string()); |
| 209 | } else if let Some(val) = line.strip_prefix("// ignore:") { |
| 210 | ignore = Some(val.trim().to_string()); |
| 211 | } |
| 212 | // Lines that don't match any prefix are silently ignored (comments). |
| 213 | } |
| 214 | |
| 215 | let feature = feature.ok_or("Fixture missing `// feature:` header")?; |
| 216 | if description.is_empty() { |
| 217 | return Err("Fixture missing `// test:` header".to_string()); |
| 218 | } |
| 219 |
no test coverage detected