Coverage for tests / test_mi / test_typescript.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 (TypeScript)."""
3from analyzers.typescript 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 = """
17function f() {
18 return 1;
19}
20"""
21 mi = _mi(code)
22 assert mi > 50, f"Trivial function should have high MI, got {mi}"
25def test_simple_add():
26 code = """
27function add(a: number, b: number): number {
28 return a + b;
29}
30"""
31 mi = _mi(code)
32 assert mi > 50, f"Simple function should have high MI, got {mi}"
35# --- Complex function (low MI) ---
37def test_complex_function():
38 code = """
39function process(data: any[], flag: boolean, mode: boolean, opt: boolean, extra: boolean) {
40 let result: any[] = [];
41 let total = 0;
42 let count = 0;
43 for (let item of data) {
44 if (flag && mode) {
45 if (item > 0) {
46 for (let sub of item) {
47 if (sub < 100) {
48 if (opt || extra) {
49 result.push(sub * 2 + total);
50 count += 1;
51 } else {
52 result.push(sub - 1);
53 }
54 } else if (sub > 200) {
55 total += sub;
56 count -= 1;
57 }
58 }
59 } else if (item < 0) {
60 try {
61 const val = parseInt(item);
62 if (val > 0 && val < 50) {
63 result.push(val);
64 } else if (val >= 50 || val === 0) {
65 result.push(-val);
66 }
67 } catch (e) {
68 result.push(0);
69 }
70 }
71 } else if (mode || opt) {
72 for (let sub of data) {
73 if (sub !== item) {
74 result.push(sub + item);
75 total += sub;
76 }
77 }
78 }
79 }
80 if (count > 0) {
81 return result.slice(0, count);
82 }
83 return result;
84}
85"""
86 mi = _mi(code)
87 assert mi < 50, f"Complex function should have low MI, got {mi}"
90# --- Edge case: empty body ---
92def test_empty_body():
93 code = """
94function noop() {}
95"""
96 mi = _mi(code)
97 # With empty/minimal body, MI should be high
98 assert mi > 50, f"Empty body function should have high MI, got {mi}"
101# --- Edge case: no operators ---
103def test_no_operators():
104 code = """
105function f() {
106 const x = 1;
107}
108"""
109 mi = _mi(code)
110 assert mi > 50, f"No-operator function should have high MI, got {mi}"
113# --- MI is in valid range ---
115def test_mi_range():
116 code = """
117function f(x: boolean) {
118 if (x) {
119 return 1;
120 }
121 return 0;
122}
123"""
124 mi = _mi(code)
125 assert 0 <= mi <= 100, f"MI should be in [0, 100], got {mi}"
128# --- Multiple functions ---
130def test_multiple_functions():
131 code = """
132function simple() {
133 return 42;
134}
136function moderate(x: number, y: number) {
137 if (x > y) {
138 return x;
139 } else if (x < y) {
140 return y;
141 } else {
142 return x + y;
143 }
144}
145"""
146 result = analyze_source(code)
147 assert len(result.functions) == 2
148 mi_simple = result.functions[0].mi
149 mi_moderate = result.functions[1].mi
150 assert mi_simple > mi_moderate, f"Simple function should have higher MI: {mi_simple} vs {mi_moderate}"