File size: 2,200 Bytes
a3c590d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | """Fase 2, QA gate de figuras (docs/PLAN_RAG.md Fase 2, tarea 10): los problemas
8, 16, 17, 22, 24, 37 y 99 tienen su figura recortada, y la red de seguridad
vectorial no encuentra dibujos que MinerU haya dejado fuera."""
from __future__ import annotations
from pathlib import Path
import pytest
from ragsolver.rag.figures import crop_figures
from ragsolver.rag.mineru_blocks import image_locators, load_pages, render_markdown
from ragsolver.rag.parse_structure import pair_problems_and_solutions, parse_markdown
ROOT = Path(__file__).resolve().parent.parent
PDF_PATH = ROOT / "problemas resueltos olimpiadas.pdf"
MINERU_DIR = ROOT / "data/parsed/edd3436ca148/mineru"
pytestmark = pytest.mark.skipif(not (PDF_PATH.exists() and MINERU_DIR.exists()), reason="requiere el PDF y la salida de MinerU")
QA_GATE_PROBLEMS = (8, 16, 17, 22, 24, 37, 99)
def test_qa_gate_figures_are_cropped_and_linked(tmp_path):
pages = load_pages(MINERU_DIR)
figures, warnings = crop_figures(PDF_PATH, pages, tmp_path, "edd3436ca148", dpi=72)
assert warnings == [] # MinerU cubrió todos los dibujos vectoriales reales
assert len(figures) == 53 and all(Path(f.image_path).stat().st_size > 0 for f in figures)
by_id = {f.figure_id: f for f in figures}
locs = image_locators(pages, "edd3436")
cards, _ = pair_problems_and_solutions(parse_markdown(render_markdown(pages, "edd3436")))
for card in cards:
if card["item_number"] in QA_GATE_PROBLEMS:
fids = [f"edd3436ca148:fig:{locs[l][0]}:{l.rsplit(':', 1)[1]}" for l in card["image_locators"]]
assert fids and all(fid in by_id for fid in fids), f"problema {card['item_number']} sin figura"
# problema 37: seis sub-figuras con su pie ("tipo uno" ... "tipo seis")
p37 = next(c for c in cards if c["item_number"] == 37)
captions = {by_id[f"edd3436ca148:fig:{locs[l][0]}:{l.rsplit(':', 1)[1]}"].caption for l in p37["image_locators"]}
assert captions == {"tipo uno", "tipo dos", "tipo tres", "tipo cuatro", "tipo cinco", "tipo seis"}
# los dibujos vectoriales (22, 24, 37) quedan marcados como detectados por ambas vías
assert {f.detected_by for f in figures} >= {"layout", "both"}
|