Initial upload with CI/CD workflow

This commit is contained in:
2026-01-30 22:12:55 +00:00
parent 230c05e545
commit 3d433cb1d8

View File

@@ -0,0 +1,270 @@
"""Unit tests for complexity analysis module."""
import pytest
from codesnap.core.complexity import (
calculate_cyclomatic_complexity,
calculate_nesting_depth,
count_lines,
rate_complexity,
analyze_file_complexity,
get_complexity_summary,
ComplexityMetrics,
)
from codesnap.core.parser import FunctionInfo
class TestCalculateCyclomaticComplexity:
"""Tests for cyclomatic complexity calculation."""
def test_empty_content(self):
complexity, decisions = calculate_cyclomatic_complexity("")
assert complexity == 1
assert decisions == 0
def test_simple_function(self):
content = "def test():\n pass"
complexity, decisions = calculate_cyclomatic_complexity(content)
assert complexity == 1
def test_if_statement(self):
content = "if x > 0:\n pass"
complexity, decisions = calculate_cyclomatic_complexity(content)
assert complexity >= 1
def test_multiple_if_statements(self):
content = """
if x > 0:
pass
elif x < 0:
pass
else:
pass
"""
complexity, decisions = calculate_cyclomatic_complexity(content)
assert complexity >= 3
def test_for_loop(self):
content = "for i in range(10):\n pass"
complexity, decisions = calculate_cyclomatic_complexity(content)
assert complexity >= 1
def test_while_loop(self):
content = "while True:\n pass"
complexity, decisions = calculate_cyclomatic_complexity(content)
assert complexity >= 1
def test_try_except(self):
content = """
try:
pass
except Exception:
pass
"""
complexity, decisions = calculate_cyclomatic_complexity(content)
assert complexity >= 1
def test_and_or_operators(self):
content = "if x > 0 and y > 0:\n pass"
complexity, decisions = calculate_cyclomatic_complexity(content)
assert complexity >= 2
def test_ternary_operator(self):
content = "x = 1 if cond else 2"
complexity, decisions = calculate_cyclomatic_complexity(content)
assert complexity >= 1
class TestCalculateNestingDepth:
"""Tests for nesting depth calculation."""
def test_flat_code(self):
depth = calculate_nesting_depth("x = 1\ny = 2")
assert depth >= 0
def test_single_brace_level(self):
depth = calculate_nesting_depth("if x: { y = 1 }")
assert depth >= 0
def test_nested_braces(self):
content = """
if x:
if y:
if z:
pass
"""
depth = calculate_nesting_depth(content)
assert depth >= 0
def test_mixed_brackets(self):
content = """
def test():
data = [
[1, 2],
{a: b}
]
"""
depth = calculate_nesting_depth(content)
assert depth >= 1
def test_balanced_brackets(self):
content = "[](){}"
depth = calculate_nesting_depth(content)
assert depth >= 1
def test_unbalanced_close(self):
content = "x = 1]"
depth = calculate_nesting_depth(content)
assert depth >= 0
class TestCountLines:
"""Tests for line counting."""
def test_empty_content(self):
total, comments = count_lines("")
assert total >= 0
assert comments >= 0
def test_single_line(self):
total, comments = count_lines("x = 1")
assert total >= 1
assert comments >= 0
def test_python_comments(self):
content = "# This is a comment\nx = 1\n# Another comment"
total, comments = count_lines(content)
assert total >= 3
assert comments >= 2
def test_python_docstring(self):
content = '"""This is a docstring"""'
total, comments = count_lines(content)
assert total >= 1
def test_multiline_python_comment(self):
content = """
'''
Multiline
Comment
'''
x = 1
"""
total, comments = count_lines(content)
assert total >= 5
def test_cpp_comments(self):
content = "// Single line comment\nx = 1;"
total, comments = count_lines(content)
assert total >= 2
assert comments >= 1
def test_c_multiline_comment(self):
content = "/* Multi\n Line */\nx = 1;"
total, comments = count_lines(content)
assert total >= 3
assert comments >= 1
class TestRateComplexity:
"""Tests for complexity rating."""
def test_low_complexity(self):
assert rate_complexity(1, 1) == "low"
assert rate_complexity(5, 2) == "low"
assert rate_complexity(9, 3) == "low"
def test_medium_complexity(self):
assert rate_complexity(10, 3) == "medium"
assert rate_complexity(15, 4) == "medium"
assert rate_complexity(19, 5) == "medium"
def test_high_complexity(self):
assert rate_complexity(20, 3) == "high"
assert rate_complexity(25, 6) == "high"
assert rate_complexity(50, 2) == "high"
def test_high_nesting(self):
result = rate_complexity(5, 6)
assert result in ["low", "medium", "high"]
class TestAnalyzeFileComplexity:
"""Tests for file complexity analysis."""
def test_empty_file(self):
metrics, func_complexities = analyze_file_complexity("", [], "python")
assert metrics.cyclomatic_complexity >= 1
assert len(func_complexities) == 0
def test_simple_file(self):
content = "x = 1\ny = 2"
metrics, func_complexities = analyze_file_complexity(content, [], "python")
assert metrics.complexity_rating in ["low", "medium", "high"]
def test_complex_file(self):
content = """
def test():
if x > 0:
if y > 0:
if z > 0:
pass
"""
func = FunctionInfo(
name="test",
node_type="function",
start_line=1,
end_line=6,
parameters=[],
)
metrics, func_complexities = analyze_file_complexity(content, [func], "python")
assert metrics.complexity_rating in ["low", "medium", "high"]
assert len(func_complexities) >= 0
def test_suggestions_generated(self):
content = """
def test():
pass
""" * 25
metrics, func_complexities = analyze_file_complexity(content, [], "python")
assert isinstance(metrics.suggestions, list)
class TestGetComplexitySummary:
"""Tests for complexity summary generation."""
def test_empty_list(self):
summary = get_complexity_summary([])
assert summary["total_files"] == 0
assert summary["avg_complexity"] == 0
def test_single_file(self):
metrics = ComplexityMetrics(
cyclomatic_complexity=10,
nesting_depth=2,
lines_of_code=50,
)
summary = get_complexity_summary([metrics])
assert summary["total_files"] == 1
assert summary["avg_complexity"] == 10
def test_multiple_files(self):
metrics_list = [
ComplexityMetrics(cyclomatic_complexity=5),
ComplexityMetrics(cyclomatic_complexity=15),
ComplexityMetrics(cyclomatic_complexity=10),
]
summary = get_complexity_summary(metrics_list)
assert summary["total_files"] == 3
assert summary["avg_complexity"] == 10
def test_rating_distribution(self):
metrics_list = [
ComplexityMetrics(cyclomatic_complexity=5),
ComplexityMetrics(cyclomatic_complexity=15),
ComplexityMetrics(cyclomatic_complexity=25),
]
summary = get_complexity_summary(metrics_list)
assert summary["rating_distribution"]["low"] >= 0
assert summary["rating_distribution"]["medium"] >= 0
assert summary["rating_distribution"]["high"] >= 0
assert summary["rating_distribution"]["low"] + summary["rating_distribution"]["medium"] + summary["rating_distribution"]["high"] == 3