#![cfg_attr(coverage_nightly, coverage(off))]
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests_part2 {
use super::super::types::{
AgentsMdDiscovery, AgentsMdFile, AgentsMdHierarchy, DiscoveryConfig, FileChange,
FileChangeType, HierarchyNode,
};
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
use std::time::SystemTime;
use tempfile::TempDir;
#[test]
fn test_cache_operations() {
let temp_dir = TempDir::new().unwrap();
let agents_path = temp_dir.path().join("AGENTS.md");
fs::write(&agents_path, "# Test").unwrap();
let discovery = AgentsMdDiscovery::new();
let found1 = discovery.find_nearest(temp_dir.path());
assert_eq!(found1, Some(agents_path.clone()));
let found2 = discovery.find_nearest(temp_dir.path());
assert_eq!(found2, Some(agents_path.clone()));
discovery.clear_cache();
let found3 = discovery.find_nearest(temp_dir.path());
assert_eq!(found3, Some(agents_path));
}
#[test]
fn test_clear_cache() {
let temp_dir = TempDir::new().unwrap();
fs::write(temp_dir.path().join("AGENTS.md"), "# Test").unwrap();
let discovery = AgentsMdDiscovery::new();
let _files = discovery.discover_all(temp_dir.path());
assert!(!discovery.cache.is_empty());
discovery.clear_cache();
assert!(discovery.cache.is_empty());
}
#[test]
fn test_cache_stores_correct_metadata() {
let temp_dir = TempDir::new().unwrap();
let agents_path = temp_dir.path().join("AGENTS.md");
fs::write(&agents_path, "# Test").unwrap();
let discovery = AgentsMdDiscovery::new();
let _found = discovery.find_nearest(&agents_path);
let cached = discovery.cache.get(&agents_path);
assert!(cached.is_some());
let cached = cached.unwrap();
assert_eq!(cached.path, agents_path);
assert_eq!(cached.parent, temp_dir.path());
assert!(cached.content.is_none()); assert!(cached.document.is_none()); }
#[test]
fn test_depth_limit() {
let temp_dir = TempDir::new().unwrap();
let mut current = temp_dir.path().to_path_buf();
for i in 0..5 {
current = current.join(format!("level{}", i));
fs::create_dir(¤t).unwrap();
}
fs::write(temp_dir.path().join("AGENTS.md"), "# Root").unwrap();
let discovery = AgentsMdDiscovery::with_config(DiscoveryConfig {
max_depth: 3,
..Default::default()
});
let found = discovery.find_nearest(¤t);
assert_eq!(found, None);
}
#[test]
fn test_depth_limit_zero() {
let temp_dir = TempDir::new().unwrap();
let subdir = temp_dir.path().join("subdir");
fs::create_dir(&subdir).unwrap();
fs::write(temp_dir.path().join("AGENTS.md"), "# Root").unwrap();
let config = DiscoveryConfig {
max_depth: 0,
..Default::default()
};
let discovery = AgentsMdDiscovery::with_config(config);
let found = discovery.find_nearest(&subdir);
assert_eq!(found, None);
let found = discovery.find_nearest(temp_dir.path());
assert!(found.is_some());
}
#[test]
fn test_depth_limit_discover_all() {
let temp_dir = TempDir::new().unwrap();
fs::write(temp_dir.path().join("AGENTS.md"), "# Root").unwrap();
let level1 = temp_dir.path().join("l1");
fs::create_dir(&level1).unwrap();
fs::write(level1.join("AGENTS.md"), "# L1").unwrap();
let level2 = level1.join("l2");
fs::create_dir(&level2).unwrap();
fs::write(level2.join("AGENTS.md"), "# L2").unwrap();
let level3 = level2.join("l3");
fs::create_dir(&level3).unwrap();
fs::write(level3.join("AGENTS.md"), "# L3").unwrap();
let config = DiscoveryConfig {
max_depth: 2,
..Default::default()
};
let discovery = AgentsMdDiscovery::with_config(config);
let files = discovery.discover_all(temp_dir.path());
assert_eq!(files.len(), 3);
assert!(files.iter().all(|f| f.depth <= 2));
}
#[test]
fn test_agents_md_file_clone() {
let file = AgentsMdFile {
path: PathBuf::from("/test/AGENTS.md"),
parent: PathBuf::from("/test"),
depth: 2,
modified: SystemTime::now(),
content: Some("# Test".to_string()),
document: None,
};
let cloned = file.clone();
assert_eq!(file.path, cloned.path);
assert_eq!(file.parent, cloned.parent);
assert_eq!(file.depth, cloned.depth);
assert_eq!(file.content, cloned.content);
}
#[test]
fn test_agents_md_file_debug() {
let file = AgentsMdFile {
path: PathBuf::from("/test/AGENTS.md"),
parent: PathBuf::from("/test"),
depth: 0,
modified: SystemTime::now(),
content: None,
document: None,
};
let debug_str = format!("{:?}", file);
assert!(debug_str.contains("AgentsMdFile"));
assert!(debug_str.contains("AGENTS.md"));
}
#[test]
fn test_agents_md_hierarchy_clone() {
let hierarchy = AgentsMdHierarchy {
root: PathBuf::from("/project"),
files: vec![],
tree: HierarchyNode {
path: PathBuf::from("/project"),
agents_file: None,
children: HashMap::new(),
},
};
let cloned = hierarchy.clone();
assert_eq!(hierarchy.root, cloned.root);
}
#[test]
fn test_agents_md_hierarchy_debug() {
let hierarchy = AgentsMdHierarchy {
root: PathBuf::from("/project"),
files: vec![],
tree: HierarchyNode {
path: PathBuf::from("/project"),
agents_file: None,
children: HashMap::new(),
},
};
let debug_str = format!("{:?}", hierarchy);
assert!(debug_str.contains("AgentsMdHierarchy"));
}
#[test]
fn test_hierarchy_node_clone() {
let node = HierarchyNode {
path: PathBuf::from("/test"),
agents_file: None,
children: HashMap::new(),
};
let cloned = node.clone();
assert_eq!(node.path, cloned.path);
}
#[test]
fn test_hierarchy_node_debug() {
let node = HierarchyNode {
path: PathBuf::from("/test"),
agents_file: None,
children: HashMap::new(),
};
let debug_str = format!("{:?}", node);
assert!(debug_str.contains("HierarchyNode"));
}
#[test]
fn test_hierarchy_node_with_children() {
let mut children = HashMap::new();
children.insert(
"child".to_string(),
HierarchyNode {
path: PathBuf::from("/test/child"),
agents_file: None,
children: HashMap::new(),
},
);
let node = HierarchyNode {
path: PathBuf::from("/test"),
agents_file: None,
children,
};
assert_eq!(node.children.len(), 1);
assert!(node.children.contains_key("child"));
}
#[test]
fn test_file_change_clone() {
let change = FileChange {
path: PathBuf::from("/test/AGENTS.md"),
change_type: FileChangeType::Created,
timestamp: SystemTime::now(),
};
let cloned = change.clone();
assert_eq!(change.path, cloned.path);
assert_eq!(change.change_type, cloned.change_type);
}
#[test]
fn test_file_change_debug() {
let change = FileChange {
path: PathBuf::from("/test/AGENTS.md"),
change_type: FileChangeType::Modified,
timestamp: SystemTime::now(),
};
let debug_str = format!("{:?}", change);
assert!(debug_str.contains("FileChange"));
assert!(debug_str.contains("Modified"));
}
#[test]
fn test_file_change_type_equality() {
assert_eq!(FileChangeType::Created, FileChangeType::Created);
assert_eq!(FileChangeType::Modified, FileChangeType::Modified);
assert_eq!(FileChangeType::Removed, FileChangeType::Removed);
assert_ne!(FileChangeType::Created, FileChangeType::Modified);
assert_ne!(FileChangeType::Modified, FileChangeType::Removed);
assert_ne!(FileChangeType::Created, FileChangeType::Removed);
}
#[test]
fn test_file_change_type_clone() {
let created = FileChangeType::Created.clone();
let modified = FileChangeType::Modified.clone();
let removed = FileChangeType::Removed.clone();
assert_eq!(created, FileChangeType::Created);
assert_eq!(modified, FileChangeType::Modified);
assert_eq!(removed, FileChangeType::Removed);
}
#[test]
fn test_file_change_type_debug() {
assert!(format!("{:?}", FileChangeType::Created).contains("Created"));
assert!(format!("{:?}", FileChangeType::Modified).contains("Modified"));
assert!(format!("{:?}", FileChangeType::Removed).contains("Removed"));
}
#[test]
fn test_find_common_root_single_file() {
let temp_dir = TempDir::new().unwrap();
fs::write(temp_dir.path().join("AGENTS.md"), "# Root").unwrap();
let discovery = AgentsMdDiscovery::new();
let files = discovery.discover_all(temp_dir.path());
assert_eq!(files.len(), 1);
let hierarchy = discovery.build_hierarchy(files);
assert_eq!(hierarchy.root, temp_dir.path());
}
#[test]
fn test_find_common_root_sibling_dirs() {
let temp_dir = TempDir::new().unwrap();
let dir_a = temp_dir.path().join("a");
fs::create_dir(&dir_a).unwrap();
fs::write(dir_a.join("AGENTS.md"), "# A").unwrap();
let dir_b = temp_dir.path().join("b");
fs::create_dir(&dir_b).unwrap();
fs::write(dir_b.join("AGENTS.md"), "# B").unwrap();
let discovery = AgentsMdDiscovery::new();
let files = discovery.discover_all(temp_dir.path());
let hierarchy = discovery.build_hierarchy(files);
assert_eq!(hierarchy.root, temp_dir.path());
}
#[test]
fn test_stop_watching() {
let mut discovery = AgentsMdDiscovery::new();
assert!(discovery.watcher.is_none());
discovery.stop_watching();
assert!(discovery.watcher.is_none());
}
#[test]
fn test_discover_with_symlinks() {
let temp_dir = TempDir::new().unwrap();
let real_dir = temp_dir.path().join("real");
fs::create_dir(&real_dir).unwrap();
fs::write(real_dir.join("AGENTS.md"), "# Real").unwrap();
let link_path = temp_dir.path().join("link");
if std::os::unix::fs::symlink(&real_dir, &link_path).is_ok() {
let discovery = AgentsMdDiscovery::new();
let files = discovery.discover_all(temp_dir.path());
assert!(files.len() >= 1);
}
}
#[test]
fn test_discover_empty_file() {
let temp_dir = TempDir::new().unwrap();
let agents_path = temp_dir.path().join("AGENTS.md");
fs::write(&agents_path, "").unwrap();
let discovery = AgentsMdDiscovery::new();
let files = discovery.discover_all(temp_dir.path());
assert_eq!(files.len(), 1);
}
#[test]
fn test_discover_large_hierarchy() {
let temp_dir = TempDir::new().unwrap();
for i in 0..10 {
let dir = temp_dir.path().join(format!("dir{}", i));
fs::create_dir(&dir).unwrap();
fs::write(dir.join("AGENTS.md"), format!("# Dir {}", i)).unwrap();
}
let discovery = AgentsMdDiscovery::new();
let files = discovery.discover_all(temp_dir.path());
assert_eq!(files.len(), 10);
}
#[test]
fn test_discover_mixed_extensions() {
let temp_dir = TempDir::new().unwrap();
fs::write(temp_dir.path().join("AGENTS.md"), "# Correct").unwrap();
fs::write(temp_dir.path().join("AGENTS.txt"), "Ignored").unwrap();
fs::write(temp_dir.path().join("AGENTS.md.bak"), "Ignored").unwrap();
fs::write(
temp_dir.path().join("agents.md"),
"Ignored - case sensitive",
)
.unwrap();
let discovery = AgentsMdDiscovery::new();
let files = discovery.discover_all(temp_dir.path());
assert_eq!(files.len(), 1);
assert!(files[0].path.ends_with("AGENTS.md"));
}
#[test]
fn test_cache_hit_on_exact_path() {
let temp_dir = TempDir::new().unwrap();
let agents_path = temp_dir.path().join("AGENTS.md");
fs::write(&agents_path, "# Test").unwrap();
let discovery = AgentsMdDiscovery::new();
let _files = discovery.discover_all(temp_dir.path());
assert!(discovery.cache.contains_key(&agents_path));
let cached = discovery.get_from_cache(&agents_path);
assert!(cached.is_some());
}
#[test]
fn test_hierarchy_preserves_file_order() {
let temp_dir = TempDir::new().unwrap();
fs::write(temp_dir.path().join("AGENTS.md"), "# Root").unwrap();
let sub = temp_dir.path().join("sub");
fs::create_dir(&sub).unwrap();
fs::write(sub.join("AGENTS.md"), "# Sub").unwrap();
let discovery = AgentsMdDiscovery::new();
let files = discovery.discover_all(temp_dir.path());
let hierarchy = discovery.build_hierarchy(files.clone());
assert_eq!(hierarchy.files.len(), files.len());
}
#[test]
fn test_special_characters_in_directory_names() {
let temp_dir = TempDir::new().unwrap();
let special_dir = temp_dir.path().join("dir with spaces");
fs::create_dir(&special_dir).unwrap();
fs::write(special_dir.join("AGENTS.md"), "# Special").unwrap();
let discovery = AgentsMdDiscovery::new();
let files = discovery.discover_all(temp_dir.path());
assert_eq!(files.len(), 1);
}
#[test]
fn test_unicode_in_directory_names() {
let temp_dir = TempDir::new().unwrap();
let unicode_dir = temp_dir.path().join("directorio_espanol");
fs::create_dir(&unicode_dir).unwrap();
fs::write(unicode_dir.join("AGENTS.md"), "# Unicode").unwrap();
let discovery = AgentsMdDiscovery::new();
let files = discovery.discover_all(temp_dir.path());
assert_eq!(files.len(), 1);
}
#[test]
fn test_insert_into_tree_direct_match() {
let temp_dir = TempDir::new().unwrap();
fs::write(temp_dir.path().join("AGENTS.md"), "# Root").unwrap();
let discovery = AgentsMdDiscovery::new();
let files = discovery.discover_all(temp_dir.path());
let hierarchy = discovery.build_hierarchy(files);
assert!(hierarchy.tree.agents_file.is_some());
}
#[test]
fn test_discovery_on_file_not_directory() {
let temp_dir = TempDir::new().unwrap();
let test_file = temp_dir.path().join("test.txt");
fs::write(&test_file, "content").unwrap();
let discovery = AgentsMdDiscovery::new();
let files = discovery.discover_all(&test_file);
assert!(files.is_empty());
}
}