//! Integration: engine-side contracts behind the F1–F28 labels/selectors. //! These use the test StubEngine; real recognition is covered by //! `tests/real_ocr.rs`. Nothing here exercises the Makepad widget. use nigig_ocr::{ format_processing_time, progress_label, run_all_pages, run_current_page, write_pdf_all, write_pdf_single, write_txt_all, write_txt_single, CaptureMode, CaptureRect, Clipboard, FileList, InMemoryClipboard, OcrLanguage, RegionState, Settings, StubEngine, UiAction, UiState, }; /// A real (decodable) PNG — signature-only bytes are now rejected. fn png() -> Vec { include_bytes!("fixtures/hello.png").to_vec() } fn pdf() -> Vec { b"%PDF-1.4 test".to_vec() } #[test] fn f1_drop_images_and_pdfs() { let mut s = UiState::new(); assert!(s.apply(UiAction::DropBytes(png())).starts_with("Added")); assert!(s .apply(UiAction::DropPdfPages(pdf(), 2)) .contains("2 pages")); assert_eq!(s.files.len(), 3); } #[test] fn f2_f3_capture_single_and_multi() { let single = RegionState::new(CaptureMode::Single, true); let multi = RegionState::new(CaptureMode::Multi, true); assert!(single.should_close_after_capture()); assert!(!multi.should_close_after_capture()); let r = CaptureRect::new(0.0, 0.0, 100.0, 50.0); assert!(r.is_valid() && r.area() == 5000.0); } #[test] fn f7_f8_do_and_batch_with_tolerance() { let e = StubEngine::with_text("t"); let mut l = FileList::new(); l.add(png()).unwrap(); l.add(png()).unwrap(); let mut items: Vec = (0..l.len()).map(|i| l.get(i).unwrap().clone()).collect(); let r = run_current_page(&e, &mut items, 0).unwrap(); assert_eq!(r.text, "t"); let rs = run_all_pages(&e, &mut items); assert_eq!(rs.len(), 2); assert!(rs.iter().all(|x| x.is_ok())); } #[test] fn f9_f10_f11_options_round_trip_via_ui() { let mut s = UiState::new(); s.apply(UiAction::DropBytes(png())); s.apply(UiAction::Language(OcrLanguage::German)); s.apply(UiAction::FastToggle(true)); s.apply(UiAction::CorrectionToggle(false)); let f = s.files.get(0).unwrap(); assert_eq!(f.options.language, OcrLanguage::German); assert_eq!(f.options.level, nigig_ocr::OcrLevel::Fast); assert!(!f.options.language_correction); assert_eq!(OcrLanguage::all_popup().len(), 8); } #[test] fn f13_f14_rotate_and_overlay() { let mut s = UiState::new(); s.apply(UiAction::DropBytes(png())); s.apply(UiAction::RotateRight); assert_eq!(s.files.get(0).unwrap().rotate_degree, 90); let before = s.overlay_on; s.apply(UiAction::OverlayToggle); assert_ne!(s.overlay_on, before); } #[test] fn f15_f16_labels_and_progress() { assert_eq!(progress_label(1, 2), "Running OCR... 1/2"); assert!(format_processing_time(42).contains("42 ms")); assert_eq!( nigig_ocr::result::result_count_label(0), "No results found." ); } #[test] fn f17_delete_current_and_all() { let mut s = UiState::new(); s.apply(UiAction::DropBytes(png())); s.apply(UiAction::DropBytes(png())); s.apply(UiAction::DeleteCurrent); assert_eq!(s.files.len(), 1); s.apply(UiAction::DeleteAll); assert!(s.files.is_empty()); assert_eq!(s.last_message, "All Files Deleted"); } #[test] fn f18_f19_f20_f21_export_copy_share() { let mut c = InMemoryClipboard::default(); c.copy_text("abc").unwrap(); assert_eq!(c.last_copied().as_deref(), Some("abc")); let d = std::env::temp_dir().join(format!("ocr-parity-{}", std::process::id())); let _ = std::fs::create_dir_all(&d); write_txt_single("hi", &d.join("a.txt")).unwrap(); write_txt_all(&[("a", "hi")], &d.join("all.txt")).unwrap(); write_pdf_single("hi", &d.join("a.pdf")).unwrap(); write_pdf_all(&["hi", "yo"], &d.join("all.pdf")).unwrap(); let mut s = UiState::new(); assert_eq!(s.apply(UiAction::Share), "Share is not implemented yet"); let _ = std::fs::remove_dir_all(&d); } #[test] fn f23_f24_settings_and_theme() { let s = Settings { theme: nigig_ocr::settings::Theme::Dark, ..Settings::default() }; let d = std::env::temp_dir().join(format!("ocr-parity-set-{}", std::process::id())); let _ = std::fs::create_dir_all(&d); let f = d.join("p.ini"); s.save(&f).unwrap(); assert_eq!(Settings::load(&f), s); let _ = std::fs::remove_dir_all(&d); }