workbench / tests /unit /test_ocr_pipeline.py
GitHub Actions
Initial ZeroGPU deployment with spaces shim
7f9dfed
Raw
History Blame Contribute Delete
6.86 kB
from __future__ import annotations
import json
import tempfile
import unittest
from pathlib import Path
from datasets.field_notes import FieldNote, FieldNoteStore
from datasets.ocr import (
export_corrected_ocr_notes,
import_uncertain_predictions,
load_ocr_predictions,
ocr_import_summary,
uncertain_predictions,
)
from ui.notes_tab import import_ocr_predictions, preview_ocr_predictions
class OCRPipelineTest(unittest.TestCase):
def test_loads_ocr_predictions_from_jsonl(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "ocr.jsonl"
path.write_text(
json.dumps(
{
"source_path": "receipt.png",
"text": "Total 12.30",
"confidence": 0.91,
"page": 1,
}
)
+ "\n",
encoding="utf-8",
)
predictions = load_ocr_predictions(path)
self.assertEqual(len(predictions), 1)
self.assertEqual(predictions[0].source_path, "receipt.png")
self.assertEqual(predictions[0].confidence, 0.91)
self.assertEqual(predictions[0].page, "1")
def test_loads_ocr_predictions_from_csv_alias_columns(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "ocr.csv"
path.write_text(
"image_path,prediction,score\nlabel.png,Best before 2026,0.72\n",
encoding="utf-8",
)
predictions = load_ocr_predictions(path)
self.assertEqual(predictions[0].source_path, "label.png")
self.assertEqual(predictions[0].text, "Best before 2026")
self.assertEqual(predictions[0].confidence, 0.72)
def test_filters_uncertain_predictions_by_threshold_and_empty_text(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "ocr.jsonl"
rows = [
{"source_path": "a.png", "text": "clear", "confidence": 0.95},
{"source_path": "b.png", "text": "maybe", "confidence": 0.7},
{"source_path": "c.png", "text": "", "confidence": 0.99},
]
path.write_text(
"\n".join(json.dumps(row) for row in rows),
encoding="utf-8",
)
uncertain = uncertain_predictions(load_ocr_predictions(path), 0.8)
self.assertEqual([item.source_path for item in uncertain], ["b.png", "c.png"])
def test_imports_uncertain_predictions_to_field_notes(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
predictions_path = Path(tmp) / "ocr.jsonl"
predictions_path.write_text(
"\n".join(
[
json.dumps(
{
"source_path": "uncertain.png",
"text": "hel1o",
"confidence": 0.5,
}
),
json.dumps(
{
"source_path": "confident.png",
"text": "hello",
"confidence": 0.99,
}
),
]
),
encoding="utf-8",
)
store = FieldNoteStore(Path(tmp) / "field_notes.csv")
imported = import_uncertain_predictions(
store,
load_ocr_predictions(predictions_path),
"minicpm5_1b",
confidence_threshold=0.8,
)
notes = store.list_notes(tag="ocr")
self.assertEqual(imported, 1)
self.assertEqual(len(notes), 1)
self.assertEqual(notes[0].response, "hel1o")
self.assertEqual(notes[0].image_path, "uncertain.png")
self.assertFalse(notes[0].use_for_training)
def test_exports_corrected_ocr_notes(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
store = FieldNoteStore(Path(tmp) / "field_notes.csv")
store.save(
FieldNote.create(
model_id="minicpm5_1b",
prompt="Review OCR text for receipt.png.",
response="Tota1",
correction="Total",
tags="ocr,uncertain",
image_path="receipt.png",
)
)
store.save(
FieldNote.create(
model_id="minicpm5_1b",
prompt="Other correction",
response="abc",
correction="abc",
tags="demo",
)
)
output = export_corrected_ocr_notes(store, Path(tmp) / "ocr_corrections.jsonl")
rows = [json.loads(line) for line in output.read_text(encoding="utf-8").splitlines()]
self.assertEqual(len(rows), 1)
self.assertEqual(rows[0]["source_path"], "receipt.png")
self.assertEqual(rows[0]["predicted_text"], "Tota1")
self.assertEqual(rows[0]["corrected_text"], "Total")
def test_ocr_import_summary_reports_uncertain_sample(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "ocr.jsonl"
path.write_text(
json.dumps({"source_path": "a.png", "text": "?", "confidence": 0.1}),
encoding="utf-8",
)
summary = ocr_import_summary(path, 0.8)
self.assertEqual(summary["rows"], 1)
self.assertEqual(summary["uncertain_rows"], 1)
self.assertEqual(summary["confidence_threshold"], 0.8)
def test_notes_tab_ocr_preview_callback_reports_missing_path(self) -> None:
self.assertEqual(
preview_ocr_predictions("", 0.8),
{"error": "Enter a local OCR prediction file path."},
)
def test_notes_tab_ocr_import_callback_binds_store(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "ocr.jsonl"
path.write_text(
json.dumps({"source_path": "a.png", "text": "?", "confidence": 0.1}),
encoding="utf-8",
)
store = FieldNoteStore(Path(tmp) / "field_notes.csv")
status = import_ocr_predictions(store, "minicpm5_1b", str(path), 0.8)
self.assertIn("Imported 1 uncertain OCR predictions", status)
self.assertEqual(len(store.list_notes(tag="ocr")), 1)
if __name__ == "__main__":
unittest.main()