Coverage for tests / test_mi / test_python.py: 100%
36 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-08 15:04 -0800
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-08 15:04 -0800
1"""Tests for Maintainability Index (Python)."""
3from analyzers.python import analyze_source
6def _mi(code: str) -> float:
7 """Return MI of the first function in code."""
8 result = analyze_source(code)
9 assert result.functions, f"No functions found in:\n{code}"
10 return result.functions[0].mi
13# --- Trivial function (high MI) ---
15def test_trivial_function():
16 code = """
17def f():
18 return 1
19"""
20 mi = _mi(code)
21 assert mi > 50, f"Trivial function should have high MI, got {mi}"
24def test_simple_add():
25 code = """
26def add(a, b):
27 return a + b
28"""
29 mi = _mi(code)
30 assert mi > 50, f"Simple function should have high MI, got {mi}"
33# --- Complex function (low MI) ---
35def test_complex_function():
36 code = """
37def process(data, flag, mode, opt, extra):
38 result = []
39 total = 0
40 count = 0
41 for item in data:
42 if flag and mode:
43 if item > 0:
44 for sub in item:
45 if sub < 100:
46 if opt or extra:
47 result.append(sub * 2 + total)
48 count += 1
49 else:
50 result.append(sub - 1)
51 elif sub > 200:
52 total += sub
53 count -= 1
54 elif item < 0:
55 try:
56 val = int(item)
57 if val > 0 and val < 50:
58 result.append(val)
59 elif val >= 50 or val == 0:
60 result.append(-val)
61 except Exception:
62 result.append(0)
63 elif mode or opt:
64 for sub in data:
65 if sub != item:
66 result.append(sub + item)
67 total += sub
68 if count > 0:
69 return result[:count]
70 return result
71"""
72 mi = _mi(code)
73 assert mi < 50, f"Complex function should have low MI, got {mi}"
76# --- Edge case: empty body ---
78def test_empty_body():
79 code = """
80def noop():
81 pass
82"""
83 mi = _mi(code)
84 assert mi > 50, f"Empty body function should have high MI, got {mi}"
87# --- Edge case: no operators ---
89def test_no_operators():
90 code = """
91def f():
92 x = 1
93"""
94 mi = _mi(code)
95 # With minimal halstead volume, MI should be high
96 assert mi > 50, f"No-operator function should have high MI, got {mi}"
99# --- MI is in valid range ---
101def test_mi_range():
102 code = """
103def f(x):
104 if x:
105 return 1
106 return 0
107"""
108 mi = _mi(code)
109 assert 0 <= mi <= 100, f"MI should be in [0, 100], got {mi}"
112# --- Multiple functions ---
114def test_multiple_functions():
115 code = """
116def simple():
117 return 42
119def moderate(x, y):
120 if x > y:
121 return x
122 elif x < y:
123 return y
124 else:
125 return x + y
126"""
127 result = analyze_source(code)
128 assert len(result.functions) == 2
129 mi_simple = result.functions[0].mi
130 mi_moderate = result.functions[1].mi
131 assert mi_simple > mi_moderate, f"Simple function should have higher MI: {mi_simple} vs {mi_moderate}"