Files
codebase-knowledge-graph-cli/tests/unit/test_analyzers.py
7000pctAUTO 5aa13df63c
Some checks failed
CI / build (push) Has been cancelled
CI / test (push) Has been cancelled
fix: resolve CI/CD issues - remove unused imports and fix type mismatches
2026-02-02 02:56:08 +00:00

224 lines
7.9 KiB
Python

from pathlib import Path
from src.analyzers.complexity import ComplexityCalculator
from src.analyzers.dependencies import DependencyAnalyzer
from src.graph.builder import GraphBuilder, GraphType, GraphNode, NodeType
from src.parsers.base import Entity, EntityType
class TestComplexityCalculator:
def setup_method(self):
self.calculator = ComplexityCalculator()
def test_simple_function_complexity(self):
entity = Entity(
name="simple_func",
entity_type=EntityType.FUNCTION,
file_path=Path("/test.py"),
start_line=1,
end_line=5,
code="def simple_func():\n pass",
)
result = self.calculator.calculate_for_entity(entity)
assert result["complexity_score"] == 1
assert result["name"] == "simple_func"
def test_function_with_if_statement(self):
entity = Entity(
name="func_with_if",
entity_type=EntityType.FUNCTION,
file_path=Path("/test.py"),
start_line=1,
end_line=10,
code="def func_with_if(x):\n if x > 0:\n return True\n return False",
)
result = self.calculator.calculate_for_entity(entity)
assert result["complexity_score"] == 2
assert result["decision_points"] == 1
def test_function_with_multiple_decision_points(self):
entity = Entity(
name="complex_func",
entity_type=EntityType.FUNCTION,
file_path=Path("/test.py"),
start_line=1,
end_line=20,
code="""def complex_func(x):
if x > 0:
if x > 10:
return "big"
else:
return "small"
elif x < 0:
return "negative"
else:
return "zero"
""",
)
result = self.calculator.calculate_for_entity(entity)
assert result["complexity_score"] >= 4
def test_function_with_loop(self):
entity = Entity(
name="func_with_loop",
entity_type=EntityType.FUNCTION,
file_path=Path("/test.py"),
start_line=1,
end_line=10,
code="def func_with_loop(items):\n for item in items:\n print(item)",
)
result = self.calculator.calculate_for_entity(entity)
assert result["complexity_score"] == 2
def test_method_complexity(self):
entity = Entity(
name="method",
entity_type=EntityType.METHOD,
file_path=Path("/test.py"),
start_line=1,
end_line=8,
code="def process(self, data):\n if data:\n for item in data:\n if item.valid:\n pass",
)
result = self.calculator.calculate_for_entity(entity)
assert result["entity_type"] == "method"
def test_complexity_threshold(self):
assert self.calculator.complexity_threshold == 10
def test_set_complexity_threshold(self):
self.calculator.set_complexity_threshold(15)
assert self.calculator.complexity_threshold == 15
def test_is_complex_flag(self):
entity = Entity(
name="simple",
entity_type=EntityType.FUNCTION,
file_path=Path("/test.py"),
start_line=1,
end_line=5,
code="def simple():\n pass",
)
result = self.calculator.calculate_for_entity(entity)
assert result["is_complex"] is False
def test_high_complexity_flag(self):
entity = Entity(
name="complex",
entity_type=EntityType.FUNCTION,
file_path=Path("/test.py"),
start_line=1,
end_line=30,
code="def complex():\n if True:\n if True:\n if True:\n if True:\n if True:\n if True:\n if True:\n if True:\n if True:\n if True:\n if True:\n pass",
)
result = self.calculator.calculate_for_entity(entity)
assert result["is_complex"] is True
def test_calculate_project_complexity(self):
entities = [
Entity(
name="func1",
entity_type=EntityType.FUNCTION,
file_path=Path("/test.py"),
start_line=1,
end_line=5,
code="def func1():\n pass",
),
Entity(
name="func2",
entity_type=EntityType.FUNCTION,
file_path=Path("/test.py"),
start_line=10,
end_line=20,
code="def func2():\n if True:\n pass",
),
]
report = self.calculator.calculate_project_complexity(entities)
assert report["total_functions"] == 2
assert report["total_cyclomatic_complexity"] >= 2
assert "complexity_distribution" in report
def test_complexity_distribution(self):
entities = [
Entity(
name=f"func{i}",
entity_type=EntityType.FUNCTION,
file_path=Path("/test.py"),
start_line=1,
end_line=5,
code="def func():\n pass",
)
for i in range(10)
]
report = self.calculator.calculate_project_complexity(entities)
assert report["complexity_distribution"]["low"] == 10
class TestDependencyAnalyzer:
def setup_method(self):
self.builder = GraphBuilder(GraphType.DIRECTED)
self.analyzer = DependencyAnalyzer(self.builder)
def test_analyze_empty_graph(self):
report = self.analyzer.analyze()
assert report.total_files == 0
assert report.total_functions == 0
assert report.total_classes == 0
def test_count_entities(self):
file_node = GraphNode(node_id="file1", node_type=NodeType.FILE, name="test.py")
func_node = GraphNode(node_id="func1", node_type=NodeType.FUNCTION, name="test_func")
class_node = GraphNode(node_id="class1", node_type=NodeType.CLASS, name="TestClass")
self.builder.add_node(file_node)
self.builder.add_node(func_node)
self.builder.add_node(class_node)
report = self.analyzer.analyze()
assert report.total_files == 1
assert report.total_functions == 1
assert report.total_classes == 1
def test_get_architecture_layers(self):
file_node = GraphNode(
node_id="controller",
node_type=NodeType.FILE,
name="controller.py",
file_path=Path("/src/ui/controller.py"),
)
self.builder.add_node(file_node)
layers = self.analyzer.get_architecture_layers()
assert "presentation" in layers or "other" in layers
def test_get_file_dependencies(self):
file_node = GraphNode(
node_id="file_test.py",
node_type=NodeType.FILE,
name="test.py",
file_path=Path("/test.py"),
)
self.builder.add_node(file_node)
deps = self.analyzer.get_file_dependencies(Path("/test.py"))
assert isinstance(deps, list)
class TestComplexityReport:
def test_report_creation(self):
from src.analyzers.complexity import ComplexityReport
report = ComplexityReport(file_path=Path("/test.py"))
assert report.file_path == Path("/test.py")
assert report.functions == []
assert report.classes == []
assert report.total_cyclomatic_complexity == 0
def test_average_complexity_calculation(self):
from src.analyzers.complexity import ComplexityReport
report = ComplexityReport(file_path=Path("/test.py"))
report.functions = [
{"complexity_score": 5},
{"complexity_score": 10},
{"complexity_score": 15},
]
expected_avg = (5 + 10 + 15) / 3
actual_avg = sum(f["complexity_score"] for f in report.functions) / len(
report.functions
)
assert actual_avg == expected_avg