Spaces:
Running
Running
| """Tests for the hybrid OCR engine module.""" | |
| import numpy as np | |
| import pytest | |
| from unittest.mock import MagicMock, patch | |
| from modules.vision.ocr_engine import OCREngine | |
| def sample_image() -> np.ndarray: | |
| """Create a simple test image. | |
| Returns: | |
| 100x200 BGR white image with some dark regions. | |
| """ | |
| image = np.ones((100, 200, 3), dtype=np.uint8) * 255 | |
| image[20:40, 10:80] = 0 # Dark rectangle | |
| image[50:70, 10:120] = 0 # Another dark rectangle | |
| return image | |
| class TestOCREngineInit: | |
| """Tests for OCR engine initialization.""" | |
| def test_default_initialization(self) -> None: | |
| """Test engine initialization with defaults.""" | |
| engine = OCREngine() | |
| assert engine.confidence_threshold == 0.5 | |
| assert engine.use_gpu is True | |
| def test_custom_initialization(self) -> None: | |
| """Test engine initialization with custom parameters.""" | |
| engine = OCREngine( | |
| use_gpu=False, | |
| confidence_threshold=0.7, | |
| enable_easyocr=True, | |
| enable_trocr=False, | |
| enable_tesseract=False, | |
| ) | |
| assert engine.confidence_threshold == 0.7 | |
| assert engine.use_gpu is False | |
| def test_available_engines(self) -> None: | |
| """Test getting available engines list.""" | |
| engine = OCREngine() | |
| engines = engine.get_available_engines() | |
| assert isinstance(engines, list) | |
| assert len(engines) == 4 | |
| for e in engines: | |
| assert "name" in e | |
| assert "available" in e | |
| assert "enabled" in e | |
| class TestOCREngineRecognition: | |
| """Tests for the OCR recognition flow.""" | |
| def test_recognize_no_engines_available( | |
| self, | |
| mock_ensure_pil: MagicMock, | |
| mock_load_easyocr: MagicMock, | |
| sample_image: np.ndarray, | |
| ) -> None: | |
| """Test recognition when no engines are available.""" | |
| from PIL import Image | |
| mock_ensure_pil.return_value = Image.new("RGB", (200, 100)) | |
| mock_load_easyocr.return_value = False | |
| engine = OCREngine( | |
| enable_easyocr=True, | |
| enable_trocr=False, | |
| enable_tesseract=False, | |
| ) | |
| result = engine.recognize(sample_image) | |
| assert result["text"] == "" | |
| assert result["source"] == "none" | |
| class TestOCREngineBatch: | |
| """Tests for batch processing.""" | |
| def test_recognize_batch( | |
| self, | |
| mock_recognize: MagicMock, | |
| sample_image: np.ndarray, | |
| ) -> None: | |
| """Test batch recognition.""" | |
| mock_recognize.return_value = { | |
| "text": "مرحبا", | |
| "confidence": 0.9, | |
| "source": "mock", | |
| "processing_time": 0.1, | |
| } | |
| engine = OCREngine() | |
| results = engine.recognize_batch([sample_image, sample_image]) | |
| assert len(results) == 2 | |
| assert results[0]["text"] == "مرحبا" | |
| assert results[0]["batch_index"] == 0 | |
| assert results[1]["batch_index"] == 1 | |
| class TestOCREngineCaching: | |
| """Tests for OCR result caching.""" | |
| def test_cache_key_generation(self, sample_image: np.ndarray) -> None: | |
| """Test cache key generation from image.""" | |
| from PIL import Image | |
| engine = OCREngine() | |
| pil_image = Image.fromarray(sample_image) | |
| key = engine._get_cache_key(pil_image) | |
| assert isinstance(key, str) | |
| assert len(key) > 0 | |
| def test_recognize_with_cache( | |
| self, | |
| mock_ensure_pil: MagicMock, | |
| mock_recognize: MagicMock, | |
| sample_image: np.ndarray, | |
| ) -> None: | |
| """Test cached recognition returns same result.""" | |
| from PIL import Image | |
| mock_ensure_pil.return_value = Image.fromarray(sample_image) | |
| mock_recognize.return_value = { | |
| "text": "test", | |
| "confidence": 0.9, | |
| "source": "mock", | |
| "processing_time": 0.1, | |
| } | |
| engine = OCREngine() | |
| cache = {} | |
| result1 = engine.recognize_with_cache(sample_image, cache=cache) | |
| result2 = engine.recognize_with_cache(sample_image, cache=cache) | |
| assert result1["from_cache"] is False | |
| assert result2["from_cache"] is True | |
| assert mock_recognize.call_count == 1 | |
| class TestImageConversion: | |
| """Tests for image format conversion.""" | |
| def test_ensure_pil_from_numpy(self, sample_image: np.ndarray) -> None: | |
| """Test converting numpy array to PIL Image.""" | |
| result = OCREngine._ensure_pil(sample_image) | |
| assert hasattr(result, "mode") | |
| def test_ensure_pil_grayscale(self) -> None: | |
| """Test converting grayscale numpy array to PIL Image.""" | |
| gray = np.ones((100, 100), dtype=np.uint8) * 128 | |
| result = OCREngine._ensure_pil(gray) | |
| assert hasattr(result, "mode") | |