"""Validation of i18n keys against locale files.""" from dataclasses import dataclass, field from typing import Dict, Set @dataclass class ValidationResult: """Result of validating i18n keys against locale files.""" missing_keys: Set[str] = field(default_factory=set) unused_keys: Set[str] = field(default_factory=set) matching_keys: Set[str] = field(default_factory=set) extra_keys_per_locale: Dict[str, Set[str]] = field(default_factory=dict) @property def total_missing(self) -> int: """Total count of missing keys.""" return len(self.missing_keys) @property def total_unused(self) -> int: """Total count of unused keys.""" return len(self.unused_keys) @property def total_matching(self) -> int: """Total count of matching keys.""" return len(self.matching_keys) @property def is_valid(self) -> bool: """Check if there are no missing or unused keys.""" return len(self.missing_keys) == 0 and len(self.unused_keys) == 0 class Validator: """Validate extracted i18n keys against locale files.""" def __init__(self): """Initialize the validator.""" def validate( self, extracted_keys: Set[str], locale_keys: Dict[str, Set[str]], ) -> ValidationResult: """Validate extracted keys against locale keys. Args: extracted_keys: Set of keys extracted from source code. locale_keys: Dictionary mapping locale names to their key sets. Returns: ValidationResult with missing, unused, and matching keys. """ if not locale_keys: return ValidationResult( missing_keys=extracted_keys, unused_keys=set(), matching_keys=set(), ) result = ValidationResult() for locale, keys in locale_keys.items(): locale_missing = extracted_keys - keys locale_unused = keys - extracted_keys locale_matching = keys & extracted_keys result.missing_keys.update(locale_missing) result.unused_keys.update(locale_unused) result.matching_keys.update(locale_matching) result.extra_keys_per_locale[locale] = locale_unused return result def validate_for_locale( self, extracted_keys: Set[str], locale_keys: Set[str], locale_name: str = "", ) -> ValidationResult: """Validate keys against a single locale. Args: extracted_keys: Set of keys extracted from source code. locale_keys: Set of keys in the locale file. locale_name: Name of the locale (for reporting). Returns: ValidationResult for the single locale. """ missing_keys = extracted_keys - locale_keys unused_keys = locale_keys - extracted_keys matching_keys = locale_keys & extracted_keys return ValidationResult( missing_keys=missing_keys, unused_keys=unused_keys, matching_keys=matching_keys, ) def get_summary(self, result: ValidationResult) -> Dict[str, int]: """Get a summary of the validation result. Args: result: ValidationResult to summarize. Returns: Dictionary with summary statistics. """ return { "missing_keys": len(result.missing_keys), "unused_keys": len(result.unused_keys), "matching_keys": len(result.matching_keys), "total_keys_in_code": len(result.missing_keys) + len(result.matching_keys), "total_keys_in_locale": len(result.unused_keys) + len(result.matching_keys), }