"""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