Files
noentropy/tests/test_path_utils.rs
glitchySid f68d960cfe Add tests for handlers and fix path display bug
- Fix compilation error in path_utils.rs where path.display() was
  used after the path was moved into spawn_blocking closure
- Add 12 tests for handle_undo handler covering no undo log,
  no completed moves, custom paths, dry run, invalid paths, etc.
- Add 16 tests for validate_and_normalize_path covering path
  validation, directories, normalization, edge cases
- Add 21 tests for cache module covering key generation,
  hit/miss behavior, eviction, persistence, etc.

All 86 tests pass successfully.
2026-01-11 22:31:43 +05:30

278 lines
8.3 KiB
Rust

//! Unit tests for path_utils module
//!
//! Tests the validate_and_normalize_path function including:
//! - Non-existent paths
//! - File paths (not directories)
//! - Directory validation
//! - Successful canonicalization
//! - Permission/access errors
use noentropy::cli::path_utils::validate_and_normalize_path;
use std::fs::{self, File};
use std::path::Path;
use tempfile::TempDir;
// ============================================================================
// NON-EXISTENT PATH TESTS
// ============================================================================
#[tokio::test]
async fn test_validate_nonexistent_path() {
let temp_dir = TempDir::new().unwrap();
let nonexistent = temp_dir.path().join("this_does_not_exist");
let result = validate_and_normalize_path(&nonexistent).await;
assert!(result.is_err());
let err = result.unwrap_err();
assert!(err.contains("does not exist"));
}
#[tokio::test]
async fn test_validate_deeply_nested_nonexistent() {
let temp_dir = TempDir::new().unwrap();
let nonexistent = temp_dir
.path()
.join("a")
.join("b")
.join("c")
.join("d")
.join("nonexistent");
let result = validate_and_normalize_path(&nonexistent).await;
assert!(result.is_err());
assert!(result.unwrap_err().contains("does not exist"));
}
// ============================================================================
// FILE PATH TESTS (NOT DIRECTORY)
// ============================================================================
#[tokio::test]
async fn test_validate_file_path_is_not_directory() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test_file.txt");
File::create(&file_path).unwrap();
let result = validate_and_normalize_path(&file_path).await;
assert!(result.is_err());
let err = result.unwrap_err();
assert!(err.contains("not a directory"));
}
#[tokio::test]
async fn test_validate_file_path_with_nested_structure() {
let temp_dir = TempDir::new().unwrap();
let nested_dir = temp_dir.path().join("dir1").join("dir2");
fs::create_dir_all(&nested_dir).unwrap();
let file_in_nested = nested_dir.join("file.txt");
File::create(&file_in_nested).unwrap();
let result = validate_and_normalize_path(&file_in_nested).await;
assert!(result.is_err());
assert!(result.unwrap_err().contains("not a directory"));
}
// ============================================================================
// DIRECTORY VALIDATION TESTS
// ============================================================================
#[tokio::test]
async fn test_validate_empty_directory() {
let temp_dir = TempDir::new().unwrap();
let empty_dir = temp_dir.path();
let result = validate_and_normalize_path(empty_dir).await;
assert!(result.is_ok());
let normalized = result.unwrap();
// Should be canonicalized to an absolute path
assert!(normalized.is_absolute());
}
#[tokio::test]
async fn test_validate_directory_with_files() {
let temp_dir = TempDir::new().unwrap();
let dir_path = temp_dir.path();
// Create some files
File::create(dir_path.join("file1.txt")).unwrap();
File::create(dir_path.join("file2.txt")).unwrap();
let result = validate_and_normalize_path(dir_path).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_validate_directory_with_subdirectories() {
let temp_dir = TempDir::new().unwrap();
let dir_path = temp_dir.path();
// Create nested directory structure
fs::create_dir_all(dir_path.join("subdir1").join("subdir2")).unwrap();
File::create(dir_path.join("file.txt")).unwrap();
let result = validate_and_normalize_path(dir_path).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_validate_directory_with_hidden_files() {
let temp_dir = TempDir::new().unwrap();
let dir_path = temp_dir.path();
// Create hidden files
File::create(dir_path.join(".gitignore")).unwrap();
File::create(dir_path.join(".config")).unwrap();
let result = validate_and_normalize_path(dir_path).await;
assert!(result.is_ok());
}
// ============================================================================
// PATH NORMALIZATION TESTS
// ============================================================================
#[tokio::test]
async fn test_validate_normalizes_relative_path() {
let temp_dir = TempDir::new().unwrap();
let dir_path = temp_dir.path();
// Get canonical path first
let canonical = dir_path.canonicalize().unwrap();
let result = validate_and_normalize_path(dir_path).await;
assert!(result.is_ok());
let normalized = result.unwrap();
// The normalized path should be equivalent to canonicalized path
assert_eq!(normalized, canonical);
}
#[tokio::test]
async fn test_validate_resolves_dot_path() {
let temp_dir = TempDir::new().unwrap();
let original_cwd = std::env::current_dir().unwrap();
// Change to temp directory
std::env::set_current_dir(temp_dir.path()).unwrap();
// Test with "./" path
let dot_path = Path::new(".");
let result = validate_and_normalize_path(dot_path).await;
// Restore original directory
std::env::set_current_dir(&original_cwd).unwrap();
assert!(result.is_ok());
}
#[tokio::test]
async fn test_validate_directory_symlink_if_available() {
let temp_dir = TempDir::new().unwrap();
let dir_path = temp_dir.path();
// Create a real directory
let real_dir = dir_path.join("real_dir");
fs::create_dir_all(&real_dir).unwrap();
// Create a symlink to it (may not work on all platforms)
#[cfg(unix)]
{
let symlink_path = dir_path.join("symlink_dir");
if let Ok(()) = std::os::unix::fs::symlink(&real_dir, &symlink_path) {
let result = validate_and_normalize_path(&symlink_path).await;
// Should resolve to the canonical path of the real directory
assert!(result.is_ok());
}
}
}
// ============================================================================
// EDGE CASE TESTS
// ============================================================================
#[tokio::test]
async fn test_validate_root_directory() {
// Test with root directory (may not be readable on all systems)
let root_path = Path::new("/");
let result = validate_and_normalize_path(root_path).await;
// On most systems, root should be accessible
// If it fails, it's likely due to permissions, not path validation
match result {
Ok(_) => {
// Root is accessible and canonicalizable
}
Err(e) => {
// Should be an access error, not "does not exist" or "not a directory"
assert!(!e.contains("does not exist"));
assert!(!e.contains("not a directory"));
}
}
}
#[tokio::test]
async fn test_validate_current_directory() {
let current_dir = Path::new(".");
let result = validate_and_normalize_path(current_dir).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_validate_parent_directory() {
let parent_dir = Path::new("..");
let result = validate_and_normalize_path(parent_dir).await;
// Parent directory should be valid (assuming we have read access)
match result {
Ok(normalized) => {
// Should be an absolute path
assert!(normalized.is_absolute());
}
Err(e) => {
// If it fails, it should be an access error
assert!(e.contains("Cannot access") || e.contains("access"));
}
}
}
#[tokio::test]
async fn test_validate_directory_with_special_characters() {
let temp_dir = TempDir::new().unwrap();
let dir_path = temp_dir.path();
// Create directory with special characters in name
let special_dir = dir_path.join("dir-with-dashes_and_underscores");
fs::create_dir_all(&special_dir).unwrap();
let result = validate_and_normalize_path(&special_dir).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_validate_unicode_directory_name() {
let temp_dir = TempDir::new().unwrap();
let dir_path = temp_dir.path();
// Create directory with unicode characters
let unicode_dir = dir_path.join("测试目录");
fs::create_dir_all(&unicode_dir).unwrap();
let result = validate_and_normalize_path(&unicode_dir).await;
assert!(result.is_ok());
}