import os import shutil import subprocess import pytest # Let widget-level tests run headless; harmless for the non-GUI tests. os.environ.setdefault("QT_QPA_PLATFORM", "offscreen") @pytest.fixture(scope="session") def qapp(): """A Qt application so QObject/QTimer and real widgets work in tests. Prefers a GUI QApplication (offscreen) so widget tests are possible; QApplication is a QCoreApplication, so existing non-GUI tests are unaffected. Falls back to QCoreApplication if no GUI platform is available. """ from PyQt6.QtCore import QCoreApplication inst = QCoreApplication.instance() if inst is not None: return inst try: from PyQt6.QtWidgets import QApplication return QApplication([]) except Exception: return QCoreApplication([]) def _generate_audio(path, codec_args): """Generate a 1-second sine-wave audio file with ffmpeg.""" if shutil.which("ffmpeg") is None: pytest.skip("ffmpeg not available to generate audio fixtures") result = subprocess.run( ["ffmpeg", "-y", "-f", "lavfi", "-i", "sine=frequency=440:duration=1", *codec_args, str(path)], capture_output=True, ) if result.returncode != 0: pytest.skip(f"ffmpeg could not generate {path.suffix} fixture") return path @pytest.fixture def mp3_file(tmp_path): return _generate_audio(tmp_path / "test.mp3", ["-codec:a", "libmp3lame", "-b:a", "64k"]) @pytest.fixture def m4a_file(tmp_path): return _generate_audio(tmp_path / "test.m4a", ["-codec:a", "aac", "-b:a", "64k"]) @pytest.fixture def flac_file(tmp_path): return _generate_audio(tmp_path / "test.flac", ["-codec:a", "flac"]) @pytest.fixture def jpeg_bytes(tmp_path): """A tiny valid JPEG for artwork tests.""" if shutil.which("ffmpeg") is None: pytest.skip("ffmpeg not available to generate image fixture") path = tmp_path / "art.jpg" result = subprocess.run( ["ffmpeg", "-y", "-f", "lavfi", "-i", "color=red:size=8x8", "-frames:v", "1", str(path)], capture_output=True, ) if result.returncode != 0: pytest.skip("ffmpeg could not generate jpeg fixture") return path.read_bytes()