whisper.cpp/examples/whisper.linux/tests/conftest.py

134 lines
3.6 KiB
Python

"""Pytest fixtures for whisper.linux tests."""
import os
import sys
import tempfile
from pathlib import Path
from unittest.mock import MagicMock, patch
import pytest
# Add project root to path so we can import the 'app' package
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
@pytest.fixture
def tmp_config_dir(tmp_path):
"""Temporary config directory."""
config_dir = tmp_path / ".config" / "whisper-linux"
config_dir.mkdir(parents=True)
return config_dir
@pytest.fixture
def tmp_config_file(tmp_config_dir):
"""Temporary config.ini with valid paths."""
config_file = tmp_config_dir / "config.ini"
config_file.write_text(
"[whisper-linux]\n"
"whisper_cli = /usr/bin/whisper-cli\n"
"model = /tmp/ggml-base.bin\n"
"models_dir = /tmp\n"
"language = ru\n"
"threads = 4\n"
"display_server = x11\n"
"audio_device = plughw:1,0\n"
"paste_keys = shift+Insert\n"
"use_clipboard_fallback = False\n"
"notification = True\n"
)
return config_file
@pytest.fixture
def mock_config(tmp_config_file, monkeypatch):
"""Config that reads from temp config file."""
import app as wl
monkeypatch.setattr(wl.config, "CONFIG_DIR", tmp_config_file.parent)
monkeypatch.setattr(wl.config, "CONFIG_FILE", tmp_config_file)
return wl.Config()
@pytest.fixture
def mock_config_wayland(mock_config):
"""Config set to Wayland."""
mock_config.display_server = "wayland"
return mock_config
@pytest.fixture
def tmp_wav_file():
"""Create a temporary WAV file for testing."""
fd, path = tempfile.mkstemp(suffix=".wav", prefix="test-whisper-")
os.write(fd, b"RIFF" + b"\x00" * 40) # Minimal WAV header stub
os.close(fd)
yield path
if os.path.exists(path):
os.unlink(path)
@pytest.fixture
def tmp_pid_file(tmp_path, monkeypatch):
"""Temporary PID file."""
import app as wl
pid_file = tmp_path / "whisper-linux.pid"
monkeypatch.setattr(wl.config, "PID_FILE", pid_file)
return pid_file
@pytest.fixture
def mock_config_stream(mock_config):
"""Config set to listen+stream mode (old 'stream' mode)."""
mock_config.input_mode = "listen"
mock_config.output_mode = "stream"
mock_config.wake_word = "дуняша"
mock_config.silence_timeout = 3.0
mock_config.vad_threshold = 300
mock_config.min_speech_ms = 500
mock_config.max_speech_s = 30.0
return mock_config
@pytest.fixture
def mock_config_hotkey_stream(mock_config):
"""Config set to hotkey+stream mode."""
mock_config.input_mode = "hotkey"
mock_config.output_mode = "stream"
mock_config.wake_word = "дуняша"
mock_config.silence_timeout = 3.0
mock_config.vad_threshold = 300
mock_config.min_speech_ms = 500
mock_config.max_speech_s = 30.0
return mock_config
@pytest.fixture
def mock_config_listen_batch(mock_config):
"""Config set to listen+batch mode."""
mock_config.input_mode = "listen"
mock_config.output_mode = "batch"
mock_config.wake_word = "дуняша"
mock_config.silence_timeout = 3.0
mock_config.vad_threshold = 300
mock_config.min_speech_ms = 500
mock_config.max_speech_s = 30.0
return mock_config
@pytest.fixture
def silence_pcm():
"""Return 1 second of silence (s16le mono 16kHz)."""
return b"\x00\x00" * 16000
@pytest.fixture
def speech_pcm():
"""Return 1 second of loud 'speech' (s16le mono 16kHz, high amplitude sine)."""
import array, math
samples = array.array("h")
for i in range(16000):
samples.append(int(10000 * math.sin(2 * math.pi * 440 * i / 16000)))
return samples.tobytes()