use std::path::PathBuf;
use std::process::Command;
use pdfluent::prelude::*;
fn mini(name: &str) -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../../tests/corpus-mini")
.join(name)
}
fn qpdf_available() -> bool {
Command::new("qpdf")
.arg("--version")
.output()
.map(|o| o.status.success())
.unwrap_or(false)
}
fn qpdf_check(path: &std::path::Path) -> (bool, String) {
let out = Command::new("qpdf")
.arg("--check")
.arg(path)
.output()
.expect("spawn qpdf");
let combined = format!(
"{}{}",
String::from_utf8_lossy(&out.stdout),
String::from_utf8_lossy(&out.stderr)
);
let code = out.status.code().unwrap_or(-1);
let has_error_line = combined.lines().any(|l| l.contains("ERROR"));
let ok = (code == 0 || code == 3) && !has_error_line;
(ok, combined)
}
#[test]
fn qr12_roundtrip_outputs_are_structurally_valid_per_qpdf() {
if !qpdf_available() {
eprintln!("qpdf not available — skipping QR-12 external validation");
return;
}
let tmp = std::env::temp_dir().join("pdfluent_qr12");
std::fs::create_dir_all(&tmp).expect("mk tmp");
for name in [
"simple.pdf",
"multi-page.pdf",
"acroform.pdf",
"pdfa-2b.pdf",
] {
let Ok(bytes) = std::fs::read(mini(name)) else {
continue;
};
let Ok(doc) = PdfDocument::from_bytes(&bytes) else {
continue;
};
let out_bytes = doc.to_bytes().expect("roundtrip to_bytes");
let out_path = tmp.join(format!("rt_{name}"));
std::fs::write(&out_path, &out_bytes).expect("write roundtrip");
let (ok, report) = qpdf_check(&out_path);
assert!(
ok,
"qpdf --check reported structural errors on roundtrip of {name}:\n{report}"
);
}
}
#[test]
fn qr12_original_corpus_is_valid_baseline() {
if !qpdf_available() {
return;
}
for name in ["simple.pdf", "multi-page.pdf"] {
let p = mini(name);
if !p.exists() {
continue;
}
let (ok, report) = qpdf_check(&p);
assert!(
ok,
"baseline fixture {name} unexpectedly fails qpdf:\n{report}"
);
}
}