From f769f4ea5d1421bcacbeda815d5988188abcd32c Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Sun, 11 Oct 2026 04:47:07 -0700 Subject: [PATCH] Tests: the envelope export test ignores the PDF's XMP dates and file ID `enveloped_type_exports_distorted_in_every_format` exports each format twice and compares the two files without the lines that contain `CreationDate` or `ModDate`. Two other lines of the PDF also change with the time it was written. The XMP packet is one line that holds `xmp:CreateDate`, `xmp:ModifyDate` and the file ID, and the trailer holds the file ID as `/ID`. The file ID is a hash that krilla computes over the bytes written before it, which include the dates. When the two PDF exports were written in different seconds, these two lines differed, and the test failed at "pdf exports are repeatable". The comparison now also drops the lines that contain `xmp:CreateDate`, `xmp:ModifyDate` or `/ID[`. A new check writes the PDF that `document.export` writes, with its creation time set to Unix seconds 0 and then 1, and asserts that the comparison's filter leaves the two files equal. --- crates/engine/src/tests_envelope.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/crates/engine/src/tests_envelope.rs b/crates/engine/src/tests_envelope.rs index 78006942..f1609d89 100644 --- a/crates/engine/src/tests_envelope.rs +++ b/crates/engine/src/tests_envelope.rs @@ -52,6 +52,14 @@ fn options(s: &Session, id: NodeId) -> (EnvelopeOptions, f64) { } } +/// `bytes` without the lines that depend on when the file was written: the EPS and PDF dates, and +/// a PDF's XMP packet (one line, with its dates and IDs) and trailer `/ID`. +fn undated(bytes: &[u8]) -> Vec { + let stamps: [&[u8]; 5] = [b"CreationDate", b"ModDate", b"xmp:CreateDate", b"xmp:ModifyDate", b"/ID["]; + let dated = |line: &&[u8]| stamps.iter().any(|s| line.windows(s.len()).any(|w| w == *s)); + bytes.split(|b| *b == b'\n').filter(|l| !dated(l)).flat_map(|l| l.iter().copied().chain(*b"\n")).collect() +} + #[test] fn new_envelopes_take_the_reference_defaults_and_options_change_them() { let mut s = session(); @@ -221,13 +229,19 @@ fn enveloped_type_exports_distorted_in_every_format() { let t = id_of(&s.execute("text.create", &json!({"x": 100, "y": 200, "text": "Envelope", "size": 48})).unwrap()); sel(&mut s, &[t]); s.execute("object.envelope.makeWithWarp", &json!({"style": "arch", "bend": 0})).unwrap(); - // The export's bytes without its time stamps (EPS and PDF date their files to the second). + // The export's bytes without its dates and file ID (EPS and PDF date their files to the second). let export = |s: &mut Session, format: &str| -> Vec { let data = s.execute("document.export", &json!({"format": format})).unwrap()["dataBase64"].as_str().unwrap().to_string(); - let bytes = vectorcraft_format::base64_decode(&data).unwrap(); - let dated = |line: &&[u8]| line.windows(12).any(|w| w == b"CreationDate") || line.windows(7).any(|w| w == b"ModDate"); - bytes.split(|b| *b == b'\n').filter(|l| !dated(l)).flat_map(|l| l.iter().copied().chain(*b"\n")).collect() + undated(&vectorcraft_format::base64_decode(&data).unwrap()) }; + // Two PDFs dated a second apart, with the options and editing data that document.export + // passes the writer, differ only in lines that `undated` drops. + let d = &s.doc().unwrap().doc; + let pdf = |at: i64| { + let o = cmd::fileio::pdf::options("document.export", d, &json!({})).unwrap(); + undated(&export_pdf(d, &vectorcraft_pdf::PdfOptions { created: Some(at), native: Some(vectorcraft_format::save(d, false)), ..o }).unwrap()) + }; + assert_eq!(pdf(0), pdf(1), "a PDF dated a second later differs only in its dates and file ID"); for format in ["svg", "pdf", "eps", "emf", "dxf"] { s.execute("object.envelope.options", &json!({"bend": 0})).unwrap(); let flat = export(&mut s, format);