commits
tags
"""rpa/ocr.py – textlager-PDF, mönster-utplock, värde-nära-etikett."""
import pytest
from rpa import ocr
def test_apply_pattern_whole_match_by_default():
txt = "Rad 1\nPersonnummer 19850101-1234 skräp\nRad 3"
assert ocr.apply_pattern(txt, r"(19|20)?\d{6}[-+]?\d{4}") == "19850101-1234"
assert ocr.apply_pattern(txt, r"\d{4}-\d{2}-\d{2}") == ""
def test_apply_pattern_named_group_wins():
txt = "Läkare: Anna Andersson (leg)"
assert ocr.apply_pattern(txt, r"Läkare:\s*(?P<value>[^()]+)").strip() == "Anna Andersson"
def test_apply_pattern_no_match_empty():
assert ocr.apply_pattern("inget här", r"\d{10}") == ""
def test_value_near_same_line():
txt = "Avsändare: Vårdcentralen Nordstan\nStatus Öppet"
assert ocr.value_near(txt, [], "Avsändare", "same_line") == "Vårdcentralen Nordstan"
assert ocr.value_near(txt, [], "Status", "same_line") == "Öppet"
assert ocr.value_near(txt, [], "Saknas", "same_line") == ""
def test_value_near_below_uses_word_boxes():
words = [
{"text": "Personnummer", "x": 10, "y": 10, "w": 90, "h": 12},
{"text": "19850101-1234", "x": 12, "y": 40, "w": 100, "h": 12},
{"text": "Namn", "x": 300, "y": 10, "w": 40, "h": 12},
]
text = "Personnummer Namn\n19850101-1234"
assert ocr.value_near(text, words, "Personnummer", "below") == "19850101-1234"
def test_pdf_text_layer_path(tmp_path):
"""En PDF med textlager ska läsas utan OCR (winocr rörs aldrig)."""
pymupdf = pytest.importorskip("pymupdf")
p = tmp_path / "remiss.pdf"
doc = pymupdf.open()
page = doc.new_page()
page.insert_text((72, 72), "Personnummer: 19850101-1234\nRemissdatum: 2026-01-15", fontsize=12)
doc.save(str(p))
doc.close()
text = ocr.pdf_to_text(p, "sv-SE")
assert "19850101-1234" in text
assert "2026-01-15" in text
def test_image_to_text_parses_winocr_shape(monkeypatch):
fake = {
"text": "Personnummer: 19850101-1234",
"lines": [{
"text": "Personnummer: 19850101-1234",
"words": [
{"text": "Personnummer:", "bounding_rect": {"x": 1, "y": 2, "width": 3, "height": 4}},
{"text": "19850101-1234", "bounding_rect": {"x": 5, "y": 2, "width": 6, "height": 4}},
],
}],
}
monkeypatch.setattr(ocr, "winocr", type("M", (), {"recognize_pil_sync": staticmethod(lambda *a: fake)}))
text, words = ocr.image_to_text(object(), "sv-SE")
assert text == "Personnummer: 19850101-1234"
assert words[1]["text"] == "19850101-1234" and words[1]["x"] == 5
def test_image_to_text_missing_language_is_ocr_unavailable(monkeypatch):
def boom(*_a):
raise AssertionError('Add-WindowsCapability -Online -Name "Language.OCR~~~sv-SE~0.0.1.0"')
monkeypatch.setattr(ocr, "winocr", type("M", (), {"recognize_pil_sync": staticmethod(boom)}))
with pytest.raises(ocr.OcrUnavailable, match="Add-WindowsCapability"):
ocr.image_to_text(object(), "sv-SE")