From 3d41fb707c5f6b01a124b85cf3ae800d350478bd Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Thu, 29 Jan 2026 23:13:48 +0000 Subject: [PATCH] Add fixer and rule tests --- tests/test_fixers.py | 220 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 tests/test_fixers.py diff --git a/tests/test_fixers.py b/tests/test_fixers.py new file mode 100644 index 0000000..e611fb0 --- /dev/null +++ b/tests/test_fixers.py @@ -0,0 +1,220 @@ +"""Tests for code fixers.""" + +import pytest +from pathlib import Path + +from src.analyzers.base import SeverityLevel, FindingCategory +from src.fixers import ( + SQLInjectionFixer, + EvalUsageFixer, + ExceptionSwallowFixer, + MagicNumberFixer, + RedundantOperationFixer, +) + + +class TestSQLInjectionFixer: + """Tests for SQL injection fixer.""" + + def setup_method(self): + self.fixer = SQLInjectionFixer() + + def test_fixes_sql_injection(self): + code = 'cursor.execute("SELECT * FROM users WHERE name = \'" + user_input + "\'")' + finding = self._create_finding() + tree = self._parse_code(code) + result = self.fixer.fix(code, finding, tree) + assert "?" in result or '"' in result + + def _create_finding(self): + from src.analyzers.base import Finding + return Finding( + rule_id="security.sql_injection", + rule_name="SQL Injection Detection", + severity=SeverityLevel.CRITICAL, + category=FindingCategory.SECURITY, + message="SQL injection detected", + suggestion="Use parameterized queries", + file_path=Path("test.py"), + line_number=1, + column=0, + ) + + def _parse_code(self, code): + from src.analyzers import PythonParser + parser = PythonParser() + return parser.parse(code) + + +class TestEvalUsageFixer: + """Tests for eval/exec fixer.""" + + def setup_method(self): + self.fixer = EvalUsageFixer() + + def test_comments_out_eval(self): + code = 'result = eval(user_input)' + finding = self._create_finding() + tree = self._parse_code(code) + result = self.fixer.fix(code, finding, tree) + assert "# eval(" in result + + def _create_finding(self): + from src.analyzers.base import Finding + return Finding( + rule_id="security.eval_usage", + rule_name="Eval Usage Detection", + severity=SeverityLevel.CRITICAL, + category=FindingCategory.SECURITY, + message="eval detected", + suggestion="Avoid eval", + file_path=Path("test.py"), + line_number=1, + column=0, + ) + + def _parse_code(self, code): + from src.analyzers import PythonParser + parser = PythonParser() + return parser.parse(code) + + +class TestExceptionSwallowFixer: + """Tests for exception swallowing fixer.""" + + def setup_method(self): + self.fixer = ExceptionSwallowFixer() + + def test_adds_exception_logging(self): + code = """try: + dangerous() +except: + pass +""" + finding = self._create_finding() + tree = self._parse_code(code) + result = self.fixer.fix(code, finding, tree) + assert "logger.error" in result or "Exception as e" in result + + def _create_finding(self): + from src.analyzers.base import Finding + return Finding( + rule_id="antipattern.exception_swallow", + rule_name="Exception Swallow Detection", + severity=SeverityLevel.MEDIUM, + category=FindingCategory.ANTIPATTERN, + message="Exception swallowing detected", + suggestion="Log the exception", + file_path=Path("test.py"), + line_number=2, + column=0, + ) + + def _parse_code(self, code): + from src.analyzers import PythonParser + parser = PythonParser() + return parser.parse(code) + + +class TestMagicNumberFixer: + """Tests for magic number fixer.""" + + def setup_method(self): + self.fixer = MagicNumberFixer() + + def test_replaces_magic_number(self): + code = "result = 42" + finding = self._create_finding() + tree = self._parse_code(code) + result = self.fixer.fix(code, finding, tree) + assert "MAGIC_NUMBER_42" in result + + def _create_finding(self): + from src.analyzers.base import Finding + return Finding( + rule_id="antipattern.magic_number", + rule_name="Magic Number Detection", + severity=SeverityLevel.LOW, + category=FindingCategory.ANTIPATTERN, + message="Magic number detected", + suggestion="Define as constant", + file_path=Path("test.py"), + line_number=1, + column=0, + ) + + def _parse_code(self, code): + from src.analyzers import PythonParser + parser = PythonParser() + return parser.parse(code) + + +class TestRedundantOperationFixer: + """Tests for redundant operation fixer.""" + + def setup_method(self): + self.fixer = RedundantOperationFixer() + + def test_removes_redundant_list_call(self): + code = "result = list(list(my_list))" + finding = self._create_finding() + tree = self._parse_code(code) + result = self.fixer.fix(code, finding, tree) + assert "list(list(" not in result + + def _create_finding(self): + from src.analyzers.base import Finding + return Finding( + rule_id="performance.redundant_operation", + rule_name="Redundant Operation Detection", + severity=SeverityLevel.LOW, + category=FindingCategory.PERFORMANCE, + message="Redundant operation detected", + suggestion="Remove redundant call", + file_path=Path("test.py"), + line_number=1, + column=0, + ) + + def _parse_code(self, code): + from src.analyzers import PythonParser + parser = PythonParser() + return parser.parse(code) + + +class TestFixerRegistry: + """Tests for fixer registry.""" + + def test_get_fixer_returns_correct_fixer(self): + from src.fixers import FixerRegistry + registry = FixerRegistry() + fixer = registry.get_fixer("security.sql_injection") + assert fixer is not None + assert isinstance(fixer, SQLInjectionFixer) + + def test_get_fixer_returns_none_for_unknown_rule(self): + from src.fixers import FixerRegistry + registry = FixerRegistry() + fixer = registry.get_fixer("unknown.rule_id") + assert fixer is None + + def test_can_fix_checks_correctly(self): + from src.fixers import FixerRegistry + from src.analyzers.base import Finding + registry = FixerRegistry() + + finding = Finding( + rule_id="security.sql_injection", + rule_name="Test", + severity=SeverityLevel.CRITICAL, + category=FindingCategory.SECURITY, + message="Test", + suggestion="Test", + file_path=Path("test.py"), + line_number=1, + column=0, + ) + assert registry.can_fix(finding) is True + + finding.rule_id = "unknown.rule" + assert registry.can_fix(finding) is False