superclaude-org--superclaude_framework
5463aff45a
Complete the confidence-check skill's TypeScript implementation (4 of its 5 checks were placeholder stubs that only read context flags) and enrich the Python ConfidenceChecker with real tech-stack detection, architecture anti-pattern warnings, and multi-language duplicate search. Logic is ported from the kazukinakai fork. The dead airis-agent import layer from the fork is intentionally dropped: the checks work with zero optional dependencies, and each check still honors its explicit *_complete / *_verified context-flag override for testing and pre-checked scenarios. - confidence.ts: implement noDuplicates / architectureCompliant / hasOssReference / rootCauseIdentified with project scanning, CLAUDE.md tech-stack parsing, and regex-based uncertainty detection. Synced across all four tracked skill copies (src CLI source, plugin source, repo-root, .claude). - confidence.py: add _read_tech_stack and _check_architecture_anti_patterns; multi-language (py/ts/js) + content-grep _search_codebase; richer root-cause validation. Flat single-class structure preserved; accepts both upstream (target_name/root_cause) and fork (feature_name/proposed_technology) keys. - tests: add test_cli_main, test_doctor, test_execution_init, test_install_mcp, test_install_skill, e2e/test_cli_e2e; expand test_confidence to a superset. All ported tests pass against the existing upstream modules. fork-only init/check CLI tests and circular full-suite meta-tests were excluded. NOTE: the confidence-check skill is duplicated across four tracked locations; a follow-up should collapse these to a single source. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
212 行
7.5 KiB
Python
212 行
7.5 KiB
Python
"""
|
|
Tests for Skill Installation Command
|
|
|
|
Tests skill installation functionality.
|
|
"""
|
|
|
|
import tempfile
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
|
|
class TestInstallSkill:
|
|
"""Tests for install_skill module"""
|
|
|
|
def test_list_available_skills_returns_list(self):
|
|
"""Test list_available_skills returns a list"""
|
|
from superclaude.cli.install_skill import list_available_skills
|
|
|
|
result = list_available_skills()
|
|
|
|
assert isinstance(result, list)
|
|
|
|
def test_list_available_skills_sorted(self):
|
|
"""Test list_available_skills returns sorted list"""
|
|
from superclaude.cli.install_skill import list_available_skills
|
|
|
|
result = list_available_skills()
|
|
|
|
assert result == sorted(result)
|
|
|
|
def test_install_skill_nonexistent_skill(self):
|
|
"""Test installing nonexistent skill fails"""
|
|
from superclaude.cli.install_skill import install_skill_command
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
target = Path(tmpdir) / "skills"
|
|
success, message = install_skill_command("nonexistent-skill-xyz", target)
|
|
|
|
assert success is False
|
|
assert "not found" in message.lower()
|
|
|
|
def test_install_skill_creates_target_dir(self):
|
|
"""Test install_skill creates target directory"""
|
|
from superclaude.cli.install_skill import install_skill_command
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
target = Path(tmpdir) / "new" / "nested" / "skills"
|
|
|
|
# Even if skill doesn't exist, target dir creation is attempted
|
|
install_skill_command("nonexistent", target)
|
|
|
|
# May or may not exist depending on when creation happens
|
|
# Just verify no exception is raised
|
|
|
|
|
|
class TestGetSkillSource:
|
|
"""Tests for _get_skill_source function"""
|
|
|
|
def test_get_skill_source_returns_none_for_unknown(self):
|
|
"""Test _get_skill_source returns None for unknown skills"""
|
|
from superclaude.cli.install_skill import _get_skill_source
|
|
|
|
result = _get_skill_source("unknown-skill-xyz-123")
|
|
|
|
assert result is None
|
|
|
|
def test_get_skill_source_handles_hyphen_underscore(self):
|
|
"""Test _get_skill_source normalizes skill names"""
|
|
from superclaude.cli.install_skill import _get_skill_source
|
|
|
|
# Should handle both hyphen and underscore versions
|
|
result1 = _get_skill_source("some-skill")
|
|
result2 = _get_skill_source("some_skill")
|
|
|
|
# Both should return same or None
|
|
assert result1 == result2 or (result1 is None and result2 is None)
|
|
|
|
|
|
class TestIsValidSkillDir:
|
|
"""Tests for _is_valid_skill_dir function"""
|
|
|
|
def test_is_valid_skill_dir_with_skill_md(self):
|
|
"""Test _is_valid_skill_dir recognizes SKILL.md"""
|
|
from superclaude.cli.install_skill import _is_valid_skill_dir
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
skill_dir = Path(tmpdir)
|
|
(skill_dir / "SKILL.md").touch()
|
|
|
|
assert _is_valid_skill_dir(skill_dir) is True
|
|
|
|
def test_is_valid_skill_dir_with_implementation_md(self):
|
|
"""Test _is_valid_skill_dir recognizes implementation.md"""
|
|
from superclaude.cli.install_skill import _is_valid_skill_dir
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
skill_dir = Path(tmpdir)
|
|
(skill_dir / "implementation.md").touch()
|
|
|
|
assert _is_valid_skill_dir(skill_dir) is True
|
|
|
|
def test_is_valid_skill_dir_with_code_files(self):
|
|
"""Test _is_valid_skill_dir recognizes code files"""
|
|
from superclaude.cli.install_skill import _is_valid_skill_dir
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
skill_dir = Path(tmpdir)
|
|
(skill_dir / "main.py").touch()
|
|
|
|
assert _is_valid_skill_dir(skill_dir) is True
|
|
|
|
def test_is_valid_skill_dir_empty_dir(self):
|
|
"""Test _is_valid_skill_dir rejects empty directory"""
|
|
from superclaude.cli.install_skill import _is_valid_skill_dir
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
skill_dir = Path(tmpdir)
|
|
|
|
assert _is_valid_skill_dir(skill_dir) is False
|
|
|
|
def test_is_valid_skill_dir_nonexistent(self):
|
|
"""Test _is_valid_skill_dir handles nonexistent path"""
|
|
from superclaude.cli.install_skill import _is_valid_skill_dir
|
|
|
|
result = _is_valid_skill_dir(Path("/nonexistent/path/xyz"))
|
|
|
|
assert result is False
|
|
|
|
def test_is_valid_skill_dir_none_path(self):
|
|
"""Test _is_valid_skill_dir handles None"""
|
|
from superclaude.cli.install_skill import _is_valid_skill_dir
|
|
|
|
result = _is_valid_skill_dir(None)
|
|
|
|
assert result is False
|
|
|
|
|
|
class TestInstallSkillWithMocks:
|
|
"""Tests with mocked skill source"""
|
|
|
|
def test_install_skill_success(self):
|
|
"""Test successful skill installation"""
|
|
from superclaude.cli.install_skill import install_skill_command
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
# Create mock skill source
|
|
source_dir = Path(tmpdir) / "source" / "test-skill"
|
|
source_dir.mkdir(parents=True)
|
|
(source_dir / "SKILL.md").write_text("# Test Skill")
|
|
(source_dir / "main.py").write_text("# Main file")
|
|
|
|
target_dir = Path(tmpdir) / "target"
|
|
|
|
with patch(
|
|
"superclaude.cli.install_skill._get_skill_source",
|
|
return_value=source_dir,
|
|
):
|
|
success, message = install_skill_command("test-skill", target_dir)
|
|
|
|
assert success is True
|
|
assert "successfully" in message.lower()
|
|
assert (target_dir / "test-skill" / "SKILL.md").exists()
|
|
|
|
def test_install_skill_already_exists(self):
|
|
"""Test skill installation fails if already exists"""
|
|
from superclaude.cli.install_skill import install_skill_command
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
# Create mock skill source
|
|
source_dir = Path(tmpdir) / "source" / "test-skill"
|
|
source_dir.mkdir(parents=True)
|
|
(source_dir / "SKILL.md").write_text("# Test Skill")
|
|
|
|
target_dir = Path(tmpdir) / "target"
|
|
(target_dir / "test-skill").mkdir(parents=True)
|
|
|
|
with patch(
|
|
"superclaude.cli.install_skill._get_skill_source",
|
|
return_value=source_dir,
|
|
):
|
|
success, message = install_skill_command("test-skill", target_dir)
|
|
|
|
assert success is False
|
|
assert "already installed" in message.lower()
|
|
|
|
def test_install_skill_force_reinstall(self):
|
|
"""Test skill force reinstall overwrites existing"""
|
|
from superclaude.cli.install_skill import install_skill_command
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
# Create mock skill source
|
|
source_dir = Path(tmpdir) / "source" / "test-skill"
|
|
source_dir.mkdir(parents=True)
|
|
(source_dir / "SKILL.md").write_text("# New Version")
|
|
|
|
target_dir = Path(tmpdir) / "target"
|
|
existing = target_dir / "test-skill"
|
|
existing.mkdir(parents=True)
|
|
(existing / "SKILL.md").write_text("# Old Version")
|
|
|
|
with patch(
|
|
"superclaude.cli.install_skill._get_skill_source",
|
|
return_value=source_dir,
|
|
):
|
|
success, message = install_skill_command(
|
|
"test-skill", target_dir, force=True
|
|
)
|
|
|
|
assert success is True
|
|
content = (target_dir / "test-skill" / "SKILL.md").read_text()
|
|
assert "New Version" in content
|