Initial upload: Add repohealth-cli project with CI/CD workflow
Some checks failed
CI / lint (push) Has been cancelled
CI / build (push) Has been cancelled
CI / test (push) Has been cancelled

This commit is contained in:
2026-02-05 17:14:10 +00:00
parent c5549771d0
commit 792b197ca3

205
tests/test_cli.py Normal file
View File

@@ -0,0 +1,205 @@
"""Tests for CLI interface."""
import os
import json
import tempfile
from pathlib import Path
from unittest.mock import patch, MagicMock
import pytest
from click.testing import CliRunner
from repohealth.cli.cli import main, analyze, report, health
from repohealth.models.result import RepositoryResult
class TestCLI:
"""Tests for CLI commands."""
def test_main_help(self):
"""Test main command help."""
runner = CliRunner()
result = runner.invoke(main, ["--help"])
assert result.exit_code == 0
assert "RepoHealth CLI" in result.output
assert "analyze" in result.output
assert "report" in result.output
assert "health" in result.output
def test_analyze_help(self):
"""Test analyze command help."""
runner = CliRunner()
result = runner.invoke(analyze, ["--help"])
assert result.exit_code == 0
assert "--depth" in result.output
assert "--path" in result.output
assert "--extensions" in result.output
assert "--json" in result.output
def test_report_help(self):
"""Test report command help."""
runner = CliRunner()
result = runner.invoke(report, ["--help"])
assert result.exit_code == 0
assert "--format" in result.output
assert "--output" in result.output
def test_health_help(self):
"""Test health command help."""
runner = CliRunner()
result = runner.invoke(health, ["--help"])
assert result.exit_code == 0
def test_analyze_invalid_repo(self):
"""Test analyze with invalid repository path."""
runner = CliRunner()
result = runner.invoke(analyze, ["/nonexistent/path"])
assert result.exit_code != 0
assert "not a valid Git repository" in result.output
def test_health_invalid_repo(self):
"""Test health with invalid repository path."""
runner = CliRunner()
result = runner.invoke(health, ["/nonexistent/path"])
assert result.exit_code != 0
def test_analyze_negative_depth(self):
"""Test analyze with negative depth option."""
runner = CliRunner()
with tempfile.TemporaryDirectory() as tmpdir:
result = runner.invoke(analyze, [tmpdir, "--depth", "-5"])
assert result.exit_code != 0
assert "positive integer" in result.output
def test_analyze_json_output(self, sample_git_repo, temp_dir):
"""Test analyze with JSON output."""
runner = CliRunner()
result = runner.invoke(analyze, [str(sample_git_repo), "--json"])
assert result.exit_code == 0
output = json.loads(result.output)
assert "repository" in output
assert "summary" in output
assert "files" in output
def test_analyze_json_to_file(self, sample_git_repo, temp_dir):
"""Test analyze saving JSON to file."""
runner = CliRunner()
output_file = temp_dir / "output.json"
result = runner.invoke(
analyze,
[str(sample_git_repo), "--output", str(output_file)]
)
assert result.exit_code == 0
assert output_file.exists()
content = json.loads(output_file.read_text())
assert "repository" in content
def test_report_html_output(self, sample_git_repo, temp_dir):
"""Test report generating HTML output."""
runner = CliRunner()
output_file = temp_dir / "report.html"
result = runner.invoke(
report,
[str(sample_git_repo), "--format", "html", "--output", str(output_file)]
)
assert result.exit_code == 0
assert output_file.exists()
html_content = output_file.read_text()
assert "<html>" in html_content
assert "Repository Health Report" in html_content
def test_health_display(self, sample_git_repo):
"""Test health command display output."""
runner = CliRunner()
result = runner.invoke(health, [str(sample_git_repo)])
assert result.exit_code == 0
assert "Repository Health" in result.output or "Bus Factor" in result.output
def test_analyze_with_extensions(self, sample_git_repo):
"""Test analyze with file extension filter."""
runner = CliRunner()
result = runner.invoke(
analyze,
[str(sample_git_repo), "--extensions", "py", "--json"]
)
assert result.exit_code == 0
output = json.loads(result.output)
assert output["files_analyzed"] >= 0
def test_analyze_with_depth(self, sample_git_repo):
"""Test analyze with commit depth limit."""
runner = CliRunner()
result = runner.invoke(
analyze,
[str(sample_git_repo), "--depth", "2", "--json"]
)
assert result.exit_code == 0
output = json.loads(result.output)
assert "files_analyzed" in output
class TestRepoHealthCLI:
"""Unit tests for RepoHealthCLI class."""
def test_cli_initialization(self):
"""Test CLI class initialization."""
from repohealth.cli.cli import RepoHealthCLI
cli = RepoHealthCLI()
assert cli.terminal_reporter is not None
assert cli.json_reporter is not None
assert cli.html_reporter is not None
def test_analyze_repository_result_structure(self, sample_git_repo):
"""Test that analyze produces valid result structure."""
from repohealth.cli.cli import RepoHealthCLI
cli = RepoHealthCLI()
result = cli.analyze_repository(str(sample_git_repo))
assert result.repository_path is not None
assert isinstance(result.files_analyzed, int)
assert isinstance(result.total_commits, int)
assert isinstance(result.unique_authors, int)
assert isinstance(result.overall_bus_factor, float)
assert result.files is not None
assert result.risk_summary is not None
def test_analyze_repository_min_commits(self, sample_git_repo):
"""Test analyze with min_commits filter."""
from repohealth.cli.cli import RepoHealthCLI
cli = RepoHealthCLI()
result_all = cli.analyze_repository(
str(sample_git_repo),
min_commits=1
)
result_filtered = cli.analyze_repository(
str(sample_git_repo),
min_commits=100
)
assert result_all.files_analyzed >= result_filtered.files_analyzed