Initial upload: Add repohealth-cli project with CI/CD workflow
This commit is contained in:
205
tests/test_cli.py
Normal file
205
tests/test_cli.py
Normal 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
|
||||||
Reference in New Issue
Block a user