use oxidize_pdf::memory::{
LazyDocument, MemoryOptions, ProcessingAction, ProcessingEvent, StreamProcessor,
StreamingOptions,
};
use oxidize_pdf::parser::PdfReader;
use std::io::Cursor;
#[test]
fn test_lazy_document_basic() {
let pdf_data = b"%PDF-1.7\n1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n2 0 obj\n<< /Type /Pages /Kids [] /Count 0 >>\nendobj\n%%EOF\n";
let cursor = Cursor::new(pdf_data);
let reader = match PdfReader::new(cursor) {
Ok(r) => r,
Err(_) => {
println!("Skipping test - cannot create PdfReader from minimal PDF");
return;
}
};
let options = MemoryOptions::default()
.with_lazy_loading(true)
.with_cache_size(10);
let lazy_doc = match LazyDocument::new(reader, options) {
Ok(doc) => doc,
Err(_) => {
println!("Skipping test - minimal PDF not sufficient for LazyDocument");
return;
}
};
assert_eq!(lazy_doc.page_count(), 0);
let stats = lazy_doc.memory_stats();
assert_eq!(stats.cache_hits, 0);
assert_eq!(stats.cache_misses, 0);
}
#[test]
fn test_memory_options_configurations() {
let small = MemoryOptions::small_file();
assert!(!small.lazy_loading);
assert!(!small.memory_mapping);
assert_eq!(small.cache_size, 0);
let large = MemoryOptions::large_file();
assert!(large.lazy_loading);
assert!(large.memory_mapping);
assert!(large.cache_size > 0);
let custom = MemoryOptions::default()
.with_lazy_loading(false)
.with_cache_size(500);
assert!(!custom.lazy_loading);
assert_eq!(custom.cache_size, 500);
}
#[test]
fn test_stream_processor_basic() {
let pdf_data = b"%PDF-1.7\ntest content";
let cursor = Cursor::new(pdf_data);
let options = StreamingOptions::default();
let mut processor = StreamProcessor::new(cursor, options);
let mut event_count = 0;
let result = processor.process_with(|event| {
event_count += 1;
match event {
ProcessingEvent::Start => assert_eq!(event_count, 1),
ProcessingEvent::Header { version } => {
assert_eq!(version, "1.7");
}
ProcessingEvent::End => {}
_ => {}
}
Ok(ProcessingAction::Continue)
});
assert!(result.is_ok());
assert!(event_count > 0);
}
#[test]
fn test_streaming_options() {
let default_opts = StreamingOptions::default();
assert_eq!(default_opts.buffer_size, 64 * 1024);
assert!(!default_opts.skip_images);
assert!(!default_opts.skip_fonts);
let custom_opts = StreamingOptions {
buffer_size: 128 * 1024,
max_stream_size: 1024 * 1024,
skip_images: true,
skip_fonts: true,
};
assert_eq!(custom_opts.buffer_size, 128 * 1024);
assert!(custom_opts.skip_images);
assert!(custom_opts.skip_fonts);
}
#[test]
fn test_processing_actions() {
let pdf_data = b"%PDF-1.7\n";
let cursor = Cursor::new(pdf_data);
let options = StreamingOptions::default();
let mut processor = StreamProcessor::new(cursor, options);
let mut processed_pages = 0;
processor
.process_pages(|_index, _page| {
processed_pages += 1;
if processed_pages >= 2 {
Ok(ProcessingAction::Stop)
} else {
Ok(ProcessingAction::Continue)
}
})
.unwrap();
assert_eq!(processed_pages, 2);
}
#[test]
fn test_extract_text_streaming() {
let pdf_data = b"%PDF-1.7\n";
let cursor = Cursor::new(pdf_data);
let options = StreamingOptions::default();
let mut processor = StreamProcessor::new(cursor, options);
let mut output = Vec::new();
let result = processor.extract_text_streaming(&mut output);
assert!(result.is_ok());
let extracted_text = String::from_utf8(output).unwrap();
assert!(!extracted_text.is_empty());
}
#[test]
fn test_lazy_document_cache_clear() {
let pdf_data = b"%PDF-1.7\n1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n2 0 obj\n<< /Type /Pages /Kids [] /Count 0 >>\nendobj\n%%EOF\n";
let cursor = Cursor::new(pdf_data);
let reader = match PdfReader::new(cursor) {
Ok(r) => r,
Err(_) => {
println!("Skipping test - cannot create PdfReader from minimal PDF");
return;
}
};
let options = MemoryOptions::default().with_cache_size(100);
let lazy_doc = match LazyDocument::new(reader, options) {
Ok(doc) => doc,
Err(_) => {
println!("Skipping test - minimal PDF not sufficient for LazyDocument");
return;
}
};
lazy_doc.clear_cache();
let stats = lazy_doc.memory_stats();
assert_eq!(stats.cache_hits, 0);
}
#[test]
fn test_memory_options_thresholds() {
let options = MemoryOptions::default();
assert_eq!(options.buffer_size, 64 * 1024); assert_eq!(options.mmap_threshold, 10 * 1024 * 1024);
let large_opts = MemoryOptions::large_file();
assert_eq!(large_opts.buffer_size, 256 * 1024); assert_eq!(large_opts.mmap_threshold, 1024 * 1024); }
#[test]
fn test_skip_processing() {
let pdf_data = b"%PDF-1.7\n";
let cursor = Cursor::new(pdf_data);
let options = StreamingOptions::default();
let mut processor = StreamProcessor::new(cursor, options);
let mut skipped_count = 0;
processor
.process_with(|event| match event {
ProcessingEvent::Page(_) => {
skipped_count += 1;
Ok(ProcessingAction::Skip)
}
_ => Ok(ProcessingAction::Continue),
})
.unwrap();
assert!(skipped_count > 0);
}
#[test]
fn test_page_preloading() {
let pdf_data = b"%PDF-1.7\n1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n2 0 obj\n<< /Type /Pages /Kids [] /Count 0 >>\nendobj\n%%EOF\n";
let cursor = Cursor::new(pdf_data);
let reader = match PdfReader::new(cursor) {
Ok(r) => r,
Err(_) => {
println!("Skipping test - cannot create PdfReader from minimal PDF");
return;
}
};
let options = MemoryOptions::default().with_lazy_loading(true);
let lazy_doc = match LazyDocument::new(reader, options) {
Ok(doc) => doc,
Err(_) => {
println!("Skipping test - minimal PDF not sufficient for LazyDocument");
return;
}
};
let result = lazy_doc.preload_page(0);
assert!(result.is_err());
}
#[test]
fn test_memory_strategies() {
let small_opts = MemoryOptions::small_file();
assert!(!small_opts.lazy_loading);
assert_eq!(small_opts.cache_size, 0);
let large_opts = MemoryOptions::large_file();
assert!(large_opts.lazy_loading);
assert_eq!(large_opts.cache_size, 5000);
let balanced = MemoryOptions::default()
.with_lazy_loading(true)
.with_cache_size(1000)
.with_streaming(true);
assert!(balanced.lazy_loading);
assert_eq!(balanced.cache_size, 1000);
assert!(balanced.streaming);
}