#[cfg(test)]
mod test_std_behavior {
use crate::soft_canonicalize;
use std::fs;
use std::io;
#[test]
fn test_std_canonicalize_empty_path() {
match fs::canonicalize("") {
Ok(_) => println!("Empty path: OK (unexpected)"),
Err(e) => {
println!("Empty path error kind: {:?}", e.kind());
println!("Empty path error message: '{e}'");
assert_eq!(e.kind(), io::ErrorKind::NotFound);
}
}
}
#[test]
fn test_our_empty_path_matches_std() {
let std_result = fs::canonicalize("");
let our_result = soft_canonicalize("");
assert!(std_result.is_err());
assert!(our_result.is_err());
let std_err = std_result.unwrap_err();
let our_err = our_result.unwrap_err();
assert_eq!(std_err.kind(), our_err.kind());
assert_eq!(our_err.kind(), io::ErrorKind::NotFound);
println!("std error: '{std_err}'");
println!("our error: '{our_err}'");
}
#[test]
fn test_error_message_format() {
let error_msg = "Too many levels of symbolic links";
println!("Expected symlink error: '{error_msg}'");
let test_error = io::Error::new(io::ErrorKind::InvalidInput, error_msg);
assert_eq!(test_error.to_string(), error_msg);
}
#[test]
fn test_std_canonicalize_limitations() {
use std::env;
let temp_dir = env::temp_dir();
println!("temp_dir: {temp_dir:?}");
let std_result = fs::canonicalize(&temp_dir);
println!("std::fs::canonicalize on existing path: {std_result:?}");
assert!(std_result.is_ok(), "std should handle existing paths");
let non_existing = temp_dir.join("this/path/does/not/exist.txt");
let std_result_nonexisting = fs::canonicalize(&non_existing);
println!("std::fs::canonicalize on non-existing path: {std_result_nonexisting:?}");
assert!(
std_result_nonexisting.is_err(),
"std should fail on non-existing paths"
);
if let Err(e) = std_result_nonexisting {
assert_eq!(e.kind(), io::ErrorKind::NotFound);
println!("std fails with NotFound: {e}");
}
let our_result = soft_canonicalize(&non_existing);
println!("soft_canonicalize on non-existing path: {our_result:?}");
assert!(
our_result.is_ok(),
"soft_canonicalize should handle non-existing paths"
);
let our_existing = soft_canonicalize(&temp_dir).expect("soft_canonicalize existing path");
let std_result_path = std_result.unwrap();
#[cfg(not(feature = "dunce"))]
{
assert_eq!(
our_existing, std_result_path,
"Without dunce: both should return exact same path"
);
}
#[cfg(feature = "dunce")]
{
#[cfg(windows)]
{
let our_str = our_existing.to_string_lossy();
let std_str = std_result_path.to_string_lossy();
assert!(!our_str.starts_with(r"\\?\"), "dunce should simplify");
assert!(std_str.starts_with(r"\\?\"), "std returns UNC");
}
#[cfg(not(windows))]
{
assert_eq!(our_existing, std_result_path);
}
}
println!("\n=== CONCLUSION ===");
println!("std::fs::canonicalize REQUIRES ALL path components to exist");
println!("soft_canonicalize works with non-existing paths - that's our value add!");
}
}