Skip to content

Commit 284d612

Browse files
authored
Rollup merge of #59408 - euclio:compiletest-normalization, r=oli-obk
compiletest: make path normalization smarter Fixes #59109.
2 parents ac1d44a + 3a18710 commit 284d612

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

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

3175-
normalized = normalized.replace("\\\\", "\\") // denormalize for paths on windows
3176-
.replace("\\", "/") // normalize for paths on windows
3177-
.replace("\r\n", "\n") // normalize for linebreaks on windows
3178-
.replace("\t", "\\t"); // makes tabs visible
3175+
normalized = Self::normalize_platform_differences(&normalized);
3176+
normalized = normalized.replace("\t", "\\t"); // makes tabs visible
31793177

31803178
// Remove test annotations like `//~ ERROR text` from the output,
31813179
// since they duplicate actual errors and make the output hard to read.
@@ -3189,6 +3187,36 @@ impl<'test> TestCx<'test> {
31893187
normalized
31903188
}
31913189

3190+
/// Normalize output differences across platforms. Generally changes Windows output to be more
3191+
/// Unix-like.
3192+
///
3193+
/// Replaces backslashes in paths with forward slashes, and replaces CRLF line endings
3194+
/// with LF.
3195+
fn normalize_platform_differences(output: &str) -> String {
3196+
lazy_static! {
3197+
/// Used to find Windows paths.
3198+
///
3199+
/// It's not possible to detect paths in the error messages generally, but this is a
3200+
/// decent enough heuristic.
3201+
static ref PATH_BACKSLASH_RE: Regex = Regex::new(r#"(?x)
3202+
(?:
3203+
# Match paths that don't include spaces.
3204+
(?:\\[\pL\pN\.\-_']+)+\.\pL+
3205+
|
3206+
# If the path starts with a well-known root, then allow spaces.
3207+
\$(?:DIR|SRC_DIR|TEST_BUILD_DIR|BUILD_DIR|LIB_DIR)(?:\\[\pL\pN\.\-_' ]+)+
3208+
)"#
3209+
).unwrap();
3210+
}
3211+
3212+
let output = output.replace(r"\\", r"\");
3213+
3214+
PATH_BACKSLASH_RE.replace_all(&output, |caps: &Captures<'_>| {
3215+
println!("{}", &caps[0]);
3216+
caps[0].replace(r"\", "/")
3217+
}).replace("\r\n", "\n")
3218+
}
3219+
31923220
fn expected_output_path(&self, kind: &str) -> PathBuf {
31933221
let mut path = expected_output_path(
31943222
&self.testpaths,
@@ -3520,3 +3548,68 @@ fn read2_abbreviated(mut child: Child) -> io::Result<Output> {
35203548
stderr: stderr.into_bytes(),
35213549
})
35223550
}
3551+
3552+
#[cfg(test)]
3553+
mod tests {
3554+
use super::TestCx;
3555+
3556+
#[test]
3557+
fn normalize_platform_differences() {
3558+
assert_eq!(
3559+
TestCx::normalize_platform_differences(r"$DIR\foo.rs"),
3560+
"$DIR/foo.rs"
3561+
);
3562+
assert_eq!(
3563+
TestCx::normalize_platform_differences(r"$BUILD_DIR\..\parser.rs"),
3564+
"$BUILD_DIR/../parser.rs"
3565+
);
3566+
assert_eq!(
3567+
TestCx::normalize_platform_differences(r"$DIR\bar.rs hello\nworld"),
3568+
r"$DIR/bar.rs hello\nworld"
3569+
);
3570+
assert_eq!(
3571+
TestCx::normalize_platform_differences(r"either bar\baz.rs or bar\baz\mod.rs"),
3572+
r"either bar/baz.rs or bar/baz/mod.rs",
3573+
);
3574+
assert_eq!(
3575+
TestCx::normalize_platform_differences(r"`.\some\path.rs`"),
3576+
r"`./some/path.rs`",
3577+
);
3578+
assert_eq!(
3579+
TestCx::normalize_platform_differences(r"`some\path.rs`"),
3580+
r"`some/path.rs`",
3581+
);
3582+
assert_eq!(
3583+
TestCx::normalize_platform_differences(r"$DIR\path-with-dashes.rs"),
3584+
r"$DIR/path-with-dashes.rs"
3585+
);
3586+
assert_eq!(
3587+
TestCx::normalize_platform_differences(r"$DIR\path_with_underscores.rs"),
3588+
r"$DIR/path_with_underscores.rs",
3589+
);
3590+
assert_eq!(
3591+
TestCx::normalize_platform_differences(r"$DIR\foo.rs:12:11"), "$DIR/foo.rs:12:11",
3592+
);
3593+
assert_eq!(
3594+
TestCx::normalize_platform_differences(r"$DIR\path with spaces 'n' quotes"),
3595+
"$DIR/path with spaces 'n' quotes",
3596+
);
3597+
assert_eq!(
3598+
TestCx::normalize_platform_differences(r"$DIR\file_with\no_extension"),
3599+
"$DIR/file_with/no_extension",
3600+
);
3601+
3602+
assert_eq!(TestCx::normalize_platform_differences(r"\n"), r"\n");
3603+
assert_eq!(TestCx::normalize_platform_differences(r"{ \n"), r"{ \n");
3604+
assert_eq!(TestCx::normalize_platform_differences(r"`\]`"), r"`\]`");
3605+
assert_eq!(TestCx::normalize_platform_differences(r#""\{""#), r#""\{""#);
3606+
assert_eq!(
3607+
TestCx::normalize_platform_differences(r#"write!(&mut v, "Hello\n")"#),
3608+
r#"write!(&mut v, "Hello\n")"#
3609+
);
3610+
assert_eq!(
3611+
TestCx::normalize_platform_differences(r#"println!("test\ntest")"#),
3612+
r#"println!("test\ntest")"#,
3613+
);
3614+
}
3615+
}

0 commit comments

Comments
 (0)