From ae7aa710cdaa71ba3bb56f26a4ea07c79e9800d7 Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Thu, 22 Oct 2026 15:54:42 +0200 Subject: [PATCH] cli-test: Normalize Windows Paths Maintaining tests for Windows and Unix separately, just because they use different characters to separate paths is annoying. This simple normalization function that in essence replaces backslashes with forward slashes eats all cases in our tests. --- crates/radicle-cli-test/src/lib.rs | 50 ++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/crates/radicle-cli-test/src/lib.rs b/crates/radicle-cli-test/src/lib.rs index 64df199e7..046d186f8 100644 --- a/crates/radicle-cli-test/src/lib.rs +++ b/crates/radicle-cli-test/src/lib.rs @@ -486,6 +486,13 @@ impl TestFormula { // separately and provide a more helpful error message in that case. match command.output() { Ok(output) => { + #[cfg(windows)] + let output = { + let mut output = output; + normalize_windows_paths(&mut output.stdout); + normalize_windows_paths(&mut output.stderr); + output + }; let assert = OutputAssert::new(output).with_assert(assert.clone()); let expected = Self::map_spaced_brackets(&assertion.expected); @@ -530,6 +537,49 @@ impl TestFormula { } } +/// Normalize drive-qualified Windows paths, compressing sequences of backslashes +/// to a forward slash. +#[cfg(windows)] +fn normalize_windows_paths(bytes: &mut Vec) { + let mut path = false; + let mut i = 0; + let mut len = 0; + while i < bytes.len() { + // Detect drive-qualified paths, e.g., `C:\` or `D:\`. + if bytes[i].is_ascii_alphabetic() + && bytes.get(i + 1) == Some(&b':') + && bytes.get(i + 2) == Some(&b'\\') + { + path = true; + } + + match bytes[i] { + b'\n' | b'\r' | b'"' | b'\'' => path = false, + b'\\' if path => { + i += match bytes.get(i + 1) { + Some(b'\\') => { + // Repeated backslash, common in escaped Rust debug + // output, e.g., `"C:\\Users\\example"`. + 2 + } + _ => 1, + }; + bytes[len] = b'/'; + len += 1; + + continue; + } + _ => {} + } + + bytes[len] = bytes[i]; + len += 1; + i += 1; + } + + bytes.truncate(len); +} + fn cargo_manifest_dir() -> PathBuf { env::var("CARGO_MANIFEST_DIR").map(PathBuf::from).unwrap() }