Skip to main content
Glama
johannhartmann

MCP Code Analysis Server

test_complexity_calculator.py8.8 kB
"""Tests for cyclomatic complexity calculator.""" import tree_sitter import tree_sitter_python as tspython from src.parser.complexity_calculator import ComplexityCalculator class TestComplexityCalculator: """Tests for ComplexityCalculator class.""" def setup_method(self) -> None: """Set up test fixtures.""" self.calculator = ComplexityCalculator() self.language = tree_sitter.Language(tspython.language()) self.parser = tree_sitter.Parser(self.language) def _parse_function(self, code: str) -> tree_sitter.Node: """Parse a function and return its node.""" tree = self.parser.parse(code.encode()) # Find the first function definition for node in tree.root_node.children: if node.type == "function_definition": return node raise ValueError("No function found in code") def test_simple_function(self) -> None: """Test complexity of a simple function.""" code = """ def simple_function(): return 42 """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) assert complexity == 1 def test_single_if_statement(self) -> None: """Test function with single if statement.""" code = """ def function_with_if(x): if x > 0: return True return False """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) assert complexity == 2 # 1 base + 1 if def test_if_else_statement(self) -> None: """Test function with if-else statement.""" code = """ def function_with_if_else(x): if x > 0: return "positive" else: return "non-positive" """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) assert complexity == 2 # 1 base + 1 if (else doesn't add complexity) def test_if_elif_else_statement(self) -> None: """Test function with if-elif-else statement.""" code = """ def function_with_elif(x): if x > 0: return "positive" elif x < 0: return "negative" else: return "zero" """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) assert complexity == 3 # 1 base + 1 if + 1 elif def test_for_loop(self) -> None: """Test function with for loop.""" code = """ def function_with_for(items): total = 0 for item in items: total += item return total """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) assert complexity == 2 # 1 base + 1 for def test_while_loop(self) -> None: """Test function with while loop.""" code = """ def function_with_while(n): count = 0 while n > 0: count += 1 n -= 1 return count """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) assert complexity == 2 # 1 base + 1 while def test_nested_loops(self) -> None: """Test function with nested loops.""" code = """ def function_with_nested_loops(matrix): total = 0 for row in matrix: for value in row: if value > 0: total += value return total """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) assert complexity == 4 # 1 base + 1 for + 1 for + 1 if def test_exception_handling(self) -> None: """Test function with exception handling.""" code = """ def function_with_try_except(x): try: result = 10 / x except ZeroDivisionError: return None except ValueError: return -1 return result """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) assert complexity == 3 # 1 base + 2 except clauses def test_boolean_operators(self) -> None: """Test function with boolean operators.""" code = """ def function_with_boolean_ops(a, b, c): if a and b: return True if b or c: return True return False """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) assert complexity == 5 # 1 base + 2 if + 1 and + 1 or def test_ternary_operator(self) -> None: """Test function with ternary operator.""" code = """ def function_with_ternary(x): return "positive" if x > 0 else "non-positive" """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) assert complexity == 2 # 1 base + 1 conditional expression def test_list_comprehension(self) -> None: """Test function with list comprehension.""" code = """ def function_with_list_comp(items): return [x * 2 for x in items if x > 0] """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) assert complexity == 2 # 1 base + 1 list comprehension def test_assert_statement(self) -> None: """Test function with assert statement.""" code = """ def function_with_assert(x): assert x > 0, "x must be positive" return x * 2 """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) assert complexity == 2 # 1 base + 1 assert def test_with_statement(self) -> None: """Test function with with statement.""" code = """ def function_with_context_manager(filename): with open(filename) as f: return f.read() """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) assert complexity == 1 # with doesn't add complexity for single context manager def test_multiple_with_items(self) -> None: """Test function with multiple context managers.""" code = """ def function_with_multiple_contexts(file1, file2): with open(file1) as f1, open(file2) as f2: return f1.read() + f2.read() """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) assert complexity == 2 # 1 base + 1 for second context manager def test_lambda_with_conditional(self) -> None: """Test function containing lambda with conditional.""" code = """ def function_with_lambda(): return lambda x: x if x > 0 else -x """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) # Note: The lambda itself adds 1, and the conditional inside adds 1 assert complexity == 3 # 1 base + 1 lambda + 1 conditional def test_complex_function(self) -> None: """Test a complex function with multiple control flow elements.""" code = """ def complex_function(data, threshold): if not data: return None results = [] for item in data: if item > threshold: try: value = process(item) if value and (value > 10 or value < -10): results.append(value) except ValueError: continue except Exception: break elif item < 0: results.append(0) return results if results else None """ node = self._parse_function(code) complexity = self.calculator.calculate_complexity(node, code.encode()) # 1 base + 1 if (not data) + 1 for + 1 if (item > threshold) + # 1 if (value and ...) + 1 and + 1 or + 2 except + 1 elif + 1 conditional assert complexity == 11 def test_get_complexity_level(self) -> None: """Test complexity level categorization.""" assert self.calculator.get_complexity_level(1) == "simple" assert self.calculator.get_complexity_level(5) == "simple" assert self.calculator.get_complexity_level(10) == "simple" assert self.calculator.get_complexity_level(11) == "moderate" assert self.calculator.get_complexity_level(20) == "moderate" assert self.calculator.get_complexity_level(21) == "complex" assert self.calculator.get_complexity_level(50) == "complex" assert self.calculator.get_complexity_level(51) == "very complex" assert self.calculator.get_complexity_level(100) == "very complex"

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/johannhartmann/mcpcodeanalysis'

If you have feedback or need assistance with the MCP directory API, please join our Discord server