use crate::soft_canonicalize;
use std::sync::Mutex;
use tempfile::TempDir;
static WORKING_DIR_MUTEX: Mutex<()> = Mutex::new(());
#[test]
fn test_symlink_depth_limit() {
#[cfg(target_os = "windows")]
assert_eq!(crate::MAX_SYMLINK_DEPTH, 63);
#[cfg(not(target_os = "windows"))]
assert_eq!(crate::MAX_SYMLINK_DEPTH, 40);
}
#[test]
fn test_symlink_depth_documentation() {
let _tmpdir = TempDir::new().expect("Failed to create temp dir");
#[cfg(unix)]
{
use std::os::unix::fs::symlink;
let link1 = _tmpdir.path().join("link1");
let link2 = _tmpdir.path().join("link2");
if symlink(&link2, &link1).is_ok() && symlink(&link1, &link2).is_ok() {
let result = soft_canonicalize(&link1);
assert!(result.is_err());
let error = result.unwrap_err();
assert_eq!(error.kind(), std::io::ErrorKind::InvalidInput);
assert!(error
.to_string()
.contains("Too many levels of symbolic links"));
}
}
#[cfg(windows)]
{
let _depth = crate::MAX_SYMLINK_DEPTH;
let result = soft_canonicalize("");
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), std::io::ErrorKind::NotFound);
}
}
#[test]
fn test_python_style_edge_cases() {
let _lock = WORKING_DIR_MUTEX.lock().unwrap();
use std::env;
use tempfile::TempDir;
let result = soft_canonicalize("");
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), std::io::ErrorKind::NotFound);
let temp_dir = TempDir::new().unwrap();
let original_cwd = env::current_dir().unwrap();
let test_result = std::panic::catch_unwind(|| {
if temp_dir.path().exists() {
if let Ok(()) = env::set_current_dir(temp_dir.path()) {
let result = soft_canonicalize(".");
assert!(result.is_ok());
let resolved = result.unwrap();
assert!(resolved.is_absolute());
let result = soft_canonicalize("..");
assert!(result.is_ok());
let resolved = result.unwrap();
assert!(resolved.is_absolute());
let result = soft_canonicalize("./././../.");
assert!(result.is_ok());
let resolved = result.unwrap();
assert!(resolved.is_absolute());
}
}
});
let _ = env::set_current_dir(original_cwd);
if let Err(e) = test_result {
std::panic::resume_unwind(e);
}
let tmpdir = TempDir::new().expect("Failed to create temp dir");
let test_path = tmpdir.path().join("non").join("existing").join("path.txt");
let result = soft_canonicalize(test_path);
assert!(result.is_ok());
let resolved = result.unwrap();
let canonical_tmp = std::fs::canonicalize(tmpdir.path()).unwrap();
#[cfg(windows)]
{
let resolved_str = resolved.to_string_lossy();
let canonical_tmp_str = canonical_tmp.to_string_lossy();
let resolved_normalized =
std::path::PathBuf::from(resolved_str.strip_prefix(r"\\?\").unwrap_or(&resolved_str));
let canonical_tmp_normalized = std::path::PathBuf::from(
canonical_tmp_str
.strip_prefix(r"\\?\")
.unwrap_or(&canonical_tmp_str),
);
assert!(resolved_normalized.starts_with(canonical_tmp_normalized));
}
#[cfg(not(windows))]
{
assert!(resolved.starts_with(canonical_tmp));
}
assert!(resolved.to_string_lossy().contains("non"));
assert!(resolved.to_string_lossy().contains("existing"));
assert!(resolved.to_string_lossy().contains("path.txt"));
}