From 8b8abf00e02386e1feddb03262c982c991df8143 Mon Sep 17 00:00:00 2001 From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 05:08:54 +0000 Subject: [PATCH 1/6] fix(CODEWIKI-009): 7 review findings across 6 files --- test_clustering_real.py | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/test_clustering_real.py b/test_clustering_real.py index 9c8285ab..de825ac6 100644 --- a/test_clustering_real.py +++ b/test_clustering_real.py @@ -16,6 +16,33 @@ from codewiki.src.be.dependency_analyzer.models.core import Node from codewiki.src.config import Config + +class TestResults: + def __init__(self): + self.tests = [] + + def add_test(self, name, passed, message=""): + self.tests.append((name, passed, message)) + + def print_summary(self): + print("\n" + "=" * 80) + print("TEST SUMMARY") + print("=" * 80) + passed_count = 0 + for name, passed, message in self.tests: + status = "✅ PASS" if passed else "❌ FAIL" + print(f"{status} - {name}" + (f": {message}" if message else "")) + if passed: + passed_count += 1 + total = len(self.tests) + print("-" * 80) + print(f"Total: {passed_count}/{total} passed") + print("=" * 80) + return passed_count == total + + +results = TestResults() + test_repo = os.getenv("TEST_REPO_PATH", os.path.dirname(os.path.abspath(__file__))) config = Config( @@ -53,13 +80,14 @@ current_module_tree={}, current_module_name=None, current_module_path=[] ) -print("\n" + "=" * 80) if len(module_tree) == 0: print("❌ FAILED - Check LLM response above") - sys.exit(1) + results.add_test("clustering produced modules", False, "module_tree is empty") else: print(f"✅ SUCCESS: {len(module_tree)} modules") for name, info in module_tree.items(): print(f" - {name}: {len(info.get('components', []))} components") - sys.exit(0) + results.add_test("clustering produced modules", True, f"{len(module_tree)} modules") +success = results.print_summary() +sys.exit(0 if success else 1) From dc066c51d4a78a7e4b4255970075ab11304b15de Mon Sep 17 00:00:00 2001 From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 05:08:55 +0000 Subject: [PATCH 2/6] fix(CODEWIKI-009): 7 review findings across 6 files --- test_with_logging.py | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/test_with_logging.py b/test_with_logging.py index adc6e714..e5e1a954 100644 --- a/test_with_logging.py +++ b/test_with_logging.py @@ -14,6 +14,33 @@ from codewiki.src.be.dependency_analyzer.utils.logging_config import setup_logging from codewiki.src.config import Config + +class TestResults: + def __init__(self): + self.results = [] + + def add_test(self, name, passed, message=""): + self.results.append((name, passed, message)) + + def print_summary(self): + print("\n" + "=" * 80) + print("TEST SUMMARY") + print("=" * 80) + failed = 0 + for name, passed, message in self.results: + status = "✅ PASS" if passed else "❌ FAIL" + print(f"{status}: {name}") + if message: + print(f" {message}") + if not passed: + failed += 1 + print("=" * 80) + print(f"Total: {len(self.results)}, Passed: {len(self.results) - failed}, Failed: {failed}") + return failed == 0 + + +results = TestResults() + # Setup logging FIRST setup_logging() @@ -71,14 +98,15 @@ current_module_path=[] ) -print("\n" + "=" * 80) - # Show result if len(module_tree) == 0: - print("❌ FAILED: Empty module tree") - print(" Check the INFO logs above for LLM response") + results.add_test("cluster_modules produces non-empty module tree", False, + "Empty module tree. Check the INFO logs above for LLM response") else: - print(f"✅ SUCCESS: {len(module_tree)} modules created") - for name, info in module_tree.items(): - print(f" - {name}: {len(info.get('components', []))} components") + detail = ", ".join(f"{name}: {len(info.get('components', []))} components" + for name, info in module_tree.items()) + results.add_test("cluster_modules produces non-empty module tree", True, + f"{len(module_tree)} modules created - {detail}") +success = results.print_summary() +sys.exit(0 if success else 1) From 328728300d9e1b83c18e728bc41fd959dae9aaf3 Mon Sep 17 00:00:00 2001 From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 05:08:57 +0000 Subject: [PATCH 3/6] fix(CODEWIKI-009): 7 review findings across 6 files --- test_fqdn_normalization.py | 218 +++++++++++++++++++++++++++++-------- 1 file changed, 174 insertions(+), 44 deletions(-) diff --git a/test_fqdn_normalization.py b/test_fqdn_normalization.py index ec90ff81..e0ca9846 100644 --- a/test_fqdn_normalization.py +++ b/test_fqdn_normalization.py @@ -1,17 +1,42 @@ """ Test Cases for FQDN Normalization Fix -Run with: python -m pytest test_fqdn_normalization.py -v +Run with: python test_fqdn_normalization.py """ -import pytest from collections import namedtuple # Mock Node class for testing Node = namedtuple('Node', ['short_id']) -def test_strip_deps_prefix(): +class TestResults: + def __init__(self): + self.total = 0 + self.passed = 0 + self.failed = 0 + self.failures = [] + + def add_test(self, name, condition, message=""): + self.total += 1 + if condition: + self.passed += 1 + else: + self.failed += 1 + self.failures.append((name, message)) + + def print_summary(self): + print(f"\n{'=' * 60}") + print(f"Test Summary: {self.passed}/{self.total} passed") + if self.failures: + print(f"\nFailures ({self.failed}):") + for name, message in self.failures: + print(f" - {name}: {message}") + print(f"{'=' * 60}") + return self.failed == 0 + + +def test_strip_deps_prefix(results): """Test that 'deps.' prefix is correctly stripped.""" # Simulated components dictionary components = { @@ -34,11 +59,19 @@ def test_strip_deps_prefix(): # Test normalization for llm_id, expected_fqdn in zip(llm_output, expected): stripped = llm_id[5:] if llm_id.startswith("deps.") else llm_id - assert stripped in components, f"Failed to find {stripped} after stripping" - assert stripped == expected_fqdn - - -def test_fuzzy_component_name_match(): + results.add_test( + "test_strip_deps_prefix: stripped in components", + stripped in components, + f"Failed to find {stripped} after stripping", + ) + results.add_test( + "test_strip_deps_prefix: stripped == expected_fqdn", + stripped == expected_fqdn, + f"{stripped} != {expected_fqdn}", + ) + + +def test_fuzzy_component_name_match(results): """Test fuzzy matching by component name (last segment).""" components = { "openframe-oss-lib.src.main.java.config.pinot.PinotConfigInitializer": Node(short_id="PinotConfigInitializer"), @@ -50,16 +83,29 @@ def test_fuzzy_component_name_match(): # Extract component name component_name = llm_id.split('.')[-1] - assert component_name == "PinotConfigInitializer" + results.add_test( + "test_fuzzy_component_name_match: component_name", + component_name == "PinotConfigInitializer", + f"component_name was {component_name}", + ) # Find matches matches = [fqdn for fqdn in components.keys() if fqdn.split('.')[-1] == component_name] - assert len(matches) == 1, f"Expected 1 match, found {len(matches)}" - assert matches[0] == "openframe-oss-lib.src.main.java.config.pinot.PinotConfigInitializer" + results.add_test( + "test_fuzzy_component_name_match: match count", + len(matches) == 1, + f"Expected 1 match, found {len(matches)}", + ) + if matches: + results.add_test( + "test_fuzzy_component_name_match: match value", + matches[0] == "openframe-oss-lib.src.main.java.config.pinot.PinotConfigInitializer", + f"matches[0] was {matches[0]}", + ) -def test_path_suffix_matching(): +def test_path_suffix_matching(results): """Test matching by path suffix (last N segments).""" components = { "openframe-oss-lib.different.path.java.config.pinot.PinotConfigInitializer": Node(short_id="PinotConfigInitializer"), @@ -73,11 +119,20 @@ def test_path_suffix_matching(): matches = [fqdn for fqdn in components.keys() if fqdn.endswith(suffix_3)] - assert len(matches) == 1 - assert matches[0] == "openframe-oss-lib.different.path.java.config.pinot.PinotConfigInitializer" + results.add_test( + "test_path_suffix_matching: match count", + len(matches) == 1, + f"Expected 1 match, found {len(matches)}", + ) + if matches: + results.add_test( + "test_path_suffix_matching: match value", + matches[0] == "openframe-oss-lib.different.path.java.config.pinot.PinotConfigInitializer", + f"matches[0] was {matches[0]}", + ) -def test_exact_fqdn_match(): +def test_exact_fqdn_match(results): """Test that exact FQDN matches work without modification.""" components = { "main-repo.src.services.user_service.UserService": Node(short_id="UserService"), @@ -85,10 +140,14 @@ def test_exact_fqdn_match(): llm_id = "main-repo.src.services.user_service.UserService" - assert llm_id in components + results.add_test( + "test_exact_fqdn_match: llm_id in components", + llm_id in components, + f"{llm_id} not found in components", + ) -def test_short_id_mapping(): +def test_short_id_mapping(results): """Test that short ID → FQDN mapping works.""" components = { "main-repo.src.services.user_service.UserService": Node(short_id="UserService"), @@ -102,11 +161,19 @@ def test_short_id_mapping(): mapping[short_id] = fqdn # Test mapping - assert mapping["UserService"] == "main-repo.src.services.user_service.UserService" - assert mapping["Logger"] == "main-repo.src.utils.logger.Logger" - - -def test_partial_path_mapping(): + results.add_test( + "test_short_id_mapping: UserService", + mapping.get("UserService") == "main-repo.src.services.user_service.UserService", + f"mapping[UserService] was {mapping.get('UserService')}", + ) + results.add_test( + "test_short_id_mapping: Logger", + mapping.get("Logger") == "main-repo.src.utils.logger.Logger", + f"mapping[Logger] was {mapping.get('Logger')}", + ) + + +def test_partial_path_mapping(results): """Test that partial paths are mapped correctly.""" components = { "main-repo.src.services.auth.UserService": Node(short_id="UserService"), @@ -128,13 +195,29 @@ def test_partial_path_mapping(): mapping[partial] = fqdn # Test mappings - assert "UserService" in mapping - assert "auth.UserService" in mapping - assert "services.auth.UserService" in mapping - assert "src.services.auth.UserService" in mapping - - -def test_collision_detection(): + results.add_test( + "test_partial_path_mapping: UserService", + "UserService" in mapping, + "UserService not in mapping", + ) + results.add_test( + "test_partial_path_mapping: auth.UserService", + "auth.UserService" in mapping, + "auth.UserService not in mapping", + ) + results.add_test( + "test_partial_path_mapping: services.auth.UserService", + "services.auth.UserService" in mapping, + "services.auth.UserService not in mapping", + ) + results.add_test( + "test_partial_path_mapping: src.services.auth.UserService", + "src.services.auth.UserService" in mapping, + "src.services.auth.UserService not in mapping", + ) + + +def test_collision_detection(results): """Test that collisions are detected when same short ID maps to multiple FQDNs.""" from collections import defaultdict @@ -154,11 +237,19 @@ def test_collision_detection(): else: mapping[short_id] = fqdn - assert "UserService" in collisions - assert len(collisions["UserService"]) >= 1 # At least one collision + results.add_test( + "test_collision_detection: UserService in collisions", + "UserService" in collisions, + "UserService not detected as collision", + ) + results.add_test( + "test_collision_detection: collision count", + len(collisions["UserService"]) >= 1, + f"Expected at least one collision, found {len(collisions['UserService'])}", + ) -def test_best_path_match_scoring(): +def test_best_path_match_scoring(results): """Test the path similarity scoring algorithm.""" llm_id = "deps.openframe-oss-lib.src.main.java.config.pinot.PinotConfigInitializer" candidates = [ @@ -180,11 +271,19 @@ def test_best_path_match_scoring(): scores.sort(key=lambda x: x[1], reverse=True) # Best match should have highest score - assert scores[0][0] == "openframe-oss-lib.src.main.java.config.pinot.PinotConfigInitializer" - assert scores[0][1] > scores[2][1] # Better than different namespace - - -def test_non_existent_component(): + results.add_test( + "test_best_path_match_scoring: best match", + scores[0][0] == "openframe-oss-lib.src.main.java.config.pinot.PinotConfigInitializer", + f"scores[0][0] was {scores[0][0]}", + ) + results.add_test( + "test_best_path_match_scoring: better than different namespace", + scores[0][1] > scores[2][1], + f"scores[0][1]={scores[0][1]} not > scores[2][1]={scores[2][1]}", + ) + + +def test_non_existent_component(results): """Test that non-existent components fail normalization.""" components = { "main-repo.src.services.UserService": Node(short_id="UserService"), @@ -194,14 +293,22 @@ def test_non_existent_component(): # Should not match anything stripped = llm_id[5:] if llm_id.startswith("deps.") else llm_id - assert stripped not in components + results.add_test( + "test_non_existent_component: stripped not in components", + stripped not in components, + f"{stripped} unexpectedly found in components", + ) component_name = llm_id.split('.')[-1] matches = [fqdn for fqdn in components.keys() if component_name in fqdn] - assert len(matches) == 0 + results.add_test( + "test_non_existent_component: no matches", + len(matches) == 0, + f"Expected 0 matches, found {len(matches)}", + ) -def test_double_class_name(): +def test_double_class_name(results): """Test handling of paths with duplicate component names.""" # This tests the scenario: PintoConfigInitializer.PinotConfigInitializer components = { @@ -218,10 +325,14 @@ def test_double_class_name(): # Should match by component name matches = [fqdn for fqdn in components.keys() if fqdn.split('.')[-1] == component_name] - assert len(matches) == 1 + results.add_test( + "test_double_class_name: match count", + len(matches) == 1, + f"Expected 1 match, found {len(matches)}", + ) -def test_java_package_path(): +def test_java_package_path(results): """Test handling of Java package paths with com.openframe prefix.""" components = { "openframe-oss-lib.src.main.java.com.openframe.management.config.PinotConfig": Node( @@ -235,8 +346,27 @@ def test_java_package_path(): # Strip deps prefix stripped = llm_id[5:] if llm_id.startswith("deps.") else llm_id - assert stripped in components + results.add_test( + "test_java_package_path: stripped in components", + stripped in components, + f"{stripped} not found in components", + ) if __name__ == "__main__": - pytest.main([__file__, "-v"]) + results = TestResults() + + test_strip_deps_prefix(results) + test_fuzzy_component_name_match(results) + test_path_suffix_matching(results) + test_exact_fqdn_match(results) + test_short_id_mapping(results) + test_partial_path_mapping(results) + test_collision_detection(results) + test_best_path_match_scoring(results) + test_non_existent_component(results) + test_double_class_name(results) + test_java_package_path(results) + + success = results.print_summary() + exit(0 if success else 1) From 8a877844cf362b0212582e5f3f4b8b48e7e79dde Mon Sep 17 00:00:00 2001 From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 05:08:58 +0000 Subject: [PATCH 4/6] fix(CODEWIKI-009): 7 review findings across 6 files --- test_id_based_clustering.py | 87 +++++++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 14 deletions(-) diff --git a/test_id_based_clustering.py b/test_id_based_clustering.py index 57cd5c4e..17a696a7 100644 --- a/test_id_based_clustering.py +++ b/test_id_based_clustering.py @@ -18,8 +18,8 @@ class TestResults: def __init__(self): self.tests = [] - def add_test(self, name: str, passed: bool): - self.tests.append((name, passed)) + def add_test(self, name: str, passed: bool, details: str = ""): + self.tests.append((name, passed, details)) def print_summary(self) -> bool: print("=" * 60) @@ -27,9 +27,10 @@ def print_summary(self) -> bool: print("=" * 60) all_passed = True - for test_name, passed in self.tests: + for test_name, passed, details in self.tests: status = "✅ PASS" if passed else "❌ FAIL" - print(f"{status}: {test_name}") + suffix = f" ({details})" if details else "" + print(f"{status}: {test_name}{suffix}") if not passed: all_passed = False @@ -43,7 +44,7 @@ def print_summary(self) -> bool: # Test 1: Verify json.loads() works with integer IDs -def test_json_parsing(): +def test_json_parsing(results: "TestResults"): print("Test 1: JSON parsing with integer IDs") print("-" * 60) @@ -65,9 +66,16 @@ def test_json_parsing(): 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'])}") + types_ok = all(isinstance(x, int) for x in result['auth_module']['components']) + print(f" Type check: {types_ok}") + results.add_test( + "JSON parsing - valid JSON with integer IDs", + types_ok, + f"components={result['auth_module']['components']}" + ) except Exception as e: print(f"❌ Failed to parse valid JSON: {e}") + results.add_test("JSON parsing - valid JSON with integer IDs", False, str(e)) return False # Invalid JSON with quoted IDs (should fail) @@ -85,17 +93,24 @@ def test_json_parsing(): 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)") + results.add_test( + "JSON parsing - quoted IDs detected as strings", + True, + f"components={components} (type: str)" + ) else: print("❌ Unexpected type") + results.add_test("JSON parsing - quoted IDs detected as strings", False, "unexpected type") except Exception as e: print(f"❌ Parsing failed: {e}") + results.add_test("JSON parsing - quoted IDs detected as strings", False, str(e)) print() return True # Test 2: Verify format_potential_core_components() return types -def test_return_types(): +def test_return_types(results: "TestResults"): print("Test 2: format_potential_core_components() return types") print("-" * 60) @@ -113,7 +128,8 @@ def format_potential_core_components_mock(leaf_nodes, components): _, 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)}") + is_str = isinstance(potential_core_components_with_code, str) + print(f" Is string: {is_str}") # Simulate count_tokens usage def count_tokens_mock(text: str) -> int: @@ -121,26 +137,39 @@ def count_tokens_mock(text: str) -> int: num_tokens = count_tokens_mock(potential_core_components_with_code) print(f" Token count: {num_tokens}") + results.add_test( + "Return types - correct unpacking yields str", + is_str, + f"type={type(potential_core_components_with_code).__name__}, tokens={num_tokens}" + ) except Exception as e: print(f"❌ Failed: {e}") + results.add_test("Return types - correct unpacking yields str", False, str(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) + is_dict_not_str = isinstance(last_element, dict) and not isinstance(last_element, str) 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! + results.add_test( + "Return types - old buggy last-element access is Dict not str", + is_dict_not_str, + f"type={type(last_element).__name__}" + ) except Exception as e: print(f"❌ Failed: {e}") + results.add_test("Return types - old buggy last-element access is Dict not str", False, str(e)) print() return True # Test 3: Verify integer ID validation -def test_id_validation(): +def test_id_validation(results: "TestResults"): print("Test 3: Integer ID validation") print("-" * 60) @@ -172,8 +201,18 @@ def test_id_validation(): if invalid_ids: print(f"❌ Module '{module_name}' has invalid IDs: {invalid_ids}") all_valid = False + results.add_test( + f"ID validation - valid module tree '{module_name}'", + False, + f"unexpected invalid IDs: {invalid_ids}" + ) else: print(f"✅ Module '{module_name}' has valid IDs: {component_ids}") + results.add_test( + f"ID validation - valid module tree '{module_name}'", + True, + f"components={component_ids}" + ) # Test invalid IDs print("\nTesting INVALID module tree:") @@ -195,16 +234,26 @@ def test_id_validation(): if invalid_ids: print(f"✅ Correctly detected invalid IDs in '{module_name}': {invalid_ids}") + results.add_test( + f"ID validation - invalid module tree '{module_name}' detected", + True, + f"invalid_ids={invalid_ids}" + ) else: print(f"❌ Should have detected invalid IDs!") all_valid = False + results.add_test( + f"ID validation - invalid module tree '{module_name}' detected", + False, + "no invalid IDs detected" + ) print() return all_valid # Test 4: Verify ID-to-FQDN normalization -def test_normalization(): +def test_normalization(results: "TestResults"): print("Test 4: ID-to-FQDN normalization") print("-" * 60) @@ -238,8 +287,18 @@ def test_normalization(): normalized_components.append(fqdn) total_normalized += 1 print(f" ✅ ID {idx} → {fqdn}") + results.add_test( + f"Normalization - ID {idx} in '{module_name}'", + True, + f"{idx} -> {fqdn}" + ) except (ValueError, TypeError) as e: print(f" ❌ Invalid ID: {comp_id} - {e}") + results.add_test( + f"Normalization - ID {comp_id} in '{module_name}'", + False, + str(e) + ) module_data['components'] = normalized_components @@ -259,10 +318,10 @@ def test_normalization(): 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()) + results.add_test("JSON parsing", test_json_parsing(results)) + results.add_test("Return types", test_return_types(results)) + results.add_test("ID validation", test_id_validation(results)) + results.add_test("Normalization", test_normalization(results)) all_passed = results.print_summary() From 0312cc8a215044559c06119f63b1822a47ede792 Mon Sep 17 00:00:00 2001 From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 05:09:00 +0000 Subject: [PATCH 5/6] fix(CODEWIKI-009): 7 review findings across 6 files --- test_local_config.py | 73 +++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/test_local_config.py b/test_local_config.py index ecfcc39d..cceb80f7 100755 --- a/test_local_config.py +++ b/test_local_config.py @@ -17,6 +17,32 @@ from codewiki.src.config import Config +class TestResults: + """Accumulates test results and prints a structured summary.""" + + def __init__(self): + self.tests = [] + + def add_test(self, name: str, passed: bool, message: str = ""): + self.tests.append((name, passed, message)) + + def all_passed(self) -> bool: + return all(passed for _, passed, _ in self.tests) + + def print_summary(self): + print_section("Test Summary") + for name, passed, message in self.tests: + status = "✅ PASS" if passed else "❌ FAIL" + line = f"{status}: {name}" + if message: + line += f" - {message}" + print(line) + + total = len(self.tests) + passed_count = sum(1 for _, passed, _ in self.tests if passed) + print(f"\n{passed_count}/{total} tests passed") + + def print_section(title: str): """Print a section header.""" print(f"\n{'='*60}") @@ -208,48 +234,51 @@ def test_llm_service_creation(backend_config): def main(): """Run all tests.""" print_section("CodeWiki Local Configuration Test") - + + results = TestResults() + # Test 1: Load API keys from .env.local result = test_env_loading() if not result: - print("\n" + "="*60) - print("❌ FAILED: Could not load API keys from .env.local") - print("="*60) + results.add_test("Load API keys from .env.local", False, "Could not load API keys from .env.local") + results.print_summary() sys.exit(1) - + results.add_test("Load API keys from .env.local", True) + openai_key, anthropic_key = result - + # Test 2: Save configuration if not test_config_manager_save(openai_key, anthropic_key): - print("\n" + "="*60) - print("❌ FAILED: Could not save configuration") - print("="*60) + results.add_test("Save configuration", False, "Could not save configuration") + results.print_summary() sys.exit(1) - + results.add_test("Save configuration", True) + # Test 3: Load configuration config_manager = test_config_manager_load() if not config_manager: - print("\n" + "="*60) - print("❌ FAILED: Could not load configuration") - print("="*60) + results.add_test("Load configuration", False, "Could not load configuration") + results.print_summary() sys.exit(1) - + results.add_test("Load configuration", True) + # Test 4: Create backend config backend_config = test_backend_config_creation(config_manager) if not backend_config: - print("\n" + "="*60) - print("❌ FAILED: Could not create backend config") - print("="*60) + results.add_test("Create backend config", False, "Could not create backend config") + results.print_summary() sys.exit(1) - + results.add_test("Create backend config", True) + # Test 5: Create LLM services if not test_llm_service_creation(backend_config): - print("\n" + "="*60) - print("❌ FAILED: Could not create LLM services") - print("="*60) + results.add_test("Create LLM services", False, "Could not create LLM services") + results.print_summary() sys.exit(1) - + results.add_test("Create LLM services", True) + # Success! + results.print_summary() print_section("🎉 SUCCESS: All tests passed!") print("\nCodeWiki is properly configured and ready to use.") print("\nNext steps:") From 007e499d7250393991e5b0b57931d3fe3f59502c Mon Sep 17 00:00:00 2001 From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 05:09:02 +0000 Subject: [PATCH 6/6] fix(CODEWIKI-009): 7 review findings across 6 files --- test_module_disambiguation.py | 90 ++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 33 deletions(-) diff --git a/test_module_disambiguation.py b/test_module_disambiguation.py index f1ac1da1..f8f2d030 100644 --- a/test_module_disambiguation.py +++ b/test_module_disambiguation.py @@ -17,6 +17,45 @@ ) logger = logging.getLogger(__name__) + +class TestResults: + """Accumulates pass/fail results and prints a structured summary.""" + + def __init__(self): + self.passed = 0 + self.failed = 0 + self.results = [] + + def add_test(self, name: str, passed: bool, message: str = ""): + if passed: + self.passed += 1 + status = "PASSED" + symbol = "✅" + else: + self.failed += 1 + status = "FAILED" + symbol = "❌" + self.results.append((name, passed, message)) + print(f"\n{symbol} {name} {status}" + (f": {message}" if message else "")) + + def print_summary(self): + total = self.passed + self.failed + print("\n" + "="*80) + print("Test Summary") + print("="*80) + print(f"✅ Passed: {self.passed}/{total}") + print(f"❌ Failed: {self.failed}/{total}") + + if self.failed == 0: + print("\n🎉 All tests passed! Module disambiguation is working correctly.") + else: + print(f"\n⚠️ {self.failed} test(s) failed. Please review the implementation.") + + @property + def exit_code(self) -> int: + return 0 if self.failed == 0 else 1 + + def _find_best_path_match_original(llm_id: str, candidates: List[str]) -> Optional[str]: """Original implementation WITHOUT module context.""" llm_segments = llm_id.split('.') @@ -255,50 +294,35 @@ def main(): print("\nThis test demonstrates the fix for ambiguous component resolution") print("by using module name context to disambiguate candidates.") - # Run all tests - tests_passed = 0 - tests_failed = 0 + results = TestResults() # Test 1: DeviceController for openframe-api-service orig_result, enh_result = test_device_controller_disambiguation() - if orig_result is None and enh_result is not None: - tests_passed += 1 - print("\n✅ Test 1 PASSED: Original failed (ambiguous), Enhanced succeeded") - else: - tests_failed += 1 - print("\n❌ Test 1 FAILED") + results.add_test( + "Test 1", + orig_result is None and enh_result is not None, + "Original failed (ambiguous), Enhanced succeeded" + ) # Test 2: DeviceController for openframe-external-api-service ext_result = test_external_api_disambiguation() - if ext_result and "external" in ext_result: - tests_passed += 1 - print("\n✅ Test 2 PASSED: Correctly matched external variant") - else: - tests_failed += 1 - print("\n❌ Test 2 FAILED") + results.add_test( + "Test 2", + bool(ext_result and "external" in ext_result), + "Correctly matched external variant" + ) # Test 3: SecurityConfig for openframe-gateway-service sec_result = test_security_config_disambiguation() - if sec_result and "gateway" in sec_result: - tests_passed += 1 - print("\n✅ Test 3 PASSED: Correctly matched gateway variant") - else: - tests_failed += 1 - print("\n❌ Test 3 FAILED") + results.add_test( + "Test 3", + bool(sec_result and "gateway" in sec_result), + "Correctly matched gateway variant" + ) - # Summary - print("\n" + "="*80) - print("Test Summary") - print("="*80) - print(f"✅ Passed: {tests_passed}/3") - print(f"❌ Failed: {tests_failed}/3") + results.print_summary() - if tests_failed == 0: - print("\n🎉 All tests passed! Module disambiguation is working correctly.") - return 0 - else: - print(f"\n⚠️ {tests_failed} test(s) failed. Please review the implementation.") - return 1 + return results.exit_code if __name__ == "__main__":