agent-Specialization/test/test_skills_manager.py
JOJO e3c897947f refactor(paths): 统一迁移运行态数据路径到 Astrion 命名空间
- 工作区内部路径 .agents/ -> .astrion/
- 默认运行态数据根 ~/.agents/agents/ -> ~/.astrion/astrion/
- 环境变量 AGENTS_DATA_ROOT -> ASTRION_DATA_ROOT(无兼容)
- 同步更新代码、测试、文档与脚本中的路径引用
- 新增 .gitignore 忽略 .astrion/ 与 .agents/ 运行态目录
2026-07-10 00:35:15 +08:00

102 lines
4.0 KiB
Python

from __future__ import annotations
import os
import tempfile
import unittest
from pathlib import Path
# 本模块测试按 web 模式布局推断 skills 目录,需在导入 config 前设定模式。
os.environ["TERMINAL_SANDBOX_MODE"] = "web"
from modules.skills_manager import (
archive_skill_directory,
get_skills_catalog,
infer_private_skills_dir,
sync_workspace_skills,
validate_skill_directory,
)
class SkillsManagerTest(unittest.TestCase):
def test_validate_skill_directory_requires_skill_md_and_frontmatter_fields(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
skill_dir = root / "sample-skill"
skill_dir.mkdir()
missing_file = validate_skill_directory(skill_dir)
self.assertFalse(missing_file.get("success"))
self.assertEqual(missing_file.get("error"), "缺少 SKILL.md")
(skill_dir / "SKILL.md").write_text("---\nname: Sample\n---\n", encoding="utf-8")
missing_description = validate_skill_directory(skill_dir)
self.assertFalse(missing_description.get("success"))
self.assertEqual(missing_description.get("error"), "缺少 description:")
(skill_dir / "SKILL.md").write_text(
"---\nname: Sample\ndescription: Demo skill\n---\n",
encoding="utf-8",
)
valid = validate_skill_directory(skill_dir)
self.assertTrue(valid.get("success"))
self.assertEqual(valid.get("skill_name"), "sample-skill")
def test_archive_skill_directory_moves_without_overwriting(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
skill_dir = root / "sample-skill"
target_root = root / "agentskills"
skill_dir.mkdir()
(skill_dir / "SKILL.md").write_text(
"---\nname: Sample\ndescription: Demo skill\n---\n",
encoding="utf-8",
)
archived = archive_skill_directory(skill_dir, target_root)
self.assertTrue(archived.get("success"))
self.assertFalse(skill_dir.exists())
self.assertTrue((target_root / "sample-skill" / "SKILL.md").exists())
duplicate_src = root / "sample-skill"
duplicate_src.mkdir()
(duplicate_src / "SKILL.md").write_text(
"---\nname: Sample\ndescription: Demo skill\n---\n",
encoding="utf-8",
)
duplicate = archive_skill_directory(duplicate_src, target_root)
self.assertFalse(duplicate.get("success"))
self.assertEqual(duplicate.get("error"), "目标 skill 已存在")
def test_private_skills_are_cataloged_and_synced(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
global_root = root / "global"
private_root = root / "users" / "jojo" / "agentskills"
data_dir = root / "users" / "jojo" / "data"
project = root / "project"
private_skill = private_root / "private-skill"
private_skill.mkdir(parents=True)
data_dir.mkdir(parents=True)
project.mkdir(parents=True)
(private_skill / "SKILL.md").write_text(
"---\nname: Private Skill\ndescription: Private demo\n---\n",
encoding="utf-8",
)
self.assertEqual(infer_private_skills_dir(data_dir), private_root.resolve())
catalog = get_skills_catalog(base_dir=str(global_root), private_dir=private_root)
self.assertEqual([item["id"] for item in catalog], ["private-skill"])
synced = sync_workspace_skills(
project,
enabled_skills=["private-skill"],
base_dir=str(global_root),
private_dir=private_root,
)
self.assertTrue(synced.get("success"))
self.assertTrue((project / ".astrion" / "skills" / "private-skill" / "SKILL.md").exists())
if __name__ == "__main__":
unittest.main()