diff --git a/.github/workflows/source-platform-smoke.yml b/.github/workflows/source-platform-smoke.yml index f2759aa..2b7423c 100644 --- a/.github/workflows/source-platform-smoke.yml +++ b/.github/workflows/source-platform-smoke.yml @@ -54,7 +54,7 @@ jobs: - name: Install Python deps (CI subset) run: | python -m pip install --upgrade pip - python -m pip install "PySide6>=6.5.0" "PyMuPDF>=1.23.0" "pikepdf>=8.0.0" "pytesseract>=0.3.10" "Pillow>=10.0.0" "python-docx>=1.1.0" "chardet>=5.0.0" "rapidfuzz>=3.0.0" pytest pytest-subtests ruff + python -m pip install "PySide6>=6.5.0" "PyMuPDF>=1.23.0" "pikepdf>=8.0.0" "pytesseract>=0.3.10" "Pillow>=10.0.0" "python-docx>=1.1.0" "chardet>=5.0.0" "rapidfuzz>=3.0.0" "tomli>=2.0; python_version < '3.11'" pytest pytest-subtests ruff - name: Run ruff linting check run: | diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 5b139c0..d4da4f7 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -4,11 +4,15 @@ import json import re -import tomllib import xml.etree.ElementTree as ET from pathlib import Path from PIL import Image +try: + import tomllib +except ModuleNotFoundError: # Python 3.10 + import tomli as tomllib + ROOT = Path(__file__).resolve().parents[1] @@ -285,8 +289,8 @@ def test_ci_workflow_integrity(): assert "ubuntu-latest" in content assert "macos-latest" in content assert "windows-latest" in content - assert "actions/checkout@v4" in content - assert "actions/setup-python@v5" in content + assert re.search(r"actions/checkout@v\d+", content) + assert re.search(r"actions/setup-python@v\d+", content) assert "pytest" in content assert "concurrency:" in content assert "cancel-in-progress: true" in content diff --git a/tests/test_pdf_collection.py b/tests/test_pdf_collection.py index 8c9de2c..a1f2653 100644 --- a/tests/test_pdf_collection.py +++ b/tests/test_pdf_collection.py @@ -20,6 +20,34 @@ ) +@pytest.fixture(scope="session") +def collection_app(): + """Keep Qt alive until every collection dialog has been destroyed.""" + from PySide6.QtWidgets import QApplication + + return QApplication.instance() or QApplication([]) + + +@pytest.fixture +def collection_dialog_factory(collection_app): + from PySide6.QtCore import QCoreApplication, QEvent + from gui.dialogs.collection_export_dialog import CollectionExportDialog + + dialogs = [] + + def create(**kwargs): + dialog = CollectionExportDialog(None, **kwargs) + dialogs.append(dialog) + return dialog + + yield create + for dialog in dialogs: + dialog.close() + dialog.deleteLater() + QCoreApplication.sendPostedEvents(None, QEvent.Type.DeferredDelete) + collection_app.processEvents() + + @pytest.fixture def make_pdf(tmp_path): """Erzeugt eine Test-PDF mit angegebener Seitenzahl.""" @@ -176,17 +204,13 @@ def test_export_collection_all_files_missing(tmp_path): assert not out_pdf.exists() -def test_dialog_reorder_and_filter(make_pdf): +def test_dialog_reorder_and_filter(make_pdf, collection_dialog_factory): from PySide6.QtCore import Qt - from PySide6.QtWidgets import QApplication - from gui.dialogs.collection_export_dialog import CollectionExportDialog - - _ = QApplication.instance() or QApplication([]) pdf1 = make_pdf("alpha.pdf", pages=1) pdf2 = make_pdf("beta.pdf", pages=1) - dialog = CollectionExportDialog(None, initial_documents=[pdf1, pdf2]) + dialog = collection_dialog_factory(initial_documents=[pdf1, pdf2]) assert dialog._list_widget.count() == 2 # Zweites Item auswählen und nach oben schieben @@ -207,17 +231,14 @@ def test_dialog_reorder_and_filter(make_pdf): dialog.close() -def test_dialog_export_execution(monkeypatch, tmp_path, make_pdf): - from PySide6.QtWidgets import QApplication, QFileDialog, QMessageBox - from gui.dialogs.collection_export_dialog import CollectionExportDialog - - _ = QApplication.instance() or QApplication([]) +def test_dialog_export_execution(monkeypatch, tmp_path, make_pdf, collection_dialog_factory): + from PySide6.QtWidgets import QFileDialog, QMessageBox p1 = make_pdf("part1.pdf", pages=2) p2 = make_pdf("part2.pdf", pages=2) out_target = tmp_path / "gui_sammel.pdf" - dialog = CollectionExportDialog(None, initial_documents=[p1, p2], current_theme="Projekt") + dialog = collection_dialog_factory(initial_documents=[p1, p2], current_theme="Projekt") # Mocke Dateidialog und Nachfrage zum Öffnen monkeypatch.setattr( diff --git a/tests/test_security_license_contract.py b/tests/test_security_license_contract.py index ed48644..9b22921 100644 --- a/tests/test_security_license_contract.py +++ b/tests/test_security_license_contract.py @@ -15,10 +15,14 @@ import os import re -import tomllib import unittest from pathlib import Path +try: + import tomllib +except ModuleNotFoundError: # Python 3.10 + import tomli as tomllib + ROOT = Path(__file__).resolve().parents[1]