""" Unit tests for the engine layer: WhisperBackbone, AdapterManager, Transcriber. These tests use mocks so they run without GPU or downloaded model weights. """ from __future__ import annotations from unittest.mock import MagicMock, patch import numpy as np import pytest class TestWhisperBackbone: def test_raises_before_load(self, tmp_path): """Accessing model or processor before load() should raise RuntimeError.""" import yaml config = {"model": {"id": "openai/whisper-large-v3-turbo"}, "training": {}, "audio": {}, "paths": {}} config_path = tmp_path / "base_config.yaml" config_path.write_text(yaml.dump(config)) from src.engine.whisper_base import WhisperBackbone backbone = WhisperBackbone(str(config_path)) with pytest.raises(RuntimeError): _ = backbone.model with pytest.raises(RuntimeError): _ = backbone.processor def test_model_id_read_from_config(self, tmp_path): import yaml config = {"model": {"id": "test-model-id"}, "training": {}, "audio": {}, "paths": {}} config_path = tmp_path / "base_config.yaml" config_path.write_text(yaml.dump(config)) from src.engine.whisper_base import WhisperBackbone backbone = WhisperBackbone(str(config_path)) assert backbone.model_id == "test-model-id" class TestAdapterManager: def _make_mock_model(self): mock_model = MagicMock() mock_model.peft_config = {} return mock_model def test_register_missing_path(self, tmp_path): """Registering a non-existent path should log a warning but not raise.""" from src.engine.adapter_manager import AdapterManager model = self._make_mock_model() manager = AdapterManager(model, {}) # Should not raise manager.register("bam", str(tmp_path / "nonexistent")) assert "bam" in manager.list_available() def test_list_available(self, tmp_path): from src.engine.adapter_manager import AdapterManager bam_path = tmp_path / "bam" bam_path.mkdir() ful_path = tmp_path / "ful" ful_path.mkdir() model = self._make_mock_model() manager = AdapterManager(model, {}) manager.register("bam", str(bam_path)) manager.register("ful", str(ful_path)) available = manager.list_available() assert "bam" in available assert "ful" in available def test_unregistered_language_raises(self): from src.engine.adapter_manager import AdapterManager model = self._make_mock_model() manager = AdapterManager(model, {}) with pytest.raises(KeyError): manager.load_adapter("xyz") class TestTranscriptionResult: def test_dataclass_fields(self): from src.engine.transcriber import TranscriptionResult result = TranscriptionResult( text="test", language="bam", duration_s=5.0, processing_time_ms=120, ) assert result.text == "test" assert result.confidence is None