项目文件夹

文件
kazuki f33e7c9e40 feat(cli): install skills and agents instead of slash commands
- 'superclaude install' now installs all skills to ~/.claude/skills/
  and agents to ~/.claude/agents/; new --minimal flag installs only
  the confidence-check skill with no agents
- 'superclaude update' force-reinstalls the same set
- Rename install_commands.py -> install_assets.py (agents only);
  remove dead install_commands/list_*_commands functions
- install_skill: dual source resolution (package dir + plugins/),
  new install_all_skills helper
- doctor: recognize SKILL.md skill layout (legacy implementation.md
  still accepted)
- install.sh / Makefile: drop slash-command install/sync steps
- Update unit and e2e tests to the new install behavior
2026-06-12 11:21:33 +09:00

225 行
7.0 KiB
Python

"""
E2E tests for SuperClaude CLI commands.
These tests execute actual CLI commands via subprocess to verify
the complete user experience works correctly.
"""
import subprocess
import sys
import tempfile
from pathlib import Path
# Get the venv bin directory where superclaude is installed
VENV_BIN = Path(sys.executable).parent
SUPERCLAUDE_CMD = VENV_BIN / "superclaude"
PROJECT_ROOT = Path(__file__).parent.parent.parent
def run_cli(*args, timeout=30, cwd=None):
"""Run superclaude CLI command using venv binary."""
if SUPERCLAUDE_CMD.exists():
cmd = [str(SUPERCLAUDE_CMD), *args]
else:
# Fallback: use python -m superclaude
cmd = [sys.executable, "-m", "superclaude", *args]
return subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=timeout,
cwd=cwd,
)
def run_pytest(*args, timeout=60):
"""Run pytest using venv python."""
return subprocess.run(
[sys.executable, "-m", "pytest", *args],
capture_output=True,
text=True,
timeout=timeout,
cwd=PROJECT_ROOT,
)
class TestCLIVersion:
"""Test version command."""
def test_version_flag(self):
"""Test --version shows version info."""
result = run_cli("--version")
assert result.returncode == 0
assert "superclaude" in result.stdout.lower() or "4." in result.stdout
def test_help_shows_version_option(self):
"""Test help mentions version option."""
result = run_cli("--help")
assert result.returncode == 0
assert "--version" in result.stdout
class TestCLIDoctor:
"""Test doctor command for health checks."""
def test_doctor_runs(self):
"""Test doctor command executes without error."""
result = run_cli("doctor", timeout=60)
# Doctor should run (may have warnings but shouldn't crash)
assert result.returncode in [0, 1] # 0=healthy, 1=warnings
# Should produce some output
assert len(result.stdout) > 0 or len(result.stderr) > 0
def test_doctor_checks_components(self):
"""Test doctor checks expected components."""
result = run_cli("doctor", timeout=60)
output = result.stdout + result.stderr
# Should mention key components
assert any(
keyword in output.lower()
for keyword in [
"superclaude",
"version",
"check",
"health",
"status",
"ok",
"installed",
]
)
class TestCLIInstall:
"""Test install command for skills and agents."""
def test_install_list(self):
"""Test install --list shows available skills and agents."""
result = run_cli("install", "--list")
assert result.returncode == 0
output = result.stdout + result.stderr
# Should list skills and agents
assert "confidence-check" in output
assert "explore-haiku" in output
def test_install_to_temp_directory(self):
"""Test install command installs to specified directories."""
with tempfile.TemporaryDirectory() as tmpdir:
skills_dir = Path(tmpdir) / "skills"
agents_dir = Path(tmpdir) / "agents"
result = run_cli(
"install",
"--skills-dir",
str(skills_dir),
"--agents-dir",
str(agents_dir),
timeout=60,
)
assert result.returncode == 0
assert (skills_dir / "confidence-check" / "SKILL.md").exists()
assert (agents_dir / "explore-haiku.md").exists()
def test_install_help(self):
"""Test install --help shows usage."""
result = run_cli("install", "--help")
assert result.returncode == 0
assert "install" in result.stdout.lower()
class TestCLIMCP:
"""Test MCP server management commands."""
def test_mcp_list(self):
"""Test mcp --list shows available servers."""
result = run_cli("mcp", "--list")
assert result.returncode == 0
output = result.stdout + result.stderr
# Should list some MCP servers
assert any(
server in output.lower()
for server in [
"tavily",
"context7",
"sequential",
"serena",
"gateway",
"airis",
]
)
def test_mcp_help(self):
"""Test mcp --help shows usage."""
result = run_cli("mcp", "--help")
assert result.returncode == 0
assert "mcp" in result.stdout.lower()
class TestCLIHelp:
"""Test help command and flags."""
def test_help_flag(self):
"""Test --help shows usage."""
result = run_cli("--help")
assert result.returncode == 0
assert "superclaude" in result.stdout.lower()
def test_help_shows_commands(self):
"""Test help shows available commands."""
result = run_cli("--help")
output = result.stdout.lower()
# Should mention main commands
assert any(cmd in output for cmd in ["install", "doctor", "mcp"])
class TestPytestPluginE2E:
"""Test pytest plugin loads correctly."""
def test_plugin_registered(self):
"""Test superclaude plugin is registered with pytest."""
result = run_pytest("--co", "-q", "tests/unit/test_confidence.py")
# Should collect tests without error
assert result.returncode == 0 or "collected" in result.stdout.lower()
def test_plugin_fixtures_available(self):
"""Test plugin fixtures are available."""
result = run_pytest("--fixtures", "-q")
output = result.stdout + result.stderr
# Should list our fixtures
assert any(
fixture in output
for fixture in ["confidence_checker", "token_budget", "pm_context"]
)
def test_run_single_unit_test(self):
"""Test running a single unit test works."""
result = run_pytest(
"tests/unit/test_confidence.py::TestConfidenceChecker::test_high_confidence_scenario",
"-v",
)
assert result.returncode == 0
assert "passed" in result.stdout.lower()
class TestConfidenceCheckerE2E:
"""E2E tests for confidence checker functionality."""
def test_confidence_check_workflow(self):
"""Test complete confidence check workflow."""
result = run_pytest(
"tests/unit/test_confidence.py::TestCodebaseSearchImplementation",
"-v",
timeout=120,
)
assert result.returncode == 0
assert "passed" in result.stdout.lower()
def test_architecture_compliance_workflow(self):
"""Test architecture compliance checking."""
result = run_pytest(
"tests/unit/test_confidence.py::TestTechStackDetection",
"-v",
timeout=120,
)
assert result.returncode == 0
assert "passed" in result.stdout.lower()