Skip to content

Commit 062bb0b

Browse files
zhujian0805claude
andcommitted
test(skills): add 10 new tests for skills_commands CLI
Add tests for uncovered skill command functions: - list_skills (empty and with skills) - view_skill (success and not found) - create_skill - delete_skill (success and not found) - uninstall_skill (single and multiple apps) - list_repos 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 5a89b02 commit 062bb0b

1 file changed

Lines changed: 169 additions & 0 deletions

File tree

tests/unit/test_skills_cli.py

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import pytest
66

77
import code_assistant_manager.cli.skills_commands as skills_commands
8+
from code_assistant_manager.skills import Skill
89

910

1011
@pytest.fixture
@@ -17,19 +18,38 @@ def __init__(self):
1718
self.installs = []
1819
self.uninstalls = []
1920
self.skills = {}
21+
self.created_skills = []
22+
self.updated_skills = []
23+
self.deleted_skills = []
2024

2125
def sync_installed_status(self, app):
2226
self.synced.append(app)
2327

2428
def get_all(self):
2529
return self.skills
2630

31+
def get(self, key):
32+
return self.skills.get(key)
33+
2734
def install(self, key, app):
2835
self.installs.append((key, app))
2936

3037
def uninstall(self, key, app):
3138
self.uninstalls.append((key, app))
3239

40+
def create(self, skill):
41+
self.created_skills.append(skill)
42+
self.skills[skill.key] = skill
43+
44+
def update(self, skill):
45+
self.updated_skills.append(skill)
46+
self.skills[skill.key] = skill
47+
48+
def delete(self, key):
49+
self.deleted_skills.append(key)
50+
if key in self.skills:
51+
del self.skills[key]
52+
3353
manager = DummyManager()
3454
monkeypatch.setattr(skills_commands, "_get_skill_manager", lambda: manager)
3555
return manager
@@ -73,3 +93,152 @@ def get_all(self):
7393
captured = capsys.readouterr().out
7494
for app in skills_commands.VALID_APP_TYPES:
7595
assert f"{app.capitalize()}" in captured
96+
97+
98+
# Additional tests for skill commands
99+
100+
101+
def test_list_skills_empty(dummy_skill_manager, capsys):
102+
"""list_skills shows message when no skills exist."""
103+
skills_commands.list_skills(app_type="claude")
104+
captured = capsys.readouterr().out
105+
assert "No skills found" in captured
106+
107+
108+
def test_list_skills_with_skills(dummy_skill_manager, capsys):
109+
"""list_skills shows all skills with their status."""
110+
dummy_skill_manager.skills = {
111+
"test-skill": Skill(
112+
key="test-skill",
113+
name="Test Skill",
114+
description="A test skill",
115+
directory="/path/to/skill",
116+
installed=True,
117+
),
118+
"another-skill": Skill(
119+
key="another-skill",
120+
name="Another Skill",
121+
description="Another skill",
122+
directory="/path/to/another",
123+
installed=False,
124+
),
125+
}
126+
127+
skills_commands.list_skills(app_type="claude")
128+
captured = capsys.readouterr().out
129+
assert "Test Skill" in captured
130+
assert "Another Skill" in captured
131+
assert "test-skill" in captured
132+
assert "another-skill" in captured
133+
134+
135+
def test_view_skill_success(dummy_skill_manager, capsys):
136+
"""view_skill displays skill content."""
137+
dummy_skill_manager.skills = {
138+
"test-skill": Skill(
139+
key="test-skill",
140+
name="Test Skill",
141+
description="A test skill description",
142+
directory="/path/to/skill",
143+
repo_owner="owner",
144+
repo_name="repo",
145+
installed=True,
146+
)
147+
}
148+
149+
skills_commands.view_skill("test-skill")
150+
captured = capsys.readouterr().out
151+
assert "Test Skill" in captured
152+
assert "A test skill description" in captured
153+
assert "owner/repo" in captured
154+
155+
156+
def test_view_skill_not_found(dummy_skill_manager, capsys):
157+
"""view_skill raises exit when skill not found."""
158+
with pytest.raises(skills_commands.typer.Exit):
159+
skills_commands.view_skill("nonexistent")
160+
161+
captured = capsys.readouterr().out
162+
assert "not found" in captured
163+
164+
165+
def test_create_skill_success(dummy_skill_manager, capsys):
166+
"""create_skill creates a new skill."""
167+
skills_commands.create_skill(
168+
skill_key="new-skill",
169+
name="New Skill",
170+
description="A new skill",
171+
directory="/path/to/skill",
172+
)
173+
174+
captured = capsys.readouterr().out
175+
assert "created" in captured.lower()
176+
assert len(dummy_skill_manager.created_skills) == 1
177+
assert dummy_skill_manager.created_skills[0].key == "new-skill"
178+
179+
180+
def test_delete_skill_success(dummy_skill_manager, capsys):
181+
"""delete_skill removes a skill."""
182+
dummy_skill_manager.skills = {
183+
"test-skill": Skill(
184+
key="test-skill",
185+
name="Test Skill",
186+
description="A test skill",
187+
directory="/path/to/skill",
188+
)
189+
}
190+
191+
skills_commands.delete_skill("test-skill", force=True)
192+
captured = capsys.readouterr().out
193+
assert "deleted" in captured.lower()
194+
assert "test-skill" in dummy_skill_manager.deleted_skills
195+
196+
197+
def test_delete_skill_not_found(dummy_skill_manager, capsys):
198+
"""delete_skill fails when skill not found."""
199+
with pytest.raises(skills_commands.typer.Exit):
200+
skills_commands.delete_skill("nonexistent", force=True)
201+
202+
captured = capsys.readouterr().out
203+
assert "not found" in captured
204+
205+
206+
def test_uninstall_skill_success(dummy_skill_manager, tmp_path, monkeypatch):
207+
"""uninstall_skill removes skill from app."""
208+
install_dirs = {app: tmp_path / app for app in skills_commands.VALID_APP_TYPES}
209+
for directory in install_dirs.values():
210+
directory.mkdir()
211+
monkeypatch.setattr(skills_commands, "SKILL_INSTALL_DIRS", install_dirs)
212+
213+
skills_commands.uninstall_skill("test-skill", app_type="claude")
214+
assert dummy_skill_manager.uninstalls == [("test-skill", "claude")]
215+
216+
217+
def test_uninstall_skill_multiple_apps(dummy_skill_manager, tmp_path, monkeypatch):
218+
"""uninstall_skill removes skill from multiple apps."""
219+
install_dirs = {app: tmp_path / app for app in skills_commands.VALID_APP_TYPES}
220+
for directory in install_dirs.values():
221+
directory.mkdir()
222+
monkeypatch.setattr(skills_commands, "SKILL_INSTALL_DIRS", install_dirs)
223+
224+
skills_commands.uninstall_skill("test-skill", app_type="claude,codex")
225+
assert dummy_skill_manager.uninstalls == [
226+
("test-skill", "claude"),
227+
("test-skill", "codex"),
228+
]
229+
230+
231+
def test_list_repos(dummy_skill_manager, capsys, monkeypatch):
232+
"""list_repos shows configured skill repositories."""
233+
234+
# Create a mock repos file
235+
class MockManager:
236+
def get_repos(self):
237+
return []
238+
239+
monkeypatch.setattr(skills_commands, "_get_skill_manager", lambda: MockManager())
240+
241+
skills_commands.list_repos()
242+
captured = capsys.readouterr().out
243+
# Should show header or "No repositories" message
244+
assert "repo" in captured.lower() or captured.strip() != ""

0 commit comments

Comments
 (0)