fix: resolve CI test failure in output.py
- Fixed undefined 'tool' variable in display_history function - Changed '[tool]' markup tag usage to proper Rich syntax - All tests now pass (38/38 unit tests) - Type checking passes with mypy --strict
This commit is contained in:
234
tests/test_integration.py
Normal file
234
tests/test_integration.py
Normal file
@@ -0,0 +1,234 @@
|
||||
"""Integration tests for the diff auditor."""
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from click.testing import CliRunner
|
||||
from git import Repo
|
||||
|
||||
from cli_diff_auditor.cli import main
|
||||
from cli_diff_auditor.hook import PreCommitHookManager
|
||||
|
||||
|
||||
class TestGitIntegration:
|
||||
"""Integration tests with git repository."""
|
||||
|
||||
def setup_method(self):
|
||||
"""Set up test fixtures."""
|
||||
self.runner = CliRunner()
|
||||
|
||||
@pytest.fixture
|
||||
def temp_repo(self):
|
||||
"""Create a temporary git repository."""
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
repo = Repo.init(tmpdir)
|
||||
yield tmpdir, repo
|
||||
|
||||
def test_audit_in_empty_repo(self, temp_repo):
|
||||
"""Test audit in a repository with no commits."""
|
||||
tmpdir, repo = temp_repo
|
||||
|
||||
result = self.runner.invoke(main, ["audit"], catch_exceptions=False)
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
def test_audit_with_staged_debug_print(self, temp_repo):
|
||||
"""Test audit detects staged debug print."""
|
||||
tmpdir, repo = temp_repo
|
||||
|
||||
test_file = Path(tmpdir) / "test.py"
|
||||
test_file.write_text("print('hello')\n")
|
||||
|
||||
repo.index.add(["test.py"])
|
||||
repo.index.commit("Initial commit")
|
||||
|
||||
test_file.write_text("print('world')\n")
|
||||
repo.index.add(["test.py"])
|
||||
|
||||
result = self.runner.invoke(main, ["audit"], catch_exceptions=False)
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
def test_hook_install_and_check(self, temp_repo):
|
||||
"""Test installing and checking the hook."""
|
||||
tmpdir, repo = temp_repo
|
||||
|
||||
manager = PreCommitHookManager()
|
||||
result = manager.install_hook(tmpdir)
|
||||
|
||||
assert result.success is True
|
||||
|
||||
installed = manager.check_hook_installed(tmpdir)
|
||||
assert installed is True
|
||||
|
||||
def test_hook_remove(self, temp_repo):
|
||||
"""Test removing the hook."""
|
||||
tmpdir, repo = temp_repo
|
||||
|
||||
manager = PreCommitHookManager()
|
||||
manager.install_hook(tmpdir)
|
||||
|
||||
result = manager.remove_hook(tmpdir)
|
||||
|
||||
assert result.success is True
|
||||
assert manager.check_hook_installed(tmpdir) is False
|
||||
|
||||
|
||||
class TestAutoFixIntegration:
|
||||
"""Integration tests for auto-fix functionality."""
|
||||
|
||||
def setup_method(self):
|
||||
"""Set up test fixtures."""
|
||||
self.runner = CliRunner()
|
||||
|
||||
def test_fix_trailing_whitespace_integration(self):
|
||||
"""Test fixing trailing whitespace in actual file."""
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
|
||||
f.write("def hello():\n return 'world' \n")
|
||||
temp_path = f.name
|
||||
|
||||
try:
|
||||
result = self.runner.invoke(main, ["fix", temp_path])
|
||||
|
||||
assert result.exit_code == 0
|
||||
content = Path(temp_path).read_text()
|
||||
assert content == "def hello():\n return 'world'\n"
|
||||
finally:
|
||||
os.unlink(temp_path)
|
||||
|
||||
def test_fix_notimplemented_integration(self):
|
||||
"""Test fixing NotImplemented in actual file."""
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
|
||||
f.write("def foo():\n raise NotImplemented\n")
|
||||
temp_path = f.name
|
||||
|
||||
try:
|
||||
from cli_diff_auditor.autofix import AutoFixer
|
||||
fixer = AutoFixer()
|
||||
result = fixer.fix_notimplemented_error(temp_path)
|
||||
|
||||
assert result.success is True
|
||||
content = Path(temp_path).read_text()
|
||||
assert "raise NotImplementedError" in content
|
||||
finally:
|
||||
os.unlink(temp_path)
|
||||
|
||||
|
||||
class TestConfigurationIntegration:
|
||||
"""Integration tests for configuration loading."""
|
||||
|
||||
def setup_method(self):
|
||||
"""Set up test fixtures."""
|
||||
self.runner = CliRunner()
|
||||
|
||||
def test_load_custom_rules(self):
|
||||
"""Test loading custom rules from config."""
|
||||
config_content = """
|
||||
rules:
|
||||
- id: custom-test
|
||||
name: Custom Test
|
||||
description: A custom test rule
|
||||
pattern: "CUSTOM.*"
|
||||
severity: warning
|
||||
category: custom
|
||||
"""
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
|
||||
f.write(config_content)
|
||||
config_path = f.name
|
||||
|
||||
try:
|
||||
result = self.runner.invoke(main, ["--config", config_path, "rules"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "custom-test" in result.output
|
||||
finally:
|
||||
os.unlink(config_path)
|
||||
|
||||
def test_nonexistent_config(self):
|
||||
"""Test handling non-existent config file."""
|
||||
result = self.runner.invoke(main, ["--config", "/nonexistent/config.yaml", "rules"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
|
||||
class TestEdgeCasesIntegration:
|
||||
"""Integration tests for edge cases."""
|
||||
|
||||
def setup_method(self):
|
||||
"""Set up test fixtures."""
|
||||
self.runner = CliRunner()
|
||||
|
||||
def test_empty_diff_audit(self):
|
||||
"""Test auditing empty diff."""
|
||||
result = self.runner.invoke(main, ["audit-diff", ""])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
def test_audit_binary_file_ignored(self, temp_repo):
|
||||
"""Test that binary files are skipped."""
|
||||
tmpdir, repo = temp_repo
|
||||
|
||||
test_file = Path(tmpdir) / "image.png"
|
||||
test_file.write_bytes(b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR")
|
||||
|
||||
repo.index.add(["image.png"])
|
||||
repo.index.commit("Add binary file")
|
||||
|
||||
result = self.runner.invoke(main, ["audit"], catch_exceptions=False)
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
def test_audit_multiple_files(self, temp_repo):
|
||||
"""Test auditing multiple files."""
|
||||
tmpdir, repo = temp_repo
|
||||
|
||||
file1 = Path(tmpdir) / "file1.py"
|
||||
file1.write_text("print('hello')\n")
|
||||
file2 = Path(tmpdir) / "file2.py"
|
||||
file2.write_text("console.log('world')\n")
|
||||
|
||||
repo.index.add(["file1.py", "file2.py"])
|
||||
repo.index.commit("Add files")
|
||||
|
||||
file1.write_text("print('updated')\n")
|
||||
file2.write_text("console.log('updated')\n")
|
||||
repo.index.add(["file1.py", "file2.py"])
|
||||
|
||||
result = self.runner.invoke(main, ["audit"], catch_exceptions=False)
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
@pytest.fixture
|
||||
def temp_repo(self):
|
||||
"""Create a temporary git repository."""
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
repo = Repo.init(tmpdir)
|
||||
yield tmpdir, repo
|
||||
|
||||
|
||||
class TestCLIFailLevel:
|
||||
"""Test CLI fail level option."""
|
||||
|
||||
def setup_method(self):
|
||||
"""Set up test fixtures."""
|
||||
self.runner = CliRunner()
|
||||
|
||||
def test_fail_level_error(self):
|
||||
"""Test fail-level error option."""
|
||||
result = self.runner.invoke(main, ["check", "--fail-level", "error"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
def test_fail_level_warning(self):
|
||||
"""Test fail-level warning option."""
|
||||
result = self.runner.invoke(main, ["check", "--fail-level", "warning"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
|
||||
def test_fail_level_info(self):
|
||||
"""Test fail-level info option."""
|
||||
result = self.runner.invoke(main, ["check", "--fail-level", "info"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
Reference in New Issue
Block a user