pdfcraft/crates/ui-egui/tests/ocr.rs

66 lines
2.7 KiB
Rust

//! Scan & OCR ▸ Recognize text in the real shell (egui_kittest): the dialog, the run and its
//! result (skipped without the OCR models: `cargo xtask models`).
use egui_kittest::Harness;
use egui_kittest::kittest::Queryable;
use printcraft_engine::{Session, export};
use printcraft_ui_egui::PrintCraftApp;
/// A one-page PDF that is only a picture of a sentence.
fn scan() -> Vec<u8> {
let mut s = Session::new();
let text = s.create_from_text("t", "Recognize these scanned words").unwrap();
let id = s.open("text.pdf", None, text, None).unwrap();
let png = export::Exporter::new(s.get(id).unwrap()).png(0, 150.0).unwrap();
s.create_from_images(&[("scan.png".into(), png)]).unwrap().to_vec()
}
#[test]
fn recognize_text_dialog_adds_searchable_text() {
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(|_cc| {
let mut app = PrintCraftApp::new();
app.open_bytes("scan.pdf", None, scan()).unwrap();
app.run_inline = true;
app
});
h.run_steps(4);
assert!(h.state_mut().execute("ocr.recognize"));
h.run_steps(2);
h.get_by_label("Document language");
h.get_by_label("Output");
if !printcraft_engine::ocr::available() {
eprintln!("skipped: OCR models not installed");
return;
}
h.get_by_label("Recognize text").click();
h.run_steps(3);
assert!(h.state().ocr_run.is_none(), "finished");
let toast = h.state().toast.clone().unwrap().0;
assert!(toast.starts_with("Recognized ") && toast.contains("on 1 page"), "{toast}");
let app = h.state();
let id = app.active_ids().unwrap().1;
assert_eq!(app.session.get(id).unwrap().can_undo(), Some("Recognize text"));
}
#[test]
fn recognize_text_in_multiple_files_writes_searchable_copies() {
if !printcraft_engine::ocr::available() {
eprintln!("skipped: OCR models not installed");
return;
}
let dir = std::env::temp_dir().join(format!("printcraft-ocr-ui-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).unwrap();
let mut app = PrintCraftApp::new();
app.run_inline = true;
app.export_dir_override = Some(dir.to_string_lossy().into_owned());
app.use_files(printcraft_ui_egui::FilePurpose::Ocr, vec![("one.pdf".into(), scan()), ("two.pdf".into(), scan())]);
assert!(app.ocr_batch.is_none(), "finished");
let toast = app.toast.clone().unwrap().0;
assert!(toast.starts_with("Recognized ") && toast.ends_with("in 2 files"), "{toast}");
for name in ["one.pdf", "two.pdf"] {
let bytes = std::fs::read(dir.join(name)).unwrap();
assert!(bytes.len() > scan().len(), "an incremental update was appended");
}
}