Generates a textual diff of `golden` and `generated`. The output is meant to be useful for human consumption when a test fails and is not guaranteed to be in patch format. Returns the empty string when the two files match.
(golden: &Path, generated: &Path)
| 351 | /// |
| 352 | /// Returns the empty string when the two files match. |
| 353 | fn diff(golden: &Path, generated: &Path) -> io::Result<String> { |
| 354 | match process::Command::new("diff") |
| 355 | .args([OsStr::new("-u"), golden.as_os_str(), generated.as_os_str()]) |
| 356 | .output() |
| 357 | { |
| 358 | Ok(result) => { |
| 359 | let Some(code) = result.status.code() else { |
| 360 | return Err(io::Error::other("diff crashed")); |
| 361 | }; |
| 362 | let Ok(stdout) = String::from_utf8(result.stdout) else { |
| 363 | return Err(io::Error::other("diff printed non-UTF8 content to stdout")); |
| 364 | }; |
| 365 | let Ok(stderr) = String::from_utf8(result.stderr) else { |
| 366 | return Err(io::Error::other("diff printed non-UTF8 content to stderr")); |
| 367 | }; |
| 368 | |
| 369 | let mut diff = stdout; |
| 370 | diff.push_str(&stderr); |
| 371 | if code == 0 && !diff.is_empty() { |
| 372 | return Err(io::Error::other("diff succeeded but output is not empty")); |
| 373 | } else if code != 0 && diff.is_empty() { |
| 374 | return Err(io::Error::other("diff succeeded but output is empty")); |
| 375 | } |
| 376 | |
| 377 | Ok(diff) |
| 378 | } |
| 379 | |
| 380 | Err(e) if e.kind() == io::ErrorKind::NotFound => { |
| 381 | let left = fs::read_to_string(golden)?; |
| 382 | let right = fs::read_to_string(generated)?; |
| 383 | |
| 384 | let mut diff = String::new(); |
| 385 | if left != right { |
| 386 | diff.push_str("Golden\n"); |
| 387 | diff.push_str("======\n"); |
| 388 | diff.push_str(&left); |
| 389 | diff.push_str("\n\nActual\n"); |
| 390 | diff.push_str("======\n"); |
| 391 | diff.push_str(&right); |
| 392 | } |
| 393 | Ok(diff) |
| 394 | } |
| 395 | |
| 396 | Err(e) => Err(e), |
| 397 | } |
| 398 | } |
| 399 | |
| 400 | #[test] |
| 401 | fn test_diff_same() -> io::Result<()> { |
no test coverage detected