fix: resolve CI issues - push complete implementation with tests
This commit is contained in:
@@ -1,5 +1,3 @@
|
|||||||
"""Tests for the IssueDetector module."""
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -9,10 +7,7 @@ from gdiffer.issue_detector import detect_issues, suggest_improvements
|
|||||||
|
|
||||||
|
|
||||||
class TestIssueDetector:
|
class TestIssueDetector:
|
||||||
"""Tests for IssueDetector class."""
|
|
||||||
|
|
||||||
def test_detect_sql_injection(self, issue_detector):
|
def test_detect_sql_injection(self, issue_detector):
|
||||||
"""Test detecting SQL injection patterns."""
|
|
||||||
code = 'query = "SELECT * FROM users WHERE name = \'" + username + "\'"'
|
code = 'query = "SELECT * FROM users WHERE name = \'" + username + "\'"'
|
||||||
issues = issue_detector.detect_issues(code, "python")
|
issues = issue_detector.detect_issues(code, "python")
|
||||||
|
|
||||||
@@ -24,7 +19,6 @@ class TestIssueDetector:
|
|||||||
assert "SQL" in issue.title
|
assert "SQL" in issue.title
|
||||||
|
|
||||||
def test_detect_xss(self, issue_detector):
|
def test_detect_xss(self, issue_detector):
|
||||||
"""Test detecting XSS patterns."""
|
|
||||||
code = "element.innerHTML = userInput"
|
code = "element.innerHTML = userInput"
|
||||||
issues = issue_detector.detect_issues(code, "javascript")
|
issues = issue_detector.detect_issues(code, "javascript")
|
||||||
|
|
||||||
@@ -32,7 +26,6 @@ class TestIssueDetector:
|
|||||||
assert len(xss_issues) > 0
|
assert len(xss_issues) > 0
|
||||||
|
|
||||||
def test_detect_command_injection(self, issue_detector):
|
def test_detect_command_injection(self, issue_detector):
|
||||||
"""Test detecting command injection patterns."""
|
|
||||||
code = "os.system('rm -rf /tmp/' + user_input)"
|
code = "os.system('rm -rf /tmp/' + user_input)"
|
||||||
issues = issue_detector.detect_issues(code, "python")
|
issues = issue_detector.detect_issues(code, "python")
|
||||||
|
|
||||||
@@ -40,7 +33,6 @@ class TestIssueDetector:
|
|||||||
assert len(cmd_issues) > 0
|
assert len(cmd_issues) > 0
|
||||||
|
|
||||||
def test_detect_eval_usage(self, issue_detector):
|
def test_detect_eval_usage(self, issue_detector):
|
||||||
"""Test detecting eval usage."""
|
|
||||||
code = "result = eval(user_code)"
|
code = "result = eval(user_code)"
|
||||||
issues = issue_detector.detect_issues(code, "python")
|
issues = issue_detector.detect_issues(code, "python")
|
||||||
|
|
||||||
@@ -48,7 +40,6 @@ class TestIssueDetector:
|
|||||||
assert len(eval_issues) > 0
|
assert len(eval_issues) > 0
|
||||||
|
|
||||||
def test_detect_hardcoded_secret(self, issue_detector):
|
def test_detect_hardcoded_secret(self, issue_detector):
|
||||||
"""Test detecting hardcoded secrets."""
|
|
||||||
code = 'api_key = "sk-1234567890abcdef"'
|
code = 'api_key = "sk-1234567890abcdef"'
|
||||||
issues = issue_detector.detect_issues(code, "python")
|
issues = issue_detector.detect_issues(code, "python")
|
||||||
|
|
||||||
@@ -56,7 +47,6 @@ class TestIssueDetector:
|
|||||||
assert len(secret_issues) > 0
|
assert len(secret_issues) > 0
|
||||||
|
|
||||||
def test_detect_insecure_http(self, issue_detector):
|
def test_detect_insecure_http(self, issue_detector):
|
||||||
"""Test detecting insecure HTTP usage."""
|
|
||||||
code = 'response = requests.get("http://api.example.com")'
|
code = 'response = requests.get("http://api.example.com")'
|
||||||
issues = issue_detector.detect_issues(code, "python")
|
issues = issue_detector.detect_issues(code, "python")
|
||||||
|
|
||||||
@@ -64,7 +54,6 @@ class TestIssueDetector:
|
|||||||
assert len(http_issues) > 0
|
assert len(http_issues) > 0
|
||||||
|
|
||||||
def test_detect_weak_random(self, issue_detector):
|
def test_detect_weak_random(self, issue_detector):
|
||||||
"""Test detecting weak random number generation."""
|
|
||||||
code = "token = random.randint(0, 9999)"
|
code = "token = random.randint(0, 9999)"
|
||||||
issues = issue_detector.detect_issues(code, "python")
|
issues = issue_detector.detect_issues(code, "python")
|
||||||
|
|
||||||
@@ -72,7 +61,6 @@ class TestIssueDetector:
|
|||||||
assert len(crypto_issues) > 0
|
assert len(crypto_issues) > 0
|
||||||
|
|
||||||
def test_detect_bare_except(self, issue_detector):
|
def test_detect_bare_except(self, issue_detector):
|
||||||
"""Test detecting bare except clauses."""
|
|
||||||
code = """try:
|
code = """try:
|
||||||
dangerous_operation()
|
dangerous_operation()
|
||||||
except:
|
except:
|
||||||
@@ -83,7 +71,6 @@ except:
|
|||||||
assert len(bare_except) > 0
|
assert len(bare_except) > 0
|
||||||
|
|
||||||
def test_detect_debug_statements(self, issue_detector):
|
def test_detect_debug_statements(self, issue_detector):
|
||||||
"""Test detecting debug statements."""
|
|
||||||
code = "print('Debug: value =', value)"
|
code = "print('Debug: value =', value)"
|
||||||
issues = issue_detector.detect_issues(code, "python")
|
issues = issue_detector.detect_issues(code, "python")
|
||||||
|
|
||||||
@@ -91,7 +78,6 @@ except:
|
|||||||
assert len(debug_issues) > 0
|
assert len(debug_issues) > 0
|
||||||
|
|
||||||
def test_detect_todo_comments(self, issue_detector):
|
def test_detect_todo_comments(self, issue_detector):
|
||||||
"""Test detecting TODO comments."""
|
|
||||||
code = "# TODO: Fix this later"
|
code = "# TODO: Fix this later"
|
||||||
issues = issue_detector.detect_issues(code, "python")
|
issues = issue_detector.detect_issues(code, "python")
|
||||||
|
|
||||||
@@ -99,7 +85,6 @@ except:
|
|||||||
assert len(todo_issues) > 0
|
assert len(todo_issues) > 0
|
||||||
|
|
||||||
def test_detect_no_issues_in_clean_code(self, issue_detector):
|
def test_detect_no_issues_in_clean_code(self, issue_detector):
|
||||||
"""Test that clean code produces no issues."""
|
|
||||||
code = """def calculate_sum(a, b):
|
code = """def calculate_sum(a, b):
|
||||||
result = a + b
|
result = a + b
|
||||||
return result
|
return result
|
||||||
@@ -109,7 +94,6 @@ except:
|
|||||||
assert len(issues) == 0
|
assert len(issues) == 0
|
||||||
|
|
||||||
def test_issue_line_number(self, issue_detector):
|
def test_issue_line_number(self, issue_detector):
|
||||||
"""Test that issue has correct line number."""
|
|
||||||
code = """line1 = 1
|
code = """line1 = 1
|
||||||
line2 = 2
|
line2 = 2
|
||||||
password = "secret"
|
password = "secret"
|
||||||
@@ -121,7 +105,6 @@ password = "secret"
|
|||||||
assert secret_issues[0].line == 3
|
assert secret_issues[0].line == 3
|
||||||
|
|
||||||
def test_detect_diff_issues(self, issue_detector, sql_injection_diff):
|
def test_detect_diff_issues(self, issue_detector, sql_injection_diff):
|
||||||
"""Test detecting issues in diff."""
|
|
||||||
old_code = "x = 1"
|
old_code = "x = 1"
|
||||||
new_code = "x = 1\nquery = 'SELECT * FROM users WHERE id = ' + user_id"
|
new_code = "x = 1\nquery = 'SELECT * FROM users WHERE id = ' + user_id"
|
||||||
|
|
||||||
@@ -130,7 +113,6 @@ password = "secret"
|
|||||||
assert isinstance(issues, list)
|
assert isinstance(issues, list)
|
||||||
|
|
||||||
def test_suggest_improvements(self, issue_detector):
|
def test_suggest_improvements(self, issue_detector):
|
||||||
"""Test suggesting improvements."""
|
|
||||||
code = 'query = "SELECT * FROM users WHERE id = " + user_id'
|
code = 'query = "SELECT * FROM users WHERE id = " + user_id'
|
||||||
suggestions = issue_detector.suggest_improvements(code, "python")
|
suggestions = issue_detector.suggest_improvements(code, "python")
|
||||||
|
|
||||||
@@ -138,7 +120,6 @@ password = "secret"
|
|||||||
assert len(suggestions) > 0
|
assert len(suggestions) > 0
|
||||||
|
|
||||||
def test_check_security_patterns_only(self, issue_detector):
|
def test_check_security_patterns_only(self, issue_detector):
|
||||||
"""Test checking only security patterns."""
|
|
||||||
code = """password = "secret"
|
code = """password = "secret"
|
||||||
query = "SELECT * FROM users"
|
query = "SELECT * FROM users"
|
||||||
"""
|
"""
|
||||||
@@ -147,7 +128,6 @@ query = "SELECT * FROM users"
|
|||||||
assert all(i.severity in ['critical', 'high', 'medium'] for i in issues)
|
assert all(i.severity in ['critical', 'high', 'medium'] for i in issues)
|
||||||
|
|
||||||
def test_check_code_quality_only(self, issue_detector):
|
def test_check_code_quality_only(self, issue_detector):
|
||||||
"""Test checking only code quality patterns."""
|
|
||||||
code = """# TODO: fix later
|
code = """# TODO: fix later
|
||||||
print("debug")
|
print("debug")
|
||||||
"""
|
"""
|
||||||
@@ -156,7 +136,6 @@ print("debug")
|
|||||||
assert all(i.severity == 'low' for i in issues)
|
assert all(i.severity == 'low' for i in issues)
|
||||||
|
|
||||||
def test_issue_has_suggestion(self, issue_detector):
|
def test_issue_has_suggestion(self, issue_detector):
|
||||||
"""Test that issues have suggestions."""
|
|
||||||
code = 'password = "secret"'
|
code = 'password = "secret"'
|
||||||
issues = issue_detector.detect_issues(code, "python")
|
issues = issue_detector.detect_issues(code, "python")
|
||||||
|
|
||||||
@@ -165,49 +144,36 @@ print("debug")
|
|||||||
|
|
||||||
|
|
||||||
class TestDetectIssuesFunction:
|
class TestDetectIssuesFunction:
|
||||||
"""Tests for the detect_issues convenience function."""
|
|
||||||
|
|
||||||
def test_detect_issues_function(self):
|
def test_detect_issues_function(self):
|
||||||
"""Test detect_issues convenience function."""
|
|
||||||
issues = detect_issues('password = "secret"', "python")
|
issues = detect_issues('password = "secret"', "python")
|
||||||
assert isinstance(issues, list)
|
assert isinstance(issues, list)
|
||||||
|
|
||||||
def test_detect_issues_empty(self):
|
def test_detect_issues_empty(self):
|
||||||
"""Test detect_issues with clean code."""
|
|
||||||
issues = detect_issues("def test():\n return 1", "python")
|
issues = detect_issues("def test():\n return 1", "python")
|
||||||
assert issues == []
|
assert issues == []
|
||||||
|
|
||||||
def test_detect_issues_with_pass(self):
|
def test_detect_issues_with_pass(self):
|
||||||
"""Test detect_issues detects pass statement."""
|
|
||||||
issues = detect_issues("def test(): pass", "python")
|
issues = detect_issues("def test(): pass", "python")
|
||||||
pass_issues = [i for i in issues if i.type == "empty_block"]
|
pass_issues = [i for i in issues if i.type == "empty_block"]
|
||||||
assert len(pass_issues) > 0
|
assert len(pass_issues) > 0
|
||||||
|
|
||||||
|
|
||||||
class TestSuggestImprovementsFunction:
|
class TestSuggestImprovementsFunction:
|
||||||
"""Tests for the suggest_improvements convenience function."""
|
|
||||||
|
|
||||||
def test_suggest_improvements_function(self):
|
def test_suggest_improvements_function(self):
|
||||||
"""Test suggest_improvements convenience function."""
|
|
||||||
suggestions = suggest_improvements('password = "secret"', "python")
|
suggestions = suggest_improvements('password = "secret"', "python")
|
||||||
assert isinstance(suggestions, list)
|
assert isinstance(suggestions, list)
|
||||||
|
|
||||||
def test_suggest_improvements_clean_code(self):
|
def test_suggest_improvements_clean_code(self):
|
||||||
"""Test suggest_improvements with clean code."""
|
|
||||||
suggestions = suggest_improvements("def test():\n return 1", "python")
|
suggestions = suggest_improvements("def test():\n return 1", "python")
|
||||||
assert suggestions == []
|
assert suggestions == []
|
||||||
|
|
||||||
def test_suggest_improvements_with_pass(self):
|
def test_suggest_improvements_with_pass(self):
|
||||||
"""Test suggest_improvements detects pass statement."""
|
|
||||||
suggestions = suggest_improvements("def test(): pass", "python")
|
suggestions = suggest_improvements("def test(): pass", "python")
|
||||||
assert len(suggestions) > 0
|
assert len(suggestions) > 0
|
||||||
|
|
||||||
|
|
||||||
class TestIssueModel:
|
class TestIssueModel:
|
||||||
"""Tests for the Issue dataclass."""
|
|
||||||
|
|
||||||
def test_issue_creation(self):
|
def test_issue_creation(self):
|
||||||
"""Test creating an Issue instance."""
|
|
||||||
from gdiffer.issue_detector import Issue
|
from gdiffer.issue_detector import Issue
|
||||||
|
|
||||||
issue = Issue(
|
issue = Issue(
|
||||||
|
|||||||
Reference in New Issue
Block a user