#!/usr/bin/env python3 """ wikParse Test Framework ======================= Comprehensive testing framework for all wikParse components. """ import json import os import sys import tempfile import sqlite3 import pathlib from typing import Dict, List, Any, Optional # Add scripts directory to path SCRIPT_DIR = pathlib.Path(__file__).parent.parent / "scripts" sys.path.insert(0, str(SCRIPT_DIR)) from transform_wiktionary import WiktionaryTransformer from InflectionProcessor import InflectionProcessor, UniversalInflectionCompressor class TestFramework: """Base test framework with common utilities.""" def __init__(self): self.test_results = { "passed": 0, "failed": 0, "errors": [], "warnings": [] } self.temp_files = [] def assert_equal(self, actual, expected, message=""): """Assert that two values are equal.""" if actual == expected: self.test_results["passed"] += 1 return True else: self.test_results["failed"] += 1 error_msg = f"Assertion failed: {message}" error_msg += f"\n Expected: {expected}" error_msg += f"\n Actual: {actual}" self.test_results["errors"].append(error_msg) return False def assert_not_equal(self, actual, expected, message=""): """Assert that two values are not equal.""" if actual != expected: self.test_results["passed"] += 1 return True else: self.test_results["failed"] += 1 error_msg = f"Assertion failed: {message}" error_msg += f"\n Values should not be equal but both are: {actual}" self.test_results["errors"].append(error_msg) return False def assert_true(self, condition, message=""): """Assert that a condition is true.""" if condition: self.test_results["passed"] += 1 return True else: self.test_results["failed"] += 1 error_msg = f"Assertion failed: {message}" error_msg += f"\n Condition is False" self.test_results["errors"].append(error_msg) return False def assert_false(self, condition, message=""): """Assert that a condition is false.""" if not condition: self.test_results["passed"] += 1 return True else: self.test_results["failed"] += 1 error_msg = f"Assertion failed: {message}" error_msg += f"\n Condition is True" self.test_results["errors"].append(error_msg) return False def assert_is_instance(self, obj, cls, message=""): """Assert that an object is an instance of a class.""" if isinstance(obj, cls): self.test_results["passed"] += 1 return True else: self.test_results["failed"] += 1 error_msg = f"Assertion failed: {message}" error_msg += f"\n Expected type: {cls}" error_msg += f"\n Actual type: {type(obj)}" self.test_results["errors"].append(error_msg) return False def assert_in(self, member, container, message=""): """Assert that a member is in a container.""" if member in container: self.test_results["passed"] += 1 return True else: self.test_results["failed"] += 1 error_msg = f"Assertion failed: {message}" error_msg += f"\n Member not found in container" self.test_results["errors"].append(error_msg) return False def assert_not_in(self, member, container, message=""): """Assert that a member is not in a container.""" if member not in container: self.test_results["passed"] += 1 return True else: self.test_results["failed"] += 1 error_msg = f"Assertion failed: {message}" error_msg += f"\n Member found in container but should not be" self.test_results["errors"].append(error_msg) return False def create_temp_file(self, content="", suffix=".json"): """Create a temporary file and return its path.""" temp_file = tempfile.NamedTemporaryFile(mode='w', suffix=suffix, delete=False) if content: temp_file.write(content) temp_file.close() self.temp_files.append(temp_file.name) return temp_file.name def cleanup(self): """Clean up temporary files.""" for file_path in self.temp_files: try: os.unlink(file_path) except: pass self.temp_files = [] def print_summary(self): """Print test summary.""" total = self.test_results["passed"] + self.test_results["failed"] print("\n" + "="*60) print("TEST SUMMARY") print("="*60) print(f"Total tests: {total}") print(f"Passed: {self.test_results['passed']}") print(f"Failed: {self.test_results['failed']}") if total > 0: success_rate = (self.test_results['passed'] / total) * 100 print(f"Success rate: {success_rate:.1f}%") if self.test_results['errors']: print(f"\nErrors: {len(self.test_results['errors'])}") for error in self.test_results['errors']: print(f" - {error}") if self.test_results['warnings']: print(f"\nWarnings: {len(self.test_results['warnings'])}") for warning in self.test_results['warnings']: print(f" - {warning}") return self.test_results["failed"] == 0 class SchemaValidator: """Schema validation utilities.""" @staticmethod def validate_universal_schema(entry: Dict[str, Any]) -> bool: """Validate an entry against the universal schema.""" required_fields = ["word", "pos", "senses"] # Check required fields for field in required_fields: if field not in entry: return False # Check field types if not isinstance(entry["word"], str): return False if not isinstance(entry["pos"], str): return False if not isinstance(entry["senses"], list): return False # Validate senses structure for sense in entry["senses"]: if not isinstance(sense, dict): return False return True class TestDataLoader: """Load test data from various sources.""" @staticmethod def load_sample_data(sample_name: str) -> Dict[str, Any]: """Load sample data from samples directory.""" samples_dir = pathlib.Path(__file__).parent.parent / "samples" # Try different paths possible_paths = [ samples_dir / "german" / f"{sample_name}.json", samples_dir / "french" / f"{sample_name}.json", samples_dir / f"{sample_name}.json" ] for path in possible_paths: if path.exists(): with open(path, 'r', encoding='utf-8') as f: return json.load(f) raise FileNotFoundError(f"Sample data not found: {sample_name}") @staticmethod def load_jsonl_data(file_path: str) -> List[Dict[str, Any]]: """Load JSONL data from file.""" entries = [] with open(file_path, 'r', encoding='utf-8') as f: for line in f: if line.strip(): entries.append(json.loads(line.strip())) return entries if __name__ == "__main__": print("wikParse Test Framework") print("Run specific test modules instead of this framework directly.")