//! 1:1 port of `dart-pdf/packages/pdf_graphics/test/streaming_interpreter_test.dart`. //! //! Streaming (op-by-op) and materialized (parse-all-then-run) //! interpretation must produce identical command lists. use nigig_pdf_document::PdfDocument; use nigig_pdf_graphics::content::{interpret_streaming, parse_content_stream}; use nigig_pdf_graphics::recording::{format_commands, RecordingDevice}; const PDFJS: &str = "/Users/aok/Projects/rustdev/CratesCode/dart-pdf/test_corpora/pdfjs"; #[test] fn streaming_and_materialized_interpretation_agree() { let fixtures = [ "operator-in-TJ-array.pdf", "rotation.pdf", "xobject-image.pdf", "gradientfill.pdf", "tiling-pattern-box.pdf", "pattern_text_embedded_font.pdf", "blendmode.pdf", "knockout_smask.pdf", ]; let mut ran = 0; for name in fixtures { let path = format!("{PDFJS}/{name}"); let Ok(bytes) = std::fs::read(&path) else { eprintln!("SKIP (missing corpus file): {path}"); continue; }; let Ok(mut doc) = PdfDocument::parse(&bytes) else { eprintln!("SKIP (unparseable — likely compressed xref): {path}"); continue; }; let pages = doc.page_count().min(2); for page_index in 0..pages { let Ok(page) = doc.page(page_index) else { continue }; let content = page.content_data.clone(); let ops = parse_content_stream(&content).expect("content parses"); let materialized = RecordingDevice::from_ops(&ops); let mut streamed = RecordingDevice::new(); // A malformed tail ends the stream; from_ops shares the same // prefix behaviour, so both sides stay comparable. let _ = interpret_streaming(&content, &mut streamed); assert!( !materialized.is_empty(), "{name} page {page_index} recorded nothing" ); assert_eq!( format_commands(&streamed.commands), format_commands(&materialized), "{name} page {page_index} diverged" ); ran += 1; } } eprintln!("streaming/materialized compared {ran} pages"); assert!(ran > 0, "no corpus pages ran — checkout missing?"); }