From 792b197ca3d5de6c0bc3cb5644118e0d5777e1b2 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Thu, 5 Feb 2026 17:14:10 +0000 Subject: [PATCH] Initial upload: Add repohealth-cli project with CI/CD workflow --- tests/test_cli.py | 205 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 tests/test_cli.py diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 0000000..1f24c52 --- /dev/null +++ b/tests/test_cli.py @@ -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 "" 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