From 6ee2f73ae3b0e511e08d70231b85bddb3229f76e Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Tue, 3 Feb 2026 07:03:24 +0000 Subject: [PATCH] Add integration tests and fixtures --- tests/integration/test_cli.py | 210 ++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 tests/integration/test_cli.py diff --git a/tests/integration/test_cli.py b/tests/integration/test_cli.py new file mode 100644 index 0000000..ffff40a --- /dev/null +++ b/tests/integration/test_cli.py @@ -0,0 +1,210 @@ +"""Integration tests for CLI commands.""" + +import json +import tempfile +from pathlib import Path +from unittest.mock import patch + +import pytest +from click.testing import CliRunner + +from vibeguard.cli.main import main +from vibeguard.utils.config import Config + + +def get_runner_with_config(config: Config | None = None): + """Create a CLI runner with custom config.""" + runner = CliRunner() + return runner + + +class TestAnalyzeCommand: + """Tests for analyze command.""" + + def test_analyze_no_files(self, tmp_path): + """Test analyze with no files to scan.""" + runner = CliRunner() + result = runner.invoke(main, ["analyze", str(tmp_path)]) + + assert result.exit_code == 0 + assert "No files found" in result.output + + def test_analyze_single_file(self, tmp_path): + """Test analyzing a single Python file.""" + test_file = tmp_path / "test.py" + test_file.write_text('print("hello")') + + runner = CliRunner() + result = runner.invoke(main, ["analyze", str(tmp_path)]) + + assert result.exit_code == 0 + assert "Found" in result.output + + def test_analyze_with_json_output(self, tmp_path): + """Test analyze with JSON output.""" + test_file = tmp_path / "test.py" + test_file.write_text('print("hello")') + + output_file = tmp_path / "output.json" + + runner = CliRunner() + result = runner.invoke(main, ["analyze", str(tmp_path), "--json"]) + + assert result.exit_code == 0 + + def test_analyze_with_severity_filter(self, tmp_path): + """Test analyze with severity filter.""" + test_file = tmp_path / "test.py" + test_file.write_text('print("hello")') + + runner = CliRunner() + result = runner.invoke(main, ["analyze", str(tmp_path), "--severity", "critical"]) + + assert result.exit_code == 0 + + def test_analyze_exit_zero(self, tmp_path): + """Test analyze with --exit-zero flag.""" + test_file = tmp_path / "test.py" + test_file.write_text('print("hello")') + + runner = CliRunner() + result = runner.invoke(main, ["analyze", str(tmp_path), "--exit-zero"]) + + assert result.exit_code == 0 + + def test_analyze_verbose(self, tmp_path): + """Test analyze with verbose flag.""" + test_file = tmp_path / "test.py" + test_file.write_text('print("hello")') + + runner = CliRunner() + result = runner.invoke(main, ["--verbose", "analyze", str(tmp_path)]) + + assert result.exit_code == 0 + assert "VibeGuard" in result.output + + def test_analyze_file_with_anti_patterns(self, tmp_path): + """Test analyzing a file with anti-patterns.""" + test_file = tmp_path / "test.py" + test_file.write_text(''' +MAGIC_VALUE = "this is a very long magic string that should be detected as anti-pattern" +MAX_RETRIES = 12345 + +def process(): + pass + +try: + x = 1 +except: + pass +''') + + runner = CliRunner() + result = runner.invoke(main, ["analyze", str(tmp_path)]) + + assert result.exit_code == 1 + assert "Issues found" in result.output + + def test_analyze_html_output(self, tmp_path): + """Test analyze with HTML output.""" + test_file = tmp_path / "test.py" + test_file.write_text('print("hello")') + + output_file = tmp_path / "report.html" + + runner = CliRunner() + result = runner.invoke(main, ["analyze", str(tmp_path), "--html", str(output_file)]) + + assert result.exit_code == 0 + assert output_file.exists() + + +class TestInitCommand: + """Tests for init command.""" + + def test_init_creates_config(self, tmp_path): + """Test init creates config file.""" + runner = CliRunner() + result = runner.invoke(main, ["init", "--path", str(tmp_path)]) + + assert result.exit_code == 0 + assert (tmp_path / ".vibeguard.toml").exists() + + def test_init_overwrite_existing(self, tmp_path): + """Test init doesn't overwrite existing config.""" + config_file = tmp_path / ".vibeguard.toml" + config_file.write_text("# existing config") + + runner = CliRunner() + result = runner.invoke(main, ["init", "--path", str(tmp_path)]) + + assert result.exit_code == 0 + assert "already exists" in result.output + + +class TestReportCommand: + """Tests for report command.""" + + def test_report_from_json(self, tmp_path): + """Test generating report from JSON file.""" + input_file = tmp_path / "input.json" + issues = [ + { + "pattern": "TEST001", + "severity": "warning", + "file": "test.py", + "line": 1, + "message": "Test issue", + "suggestion": "Test suggestion", + } + ] + input_file.write_text(json.dumps({"issues": issues})) + + runner = CliRunner() + result = runner.invoke(main, ["report", str(input_file)]) + + assert result.exit_code == 0 + + def test_report_to_html(self, tmp_path): + """Test generating HTML report.""" + input_file = tmp_path / "input.json" + input_file.write_text(json.dumps({"issues": []})) + + output_file = tmp_path / "report.html" + + runner = CliRunner() + result = runner.invoke(main, ["report", str(input_file), "--html", str(output_file)]) + + assert result.exit_code == 0 + + def test_report_empty_issues(self, tmp_path): + """Test report with no issues.""" + input_file = tmp_path / "input.json" + input_file.write_text(json.dumps({"issues": []})) + + runner = CliRunner() + result = runner.invoke(main, ["report", str(input_file)]) + + assert result.exit_code == 0 + assert "No issues" in result.output + + +class TestMainCommand: + """Tests for main command group.""" + + def test_main_help(self): + """Test main help command.""" + runner = CliRunner() + result = runner.invoke(main, ["--help"]) + + assert result.exit_code == 0 + assert "VibeGuard" in result.output + assert "analyze" in result.output + assert "init" in result.output + + def test_main_version(self): + """Test main version output.""" + runner = CliRunner() + result = runner.invoke(main, ["--help"]) + + assert result.exit_code == 0