[librsvg: 1/2] (#767): Add test for generating links in PDF output
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 1/2] (#767): Add test for generating links in PDF output
- Date: Fri, 16 Jul 2021 17:16:11 +0000 (UTC)
commit 9eccd1c1b6e44d500a39b45889bb3964093e3b50
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Jul 14 21:30:45 2021 -0500
(#767): Add test for generating links in PDF output
This is really basic for now; the code just tests for the presence of
an Annotation with the correct URL, but not for the annotation being
really associated to a page.
Fixes https://gitlab.gnome.org/GNOME/librsvg/-/issues/767
Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/571>
tests/fixtures/cmdline/a-link.svg | 6 +++++
tests/src/cmdline/rsvg_convert.rs | 12 +++++++++
tests/src/predicates/pdf.rs | 52 ++++++++++++++++++++++++++++++++++++---
3 files changed, 67 insertions(+), 3 deletions(-)
---
diff --git a/tests/fixtures/cmdline/a-link.svg b/tests/fixtures/cmdline/a-link.svg
new file mode 100644
index 00000000..1ae8ace5
--- /dev/null
+++ b/tests/fixtures/cmdline/a-link.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="400" height="400" xmlns="http://www.w3.org/2000/svg">
+ <a href="https://example.com">
+ <rect x="100" y="100" width="200" height="200" fill="lime"/>
+ </a>
+</svg>
diff --git a/tests/src/cmdline/rsvg_convert.rs b/tests/src/cmdline/rsvg_convert.rs
index f23b3f02..7794bb37 100644
--- a/tests/src/cmdline/rsvg_convert.rs
+++ b/tests/src/cmdline/rsvg_convert.rs
@@ -289,6 +289,18 @@ fn multiple_input_files_create_multi_page_pdf_output() {
.stdout(file::is_pdf().with_page_count(3));
}
+#[cfg(system_deps_have_cairo_pdf)]
+#[test]
+fn pdf_has_link() {
+ let input = Path::new("tests/fixtures/cmdline/a-link.svg");
+ RsvgConvert::new()
+ .arg("--format=pdf")
+ .arg(input)
+ .assert()
+ .success()
+ .stdout(file::is_pdf().with_link("https://example.com"));
+}
+
#[cfg(system_deps_have_cairo_pdf)]
#[test]
fn env_source_data_epoch_controls_pdf_creation_date() {
diff --git a/tests/src/predicates/pdf.rs b/tests/src/predicates/pdf.rs
index 5c51514b..14ba46f7 100644
--- a/tests/src/predicates/pdf.rs
+++ b/tests/src/predicates/pdf.rs
@@ -1,7 +1,5 @@
-extern crate chrono;
-extern crate lopdf;
-
use chrono::{DateTime, Utc};
+use lopdf::{self, Dictionary, Object};
use predicates::prelude::*;
use predicates::reflection::{Case, Child, PredicateReflection, Product};
use std::cmp;
@@ -40,6 +38,13 @@ impl PdfPredicate {
d: Detail::CreationDate(when),
}
}
+
+ pub fn with_link(self: Self, link: &str) -> DetailPredicate<Self> {
+ DetailPredicate::<Self> {
+ p: self,
+ d: Detail::Link(link.to_string()),
+ }
+ }
}
impl Predicate<[u8]> for PdfPredicate {
@@ -75,6 +80,7 @@ enum Detail {
PageCount(usize),
PageSize(Dimensions),
CreationDate(DateTime<Utc>),
+ Link(String),
}
/// A PDF page's dimensions from its `MediaBox`.
@@ -144,6 +150,7 @@ impl DetailPredicate<PdfPredicate> {
Detail::PageCount(n) => doc.get_page_count() == *n,
Detail::PageSize(d) => doc.get_page_size().map_or(false, |dim| dim == *d),
Detail::CreationDate(d) => doc.get_creation_date().map_or(false, |date| date == *d),
+ Detail::Link(link) => document_has_link(doc, &link),
}
}
@@ -173,6 +180,10 @@ impl DetailPredicate<PdfPredicate> {
"actual creation date",
format!("{:?}", doc.get_creation_date()),
),
+ Detail::Link(_) => Product::new(
+ "actual link contents",
+ "FIXME: who knows, but it's not what we expected".to_string(),
+ ),
}
}
}
@@ -261,6 +272,41 @@ impl fmt::Display for DetailPredicate<PdfPredicate> {
Detail::PageCount(n) => write!(f, "is a PDF with {} page(s)", n),
Detail::PageSize(d) => write!(f, "is a PDF sized {}", d),
Detail::CreationDate(d) => write!(f, "is a PDF created {:?}", d),
+ Detail::Link(l) => write!(f, "is a PDF with a link to {}", l),
}
}
}
+
+// We do a super simple test that a PDF actually contains an Annotation object
+// with a particular link. We don't test that this annotation is actually linked
+// from a page; that would be nicer.
+fn document_has_link(document: &lopdf::Document, link_text: &str) -> bool {
+ document
+ .objects
+ .iter()
+ .map(|(_obj_id, object)| object)
+ .any(|obj| object_is_annotation_with_link(obj, link_text))
+}
+
+fn object_is_annotation_with_link(object: &Object, link_text: &str) -> bool {
+ object
+ .as_dict()
+ .map(|dict| dict_is_annotation(dict) && dict_has_a_with_link(dict, link_text))
+ .unwrap_or(false)
+}
+
+fn dict_is_annotation(dict: &Dictionary) -> bool {
+ dict.get(b"Type")
+ .and_then(|type_val| type_val.as_name_str())
+ .map(|name| name == "Annot")
+ .unwrap_or(false)
+}
+
+fn dict_has_a_with_link(dict: &Dictionary, link_text: &str) -> bool {
+ dict.get(b"A")
+ .and_then(|obj| obj.as_dict())
+ .and_then(|dict| dict.get(b"URI"))
+ .and_then(|obj| obj.as_str())
+ .map(|string| string == link_text.as_bytes())
+ .unwrap_or(false)
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]