Files
creator/backend/tests/test_pdf_convert.py
2026-07-03 11:45:27 +02:00

72 lines
2.5 KiB
Python

"""PDF→Text-Konvertierung: pymupdf4llm primär, pdftotext-Fallback, mtime-Cache."""
import os
import time
import fitz # PyMuPDF
import pytest
import blocks as blx
def _mini_pdf(path, text="Approximationsalgorithmen sind wichtig."):
doc = fitz.open()
page = doc.new_page()
page.insert_text((72, 72), text, fontsize=12)
doc.save(str(path))
doc.close()
def test_convert_writes_markdown_txt(tmp_path):
_mini_pdf(tmp_path / "skript.pdf")
blx._convert_pdfs(tmp_path)
out = (tmp_path / "skript.txt").read_text(encoding="utf-8")
assert "Approximationsalgorithmen" in out
def test_cache_skips_fresh_txt(tmp_path):
_mini_pdf(tmp_path / "a.pdf")
marker = tmp_path / "a.txt"
marker.write_text("MARKER", encoding="utf-8")
now = time.time() + 60
os.utime(marker, (now, now))
blx._convert_pdfs(tmp_path)
assert marker.read_text(encoding="utf-8") == "MARKER" # nicht neu konvertiert
def test_fallback_to_pdftotext(tmp_path, monkeypatch):
_mini_pdf(tmp_path / "b.pdf")
monkeypatch.setattr(blx, "_pdf_markdown", lambda p: None)
monkeypatch.setattr(blx, "_pdf_plaintext", lambda p: "fallback")
blx._convert_pdfs(tmp_path)
assert (tmp_path / "b.txt").read_text(encoding="utf-8") == "fallback"
def test_ocr_languages_from_tessdata(tmp_path, monkeypatch):
import pymupdf
monkeypatch.setattr(pymupdf, "get_tessdata", lambda: str(tmp_path))
assert blx._ocr_languages() is None # keine Sprachdaten → OCR aus
(tmp_path / "eng.traineddata").touch()
assert blx._ocr_languages() == "eng"
(tmp_path / "deu.traineddata").touch()
assert blx._ocr_languages() == "deu+eng"
monkeypatch.setattr(pymupdf, "get_tessdata", lambda: (_ for _ in ()).throw(RuntimeError()))
assert blx._ocr_languages() is None
def test_fidelity_guard_prefers_faithful_plaintext():
plain = "Definition. P = {L ⊆ Σ | A ∈ L} und ≤ sowie häufig über. " * 20
# Markdown verlor die Formeln (Symbole weg) → plain gewinnt
md_lossy = "Definition. und sowie h¨aufig ¨uber. " * 20
text, tool = blx._pick_conversion(md_lossy, plain)
assert tool == "pdftotext"
# Markdown treu (Symbole + Länge da) → md gewinnt
md_ok = "# Def\n" + plain
text, tool = blx._pick_conversion(md_ok, plain)
assert tool == "pymupdf4llm"
# nur eine Quelle verfügbar
assert blx._pick_conversion(None, plain)[1] == "pdftotext"
assert blx._pick_conversion(md_ok, None)[1] == "pymupdf4llm"
assert blx._pick_conversion(None, None) is None