Files
galaxy/app/src/ai/skills/skill_utils_tests.rs
T

190 lines
6.4 KiB
Rust

use std::path::PathBuf;
use ai::skills::{ParsedSkill, SkillProvider, SkillScope};
use warp_util::host_id::HostId;
use warp_util::local_or_remote_path::LocalOrRemotePath;
use warp_util::remote_path::RemotePath;
use warp_util::standardized_path::StandardizedPath;
use super::*;
fn remote_location(path: &str) -> LocalOrRemotePath {
LocalOrRemotePath::Remote(RemotePath::new(
HostId::new("remote-host".to_string()),
StandardizedPath::try_new(path).unwrap(),
))
}
#[test]
fn skill_path_from_unix_encoded_remote_location() {
let location = remote_location("/repo/.agents/skills/deploy/scripts/run.sh");
assert_eq!(
skill_path_from_location(&location),
Some(remote_location("/repo/.agents/skills/deploy/SKILL.md"))
);
}
#[test]
fn skill_path_from_windows_encoded_remote_location() {
let location = remote_location(r"C:\repo\.agents\skills\deploy\scripts\run.ps1");
assert_eq!(
skill_path_from_location(&location),
Some(remote_location(r"C:\repo\.agents\skills\deploy\SKILL.md"))
);
}
#[test]
fn test_unique_skills_dedupes_identical_skills_same_dir() {
let shared_skill_dir = PathBuf::from("/home/user");
let skill_path1 = shared_skill_dir.join(".agents/skills/my-skill/SKILL.md");
let skill_path2 = shared_skill_dir.join(".claude/skills/my-skill/SKILL.md");
let content = "---\nname: test-skill\ndescription: A test skill\n---\nContent here";
let skill = ParsedSkill {
path: LocalOrRemotePath::Local(skill_path1.clone()),
name: "test-skill".to_string(),
description: "A test skill".to_string(),
content: content.to_string(),
line_range: Some(8..18),
provider: SkillProvider::Agents,
scope: SkillScope::Home,
};
let skill2 = ParsedSkill {
path: LocalOrRemotePath::Local(skill_path2.clone()),
name: "test-skill".to_string(),
description: "A test skill".to_string(),
content: content.to_string(),
line_range: Some(8..18),
provider: SkillProvider::Claude,
scope: SkillScope::Home,
};
let mut skills_by_path = HashMap::new();
skills_by_path.insert(LocalOrRemotePath::Local(skill_path1.clone()), skill);
skills_by_path.insert(LocalOrRemotePath::Local(skill_path2.clone()), skill2);
let skill_paths = vec![
(
LocalOrRemotePath::Local(shared_skill_dir.clone()),
LocalOrRemotePath::Local(skill_path1),
),
(
LocalOrRemotePath::Local(shared_skill_dir),
LocalOrRemotePath::Local(skill_path2),
),
];
let result = unique_skills(&skill_paths, &skills_by_path);
assert_eq!(result.len(), 1);
// Agents has higher priority (index 0) than Claude, so it should be preferred
assert_eq!(result[0].provider, SkillProvider::Agents);
}
#[test]
fn test_unique_skills_does_not_dedupe_different_dirs() {
let home_dir = PathBuf::from("/home/user");
let project_dir = PathBuf::from("/home/user/projects/repo");
let home_path = home_dir.join(".agents/skills/my-skill/SKILL.md");
let project_path = project_dir.join(".agents/skills/my-skill/SKILL.md");
let content = "---\nname: test-skill\ndescription: A test skill\n---\nContent here";
let home_skill = ParsedSkill {
path: LocalOrRemotePath::Local(home_path.clone()),
name: "test-skill".to_string(),
description: "A test skill".to_string(),
content: content.to_string(),
line_range: Some(8..18),
provider: SkillProvider::Agents,
scope: SkillScope::Home,
};
let project_skill = ParsedSkill {
path: LocalOrRemotePath::Local(project_path.clone()),
name: "test-skill".to_string(),
description: "A test skill".to_string(),
content: content.to_string(),
line_range: Some(8..18),
provider: SkillProvider::Agents,
scope: SkillScope::Project,
};
let mut skills_by_path = HashMap::new();
skills_by_path.insert(LocalOrRemotePath::Local(home_path.clone()), home_skill);
skills_by_path.insert(
LocalOrRemotePath::Local(project_path.clone()),
project_skill,
);
let skill_paths = vec![
(
LocalOrRemotePath::Local(home_dir),
LocalOrRemotePath::Local(home_path),
),
(
LocalOrRemotePath::Local(project_dir),
LocalOrRemotePath::Local(project_path),
),
];
let result = unique_skills(&skill_paths, &skills_by_path);
assert_eq!(
result.len(),
2,
"Skills with same content but different directories should not be deduped"
);
}
#[test]
fn test_unique_skills_does_not_dedupe_different_content() {
let shared_skill_dir = PathBuf::from("/home/user");
let skill_path1 = shared_skill_dir.join(".agents/skills/my-skill/SKILL.md");
let skill_path2 = shared_skill_dir.join(".claude/skills/my-skill/SKILL.md");
let content1 = "---\nname: test-skill\ndescription: A test skill\n---\nContent here";
let content2 = "---\nname: test-skill\ndescription: A test skill\n---\nDifferent content";
let skill1 = ParsedSkill {
path: LocalOrRemotePath::Local(skill_path1.clone()),
name: "test-skill".to_string(),
description: "A test skill".to_string(),
content: content1.to_string(),
line_range: Some(8..18),
provider: SkillProvider::Agents,
scope: SkillScope::Home,
};
let skill2 = ParsedSkill {
path: LocalOrRemotePath::Local(skill_path2.clone()),
name: "test-skill".to_string(),
description: "A test skill".to_string(),
content: content2.to_string(),
line_range: Some(8..18),
provider: SkillProvider::Claude,
scope: SkillScope::Home,
};
let mut skills_by_path = HashMap::new();
skills_by_path.insert(LocalOrRemotePath::Local(skill_path1.clone()), skill1);
skills_by_path.insert(LocalOrRemotePath::Local(skill_path2.clone()), skill2);
let skill_paths = vec![
(
LocalOrRemotePath::Local(shared_skill_dir.clone()),
LocalOrRemotePath::Local(skill_path1),
),
(
LocalOrRemotePath::Local(shared_skill_dir),
LocalOrRemotePath::Local(skill_path2),
),
];
let result = unique_skills(&skill_paths, &skills_by_path);
assert_eq!(
result.len(),
2,
"Skills with different content should not be deduped even if same directory and name"
);
}