""" Simple test runner for pattern validation (bypasses pytest collection issues) """ import sys from pathlib import Path # Add parent directory to path sys.path.insert(0, str(Path(__file__).parent.parent)) # Import test functions from tests.test_pattern_validation import ( load_all_pattern_files, load_pattern_file, extract_error_keys_from_i18n, extract_suggestions_from_i18n, SUPPORTED_LANGUAGES, VALID_CATEGORIES, PROJECT_ROOT ) import re def run_tests(): """Run all validation tests""" print("="*70) print("Pattern Validation Test Suite") print("="*70) # Load data print("\nINFO: Loading pattern files...") pattern_files = load_all_pattern_files() print(f" Found {len(pattern_files)} pattern files") all_patterns = [] for file_path in pattern_files: data = load_pattern_file(file_path) for pattern in data.get("patterns", []): pattern["_source_file"] = str(file_path.relative_to(PROJECT_ROOT)) all_patterns.append(pattern) print(f" Loaded {len(all_patterns)} patterns total") print("\nINFO: Loading i18n data...") error_keys = extract_error_keys_from_i18n() suggestions = extract_suggestions_from_i18n() print(f" Found {len(error_keys)} error keys") print(f" Found translations for {len(suggestions)} languages") # Test 1: JSON validity print("\nOK Test 1: JSON Validity") for file_path in pattern_files: try: load_pattern_file(file_path) print(f" PASS {file_path.name}") except Exception as e: print(f" FAIL {file_path.name}: {e}") return False # Test 2: Required fields print("\nOK Test 2: Required Fields") required_fields = ["id", "regex", "error_key", "priority", "category"] for pattern in all_patterns: for field in required_fields: if field not in pattern: print(f" FAIL Pattern {pattern.get('id', 'UNKNOWN')} missing field: {field}") return False print(f" PASS All {len(all_patterns)} patterns have required fields") # Test 3: Regex compilation print("\nOK Test 3: Regex Compilation") for pattern in all_patterns: try: re.compile(pattern.get("regex", "")) except re.error as e: print(f" FAIL Pattern {pattern.get('id', 'UNKNOWN')}: Invalid regex - {e}") return False print(f" PASS All {len(all_patterns)} regex patterns compile successfully") # Test 4: i18n completeness (FIXED: properly map error_key -> ERROR_KEYS -> SUGGESTIONS) print("\nOK Test 4: i18n Completeness") # Import ERROR_KEYS dict for proper mapping import i18n ERROR_KEYS_DICT = i18n.ERROR_KEYS # First check: all pattern error_keys must exist in ERROR_KEYS for pattern in all_patterns: error_key = pattern.get("error_key", "") if error_key not in ERROR_KEYS_DICT: print(f" FAIL Pattern {pattern.get('id', 'UNKNOWN')}: error_key '{error_key}' not in i18n.ERROR_KEYS") return False # Second check: all mapped suggestion_keys must have translations in all languages for lang in SUPPORTED_LANGUAGES: if lang not in suggestions: print(f" FAIL Language '{lang}' not found in SUGGESTIONS") return False missing_patterns = [] for pattern in all_patterns: error_key = pattern.get("error_key", "") # Map error_key to actual suggestion_key via ERROR_KEYS dict # Example: "TYPE_MISMATCH" -> "type_mismatch" suggestion_key = ERROR_KEYS_DICT.get(error_key) if suggestion_key is None: # Shouldn't happen since we checked above missing_patterns.append(f"{pattern.get('id', 'UNKNOWN')} (no mapping for '{error_key}')") continue # Check if the mapped suggestion_key exists in this language's SUGGESTIONS if suggestion_key not in suggestions[lang]: missing_patterns.append(f"{pattern.get('id', 'UNKNOWN')} ({error_key} -> {suggestion_key})") if missing_patterns: print(f" FAIL {lang}: {len(missing_patterns)} patterns missing translations:") for mp in missing_patterns[:5]: # Show first 5 print(f" - {mp}") if len(missing_patterns) > 5: print(f" ... and {len(missing_patterns) - 5} more") return False else: print(f" PASS {lang}: All {len(all_patterns)} patterns have translations") # Test 5: Priority ranges print("\nOK Test 5: Priority Ranges (50-95)") for pattern in all_patterns: priority = pattern.get("priority", 0) if not isinstance(priority, int) or not (50 <= priority <= 95): print(f" FAIL Pattern {pattern.get('id', 'UNKNOWN')}: Invalid priority {priority}") return False print(f" PASS All priorities valid") # Test 6: Unique IDs print("\nOK Test 6: Unique Pattern IDs") seen_ids = {} for pattern in all_patterns: pattern_id = pattern.get("id", "UNKNOWN") if pattern_id in seen_ids: print(f" FAIL Duplicate ID '{pattern_id}' in:") print(f" - {seen_ids[pattern_id]}") print(f" - {pattern['_source_file']}") return False seen_ids[pattern_id] = pattern["_source_file"] print(f" PASS All {len(all_patterns)} pattern IDs are unique") # Test 7: Valid categories print("\nOK Test 7: Valid Categories") for pattern in all_patterns: category = pattern.get("category", "") if category not in VALID_CATEGORIES: print(f" FAIL Pattern {pattern.get('id', 'UNKNOWN')}: Invalid category '{category}'") print(f" Valid: {', '.join(sorted(VALID_CATEGORIES))}") return False print(f" PASS All categories valid") # Statistics print("\nINFO: Pattern Statistics") print("="*70) print(f"Total patterns: {len(all_patterns)}") by_category = {} by_source = {} for pattern in all_patterns: category = pattern.get("category", "unknown") source_file = pattern["_source_file"] by_category[category] = by_category.get(category, 0) + 1 by_source[source_file] = by_source.get(source_file, 0) + 1 print("\nBy category:") for cat, count in sorted(by_category.items()): print(f" {cat:20s}: {count}") print("\nBy source file:") for src, count in sorted(by_source.items()): print(f" {src:40s}: {count}") print("\n" + "="*70) print("PASS ALL TESTS PASSED!") print("="*70) return True if __name__ == "__main__": success = run_tests() sys.exit(0 if success else 1)