forked from FSoft-AI4Code/CodeWiki
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtest_id_based_clustering.py
More file actions
272 lines (221 loc) · 8.31 KB
/
Copy pathtest_id_based_clustering.py
File metadata and controls
272 lines (221 loc) · 8.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
#!/usr/bin/env python3
"""
Test script to verify ID-based clustering fixes.
Tests the critical fixes:
1. json.loads() instead of eval()
2. format_potential_core_components() return type handling
3. Integer ID validation
"""
import json
import sys
from typing import Dict
class TestResults:
"""Accumulator for standalone integration test scripts."""
def __init__(self):
self.tests = []
def add_test(self, name: str, passed: bool):
self.tests.append((name, passed))
def print_summary(self) -> bool:
print("=" * 60)
print("TEST SUMMARY")
print("=" * 60)
all_passed = True
for test_name, passed in self.tests:
status = "✅ PASS" if passed else "❌ FAIL"
print(f"{status}: {test_name}")
if not passed:
all_passed = False
print()
if all_passed:
print("✅ ALL TESTS PASSED")
else:
print("❌ SOME TESTS FAILED")
return all_passed
# Test 1: Verify json.loads() works with integer IDs
def test_json_parsing():
print("Test 1: JSON parsing with integer IDs")
print("-" * 60)
# Valid JSON with integer IDs
valid_json = """
{
"auth_module": {
"path": "src/auth",
"components": [0, 1, 2]
},
"api_module": {
"path": "src/api",
"components": [3, 4, 5]
}
}
"""
try:
result = json.loads(valid_json)
print("✅ Valid JSON parsed successfully")
print(f" auth_module components: {result['auth_module']['components']}")
print(f" Type check: {all(isinstance(x, int) for x in result['auth_module']['components'])}")
except Exception as e:
print(f"❌ Failed to parse valid JSON: {e}")
return False
# Invalid JSON with quoted IDs (should fail)
invalid_json = """
{
"auth_module": {
"components": ["0", "1", "2"]
}
}
"""
try:
result = json.loads(invalid_json)
components = result['auth_module']['components']
if all(isinstance(x, str) for x in components):
print("⚠️ JSON with quoted IDs parsed (but will fail validation)")
print(f" Components: {components} (type: str - WRONG)")
else:
print("❌ Unexpected type")
except Exception as e:
print(f"❌ Parsing failed: {e}")
print()
return True
# Test 2: Verify format_potential_core_components() return types
def test_return_types():
print("Test 2: format_potential_core_components() return types")
print("-" * 60)
# Simulate the function signature
def format_potential_core_components_mock(leaf_nodes, components):
"""Mock function with correct 4-tuple return"""
potential_core_components = "# Mock component list"
potential_core_components_with_code = "# Mock component with code\nclass Example:\n pass"
id_to_fqdn = {0: "example.Example", 1: "test.Test"}
id_descriptions = {"0": "Example (mock, test)", "1": "Test (mock, test)"}
return potential_core_components, potential_core_components_with_code, id_to_fqdn, id_descriptions
# Test correct usage (NEW code)
try:
_, potential_core_components_with_code, _, _ = format_potential_core_components_mock([], {})
print(f"✅ Correct unpacking works")
print(f" Type: {type(potential_core_components_with_code)}")
print(f" Is string: {isinstance(potential_core_components_with_code, str)}")
# Simulate count_tokens usage
def count_tokens_mock(text: str) -> int:
return len(text.split())
num_tokens = count_tokens_mock(potential_core_components_with_code)
print(f" Token count: {num_tokens}")
except Exception as e:
print(f"❌ Failed: {e}")
return False
# Test OLD buggy code (would fail)
try:
result = format_potential_core_components_mock([], {})
last_element = result[-1] # This is id_descriptions (Dict)
print(f"⚠️ OLD code: result[-1] = {type(last_element)} (Dict, not str!)")
# This would fail in count_tokens:
# num_tokens = count_tokens(last_element) # TypeError!
except Exception as e:
print(f"❌ Failed: {e}")
print()
return True
# Test 3: Verify integer ID validation
def test_id_validation():
print("Test 3: Integer ID validation")
print("-" * 60)
id_to_fqdn = {0: "auth.AuthService", 1: "api.UserController", 2: "config.DatabaseConfig"}
max_id = len(id_to_fqdn) - 1
# Test valid IDs
valid_module_tree = {
"auth_module": {
"components": [0, 1]
},
"config_module": {
"components": [2]
}
}
print("Testing VALID module tree:")
all_valid = True
for module_name, module_info in valid_module_tree.items():
component_ids = module_info.get("components", [])
invalid_ids = []
for comp_id in component_ids:
if not isinstance(comp_id, int):
invalid_ids.append(f"{comp_id} (type: {type(comp_id).__name__})")
elif comp_id < 0 or comp_id > max_id:
invalid_ids.append(f"{comp_id} (out of range 0-{max_id})")
if invalid_ids:
print(f"❌ Module '{module_name}' has invalid IDs: {invalid_ids}")
all_valid = False
else:
print(f"✅ Module '{module_name}' has valid IDs: {component_ids}")
# Test invalid IDs
print("\nTesting INVALID module tree:")
invalid_module_tree = {
"bad_module": {
"components": ["0", 1, 999] # String, valid int, out-of-range int
}
}
for module_name, module_info in invalid_module_tree.items():
component_ids = module_info.get("components", [])
invalid_ids = []
for comp_id in component_ids:
if not isinstance(comp_id, int):
invalid_ids.append(f"{comp_id} (type: {type(comp_id).__name__})")
elif comp_id < 0 or comp_id > max_id:
invalid_ids.append(f"{comp_id} (out of range 0-{max_id})")
if invalid_ids:
print(f"✅ Correctly detected invalid IDs in '{module_name}': {invalid_ids}")
else:
print(f"❌ Should have detected invalid IDs!")
all_valid = False
print()
return all_valid
# Test 4: Verify ID-to-FQDN normalization
def test_normalization():
print("Test 4: ID-to-FQDN normalization")
print("-" * 60)
id_to_fqdn = {
0: "main-repo.src/auth/auth_service.py::AuthService",
1: "main-repo.src/api/user_controller.py::UserController",
2: "main-repo.src/config/database.py::DatabaseConfig"
}
module_tree = {
"auth_module": {
"components": [0, 1]
},
"config_module": {
"components": [2]
}
}
print("Normalizing component IDs to FQDNs:")
total_normalized = 0
for module_name, module_data in module_tree.items():
component_ids = module_data.get('components', [])
normalized_components = []
for comp_id in component_ids:
try:
idx = int(comp_id)
if idx in id_to_fqdn:
fqdn = id_to_fqdn[idx]
normalized_components.append(fqdn)
total_normalized += 1
print(f" ✅ ID {idx} → {fqdn}")
except (ValueError, TypeError) as e:
print(f" ❌ Invalid ID: {comp_id} - {e}")
module_data['components'] = normalized_components
print(f"\n✅ Normalized {total_normalized} component IDs")
print(f" Final module tree has FQDNs:")
for module_name, module_data in module_tree.items():
print(f" {module_name}: {len(module_data['components'])} components")
print()
return total_normalized == 3
if __name__ == "__main__":
print("=" * 60)
print("ID-BASED CLUSTERING VALIDATION TESTS")
print("=" * 60)
print()
results = TestResults()
results.add_test("JSON parsing", test_json_parsing())
results.add_test("Return types", test_return_types())
results.add_test("ID validation", test_id_validation())
results.add_test("Normalization", test_normalization())
all_passed = results.print_summary()
if all_passed:
sys.exit(0)
else:
sys.exit(1)