Skip to content

Commit 3a18710

Browse files
committed
compiletest: make path normalization smarter
1 parent 5f5592c commit 3a18710

File tree

1 file changed

+98
-5
lines changed

1 file changed

+98
-5
lines changed

src/runtest.rs

Lines changed: 98 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::errors::{self, Error, ErrorKind};
1010
use filetime::FileTime;
1111
use crate::header::TestProps;
1212
use crate::json;
13-
use regex::Regex;
13+
use regex::{Captures, Regex};
1414
use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
1515
use crate::util::{logv, PathBufExt};
1616

@@ -3147,10 +3147,8 @@ impl<'test> TestCx<'test> {
31473147
normalized = Regex::new("SRC_DIR(.+):\\d+:\\d+").unwrap()
31483148
.replace_all(&normalized, "SRC_DIR$1:LL:COL").into_owned();
31493149

3150-
normalized = normalized.replace("\\\\", "\\") // denormalize for paths on windows
3151-
.replace("\\", "/") // normalize for paths on windows
3152-
.replace("\r\n", "\n") // normalize for linebreaks on windows
3153-
.replace("\t", "\\t"); // makes tabs visible
3150+
normalized = Self::normalize_platform_differences(&normalized);
3151+
normalized = normalized.replace("\t", "\\t"); // makes tabs visible
31543152

31553153
// Remove test annotations like `//~ ERROR text` from the output,
31563154
// since they duplicate actual errors and make the output hard to read.
@@ -3164,6 +3162,36 @@ impl<'test> TestCx<'test> {
31643162
normalized
31653163
}
31663164

3165+
/// Normalize output differences across platforms. Generally changes Windows output to be more
3166+
/// Unix-like.
3167+
///
3168+
/// Replaces backslashes in paths with forward slashes, and replaces CRLF line endings
3169+
/// with LF.
3170+
fn normalize_platform_differences(output: &str) -> String {
3171+
lazy_static! {
3172+
/// Used to find Windows paths.
3173+
///
3174+
/// It's not possible to detect paths in the error messages generally, but this is a
3175+
/// decent enough heuristic.
3176+
static ref PATH_BACKSLASH_RE: Regex = Regex::new(r#"(?x)
3177+
(?:
3178+
# Match paths that don't include spaces.
3179+
(?:\\[\pL\pN\.\-_']+)+\.\pL+
3180+
|
3181+
# If the path starts with a well-known root, then allow spaces.
3182+
\$(?:DIR|SRC_DIR|TEST_BUILD_DIR|BUILD_DIR|LIB_DIR)(?:\\[\pL\pN\.\-_' ]+)+
3183+
)"#
3184+
).unwrap();
3185+
}
3186+
3187+
let output = output.replace(r"\\", r"\");
3188+
3189+
PATH_BACKSLASH_RE.replace_all(&output, |caps: &Captures<'_>| {
3190+
println!("{}", &caps[0]);
3191+
caps[0].replace(r"\", "/")
3192+
}).replace("\r\n", "\n")
3193+
}
3194+
31673195
fn expected_output_path(&self, kind: &str) -> PathBuf {
31683196
let mut path = expected_output_path(
31693197
&self.testpaths,
@@ -3495,3 +3523,68 @@ fn read2_abbreviated(mut child: Child) -> io::Result<Output> {
34953523
stderr: stderr.into_bytes(),
34963524
})
34973525
}
3526+
3527+
#[cfg(test)]
3528+
mod tests {
3529+
use super::TestCx;
3530+
3531+
#[test]
3532+
fn normalize_platform_differences() {
3533+
assert_eq!(
3534+
TestCx::normalize_platform_differences(r"$DIR\foo.rs"),
3535+
"$DIR/foo.rs"
3536+
);
3537+
assert_eq!(
3538+
TestCx::normalize_platform_differences(r"$BUILD_DIR\..\parser.rs"),
3539+
"$BUILD_DIR/../parser.rs"
3540+
);
3541+
assert_eq!(
3542+
TestCx::normalize_platform_differences(r"$DIR\bar.rs hello\nworld"),
3543+
r"$DIR/bar.rs hello\nworld"
3544+
);
3545+
assert_eq!(
3546+
TestCx::normalize_platform_differences(r"either bar\baz.rs or bar\baz\mod.rs"),
3547+
r"either bar/baz.rs or bar/baz/mod.rs",
3548+
);
3549+
assert_eq!(
3550+
TestCx::normalize_platform_differences(r"`.\some\path.rs`"),
3551+
r"`./some/path.rs`",
3552+
);
3553+
assert_eq!(
3554+
TestCx::normalize_platform_differences(r"`some\path.rs`"),
3555+
r"`some/path.rs`",
3556+
);
3557+
assert_eq!(
3558+
TestCx::normalize_platform_differences(r"$DIR\path-with-dashes.rs"),
3559+
r"$DIR/path-with-dashes.rs"
3560+
);
3561+
assert_eq!(
3562+
TestCx::normalize_platform_differences(r"$DIR\path_with_underscores.rs"),
3563+
r"$DIR/path_with_underscores.rs",
3564+
);
3565+
assert_eq!(
3566+
TestCx::normalize_platform_differences(r"$DIR\foo.rs:12:11"), "$DIR/foo.rs:12:11",
3567+
);
3568+
assert_eq!(
3569+
TestCx::normalize_platform_differences(r"$DIR\path with spaces 'n' quotes"),
3570+
"$DIR/path with spaces 'n' quotes",
3571+
);
3572+
assert_eq!(
3573+
TestCx::normalize_platform_differences(r"$DIR\file_with\no_extension"),
3574+
"$DIR/file_with/no_extension",
3575+
);
3576+
3577+
assert_eq!(TestCx::normalize_platform_differences(r"\n"), r"\n");
3578+
assert_eq!(TestCx::normalize_platform_differences(r"{ \n"), r"{ \n");
3579+
assert_eq!(TestCx::normalize_platform_differences(r"`\]`"), r"`\]`");
3580+
assert_eq!(TestCx::normalize_platform_differences(r#""\{""#), r#""\{""#);
3581+
assert_eq!(
3582+
TestCx::normalize_platform_differences(r#"write!(&mut v, "Hello\n")"#),
3583+
r#"write!(&mut v, "Hello\n")"#
3584+
);
3585+
assert_eq!(
3586+
TestCx::normalize_platform_differences(r#"println!("test\ntest")"#),
3587+
r#"println!("test\ntest")"#,
3588+
);
3589+
}
3590+
}

0 commit comments

Comments
 (0)