use anyhow::Result;
use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};
use tempfile::TempDir;
use crate::tree::{TreeOptions, generate_tree};
fn create_test_directory_structure(dir: &Path) -> Result<()> {
let test_files = [
"file1.txt",
"file2.rs",
"src/main.rs",
"src/lib.rs",
"src/utils/helper.rs",
"docs/readme.md",
"docs/examples/example1.md",
"docs/examples/example2.md",
"tests/test_main.rs",
];
for file_path in &test_files {
let full_path = dir.join(file_path);
if let Some(parent) = full_path.parent() {
std::fs::create_dir_all(parent)?;
}
let mut file = File::create(full_path)?;
file.write_all(format!("Test content for {}", file_path).as_bytes())?;
}
Ok(())
}
fn normalize_path(path: &str) -> String {
path.replace("\\", "/")
}
#[test]
fn test_omit_path_prefix_basic() -> Result<()> {
let temp_dir = TempDir::new()?;
let temp_path = temp_dir.path();
create_test_directory_structure(temp_path)?;
let options = TreeOptions {
case_sensitive: false,
respect_gitignore: false, depth: None,
omit_path_prefix: Some(temp_path.to_path_buf()),
};
let tree_result = generate_tree(temp_path, &options)?;
assert!(!tree_result.is_empty(), "Tree result should not be empty");
for dir_tree in &tree_result {
let normalized_dir = normalize_path(&dir_tree.dir);
assert!(
!normalized_dir.contains(temp_path.to_string_lossy().as_ref()),
"Directory path '{}' should not contain the temp path prefix",
normalized_dir
);
assert!(
normalized_dir.len() < temp_path.to_string_lossy().len(),
"Directory path '{}' should be shorter than the original temp path",
normalized_dir
);
}
let dir_names: Vec<String> = tree_result.iter().map(|d| normalize_path(&d.dir)).collect();
assert!(
dir_names.iter().any(|d| d.is_empty() || d == "."),
"Root directory should be present in the results"
);
let expected_dirs = ["src", "docs", "docs/examples", "tests", "src/utils"];
for expected in &expected_dirs {
let found = dir_names.iter().any(|d| d.ends_with(expected));
assert!(
found,
"Directory '{}' should be present in the results",
expected
);
}
Ok(())
}
#[test]
fn test_omit_path_prefix_without_removal() -> Result<()> {
let temp_dir = TempDir::new()?;
let temp_path = temp_dir.path();
create_test_directory_structure(temp_path)?;
let options = TreeOptions {
case_sensitive: false,
respect_gitignore: false,
depth: None,
omit_path_prefix: None, };
let tree_result = generate_tree(temp_path, &options)?;
for dir_tree in &tree_result {
let normalized_dir = normalize_path(&dir_tree.dir);
assert!(
normalized_dir.starts_with(&normalize_path(&temp_path.to_string_lossy())),
"Directory path '{}' should start with the temp path prefix",
normalized_dir
);
}
Ok(())
}
#[test]
fn test_omit_path_prefix_partial_match() -> Result<()> {
let temp_dir = TempDir::new()?;
let temp_path = temp_dir.path();
create_test_directory_structure(temp_path)?;
let non_matching_prefix = if cfg!(windows) {
PathBuf::from("C:\\some\\other\\path")
} else {
PathBuf::from("/some/other/path")
};
let options = TreeOptions {
case_sensitive: false,
respect_gitignore: false,
depth: None,
omit_path_prefix: Some(non_matching_prefix.clone()),
};
let tree_result = generate_tree(temp_path, &options)?;
for dir_tree in &tree_result {
let normalized_dir = normalize_path(&dir_tree.dir);
assert!(
normalized_dir.starts_with(&normalize_path(&temp_path.to_string_lossy())),
"Directory path '{}' should start with the temp path prefix when non-matching prefix is used",
normalized_dir
);
}
Ok(())
}
#[test]
fn test_omit_path_prefix_with_depth_limit() -> Result<()> {
let temp_dir = TempDir::new()?;
let temp_path = temp_dir.path();
create_test_directory_structure(temp_path)?;
let options = TreeOptions {
case_sensitive: false,
respect_gitignore: false,
depth: Some(1), omit_path_prefix: Some(temp_path.to_path_buf()),
};
let tree_result = generate_tree(temp_path, &options)?;
assert!(!tree_result.is_empty(), "Tree result should not be empty");
for dir_tree in &tree_result {
let normalized_dir = normalize_path(&dir_tree.dir);
assert!(
!normalized_dir.contains(temp_path.to_string_lossy().as_ref()),
"Directory path '{}' should not contain the temp path prefix",
normalized_dir
);
assert!(
!normalized_dir.contains("/"),
"With depth=1, directory path '{}' should not contain subdirectories",
normalized_dir
);
}
Ok(())
}