[librsvg: 9/15] Use JSON fixtures for the primitive_geometries tests




commit 9ade0bfe46fff3f69c5264165de2993e747c36ce
Author: Federico Mena Quintero <federico gnome org>
Date:   Mon May 9 12:57:00 2022 -0500

    Use JSON fixtures for the primitive_geometries tests
    
    Finally, something I've been wanting to do for a while.
    
    Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/697>

 tests/fixtures/primitive_geometries/rect.svg       |   4 +
 tests/fixtures/primitive_geometries/rect.svg.geom  |  16 ++
 .../fixtures/primitive_geometries/rect_stroke.svg  |   4 +
 .../primitive_geometries/rect_stroke.svg.geom      |  16 ++
 .../primitive_geometries/rect_stroke_unfilled.svg  |   4 +
 .../rect_stroke_unfilled.svg.geom                  |  16 ++
 tests/src/primitive_geometries.rs                  | 265 ++++++++++++---------
 7 files changed, 206 insertions(+), 119 deletions(-)
---
diff --git a/tests/fixtures/primitive_geometries/rect.svg b/tests/fixtures/primitive_geometries/rect.svg
new file mode 100644
index 000000000..e0cafe2b0
--- /dev/null
+++ b/tests/fixtures/primitive_geometries/rect.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; width="100" height="100">
+  <rect id="a" x="10" y="20" width="30" height="40"/>
+</svg>
diff --git a/tests/fixtures/primitive_geometries/rect.svg.geom 
b/tests/fixtures/primitive_geometries/rect.svg.geom
new file mode 100644
index 000000000..09c7255cd
--- /dev/null
+++ b/tests/fixtures/primitive_geometries/rect.svg.geom
@@ -0,0 +1,16 @@
+{
+    "#a": {
+        "ink_rect": {
+            "x": 10.0,
+            "y": 20.0,
+            "width": 30.0,
+            "height": 40.0
+        },
+        "logical_rect": {
+            "x": 10.0,
+            "y": 20.0,
+            "width": 30.0,
+            "height": 40.0
+        }
+    }
+}
diff --git a/tests/fixtures/primitive_geometries/rect_stroke.svg 
b/tests/fixtures/primitive_geometries/rect_stroke.svg
new file mode 100644
index 000000000..b3b489331
--- /dev/null
+++ b/tests/fixtures/primitive_geometries/rect_stroke.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; width="100" height="100">
+  <rect id="a" x="10" y="20" width="30" height="40" stroke-width="10" stroke="black"/>
+</svg>
diff --git a/tests/fixtures/primitive_geometries/rect_stroke.svg.geom 
b/tests/fixtures/primitive_geometries/rect_stroke.svg.geom
new file mode 100644
index 000000000..1956bd8dd
--- /dev/null
+++ b/tests/fixtures/primitive_geometries/rect_stroke.svg.geom
@@ -0,0 +1,16 @@
+{
+    "#a": {
+        "ink_rect": {
+            "x": 5.0,
+            "y": 15.0,
+            "width": 40.0,
+            "height": 50.0
+        },
+        "logical_rect": {
+            "x": 10.0,
+            "y": 20.0,
+            "width": 30.0,
+            "height": 40.0
+        }
+    }
+}
diff --git a/tests/fixtures/primitive_geometries/rect_stroke_unfilled.svg 
b/tests/fixtures/primitive_geometries/rect_stroke_unfilled.svg
new file mode 100644
index 000000000..6857fc742
--- /dev/null
+++ b/tests/fixtures/primitive_geometries/rect_stroke_unfilled.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; width="100" height="100">
+  <rect id="a" x="10" y="20" width="30" height="40" stroke-width="10" stroke="black" fill="none"/>
+</svg>
diff --git a/tests/fixtures/primitive_geometries/rect_stroke_unfilled.svg.geom 
b/tests/fixtures/primitive_geometries/rect_stroke_unfilled.svg.geom
new file mode 100644
index 000000000..1956bd8dd
--- /dev/null
+++ b/tests/fixtures/primitive_geometries/rect_stroke_unfilled.svg.geom
@@ -0,0 +1,16 @@
+{
+    "#a": {
+        "ink_rect": {
+            "x": 5.0,
+            "y": 15.0,
+            "width": 40.0,
+            "height": 50.0
+        },
+        "logical_rect": {
+            "x": 10.0,
+            "y": 20.0,
+            "width": 30.0,
+            "height": 40.0
+        }
+    }
+}
diff --git a/tests/src/primitive_geometries.rs b/tests/src/primitive_geometries.rs
index dc28f37f2..c530885d2 100644
--- a/tests/src/primitive_geometries.rs
+++ b/tests/src/primitive_geometries.rs
@@ -1,133 +1,160 @@
+//! Tests for geometries of SVG primitives
+//!
+//! These use the *.svg and *.svg.geom files in the tests/fixtures/primitive_geometries directory.
+//!
+//! Each .svg.geom is a JSON file formatted like this:
+//!
+//! ```json
+//! {
+//!     "#element_id": {
+//!         "ink_rect": {
+//!             "x": 5.0,
+//!             "y": 15.0,
+//!             "width": 40.0,
+//!             "height": 50.0
+//!         },
+//!         "logical_rect": {
+//!             "x": 10.0,
+//!             "y": 20.0,
+//!             "width": 30.0,
+//!             "height": 40.0
+//!         }
+//!     }
+//! }
+//! ```
+//!
+//! Any number of element_ids may appear in the file.  For each of those, the `test()` function will
+//! call `CairoRenderer::get_layer_geometry()` and compare its result against the provided rectangles.
+
+use anyhow::{Context, Result};
 use cairo;
-use librsvg::CairoRenderer;
+use librsvg::{CairoRenderer, LengthUnit, Loader, Rect};
+use serde::Deserialize;
+use std::collections::BTreeMap;
+use std::fs;
+
+// Copy of cairo::Rectangle
+//
+// Somehow I can't make serde's "remote" work here, in combination with the BTreeMap below...
+#[derive(Copy, Clone, Deserialize, Debug, PartialEq)]
+struct Rectangle {
+    x: f64,
+    y: f64,
+    width: f64,
+    height: f64,
+}
+
+impl From<Rectangle> for Rect {
+    fn from(r: Rectangle) -> Rect {
+        Rect {
+            x0: r.x,
+            y0: r.y,
+            x1: r.x + r.width,
+            y1: r.y + r.height,
+        }
+    }
+}
 
-use crate::utils::load_svg;
+#[derive(Copy, Clone, Deserialize, Debug, PartialEq)]
+struct ElementGeometry {
+    ink_rect: Option<Rectangle>,
+    logical_rect: Option<Rectangle>,
+}
+
+#[derive(Deserialize)]
+struct Geometries(BTreeMap<String, ElementGeometry>);
+
+fn read_geometries(path: &str) -> Result<Geometries> {
+    let contents = fs::read_to_string(path).context(format!("could not read {:?}", path))?;
+    Ok(serde_json::from_str(&contents).context(format!("could not parse JSON from {:?}", path))?)
+}
+
+// We create a struct with the id and geometry so that
+// assert_eq!() in the tests will print out the element name for failures.
+//
+// Here we use librsvg::Rect as that one has an approx_eq() method.
+#[derive(Debug, PartialEq)]
+struct Element {
+    id: String,
+    ink_rect: Option<Rect>,
+    logical_rect: Option<Rect>,
+}
+
+impl Element {
+    fn from_element_geometry(id: &str, geom: &ElementGeometry) -> Element {
+        Element {
+            id: String::from(id),
+            ink_rect: geom.ink_rect.map(Into::into),
+            logical_rect: geom.logical_rect.map(Into::into),
+        }
+    }
+
+    fn from_rectangles(id: &str, ink_rect: cairo::Rectangle, logical_rect: cairo::Rectangle) -> Element {
+        Element {
+            id: String::from(id),
+            ink_rect: Some(ink_rect.into()),
+            logical_rect: Some(logical_rect.into()),
+        }
+    }
+}
+
+fn test(svg_filename: &str, geometries_filename: &str) {
+    let geometries = read_geometries(geometries_filename).expect("reading geometries JSON");
+
+    let handle = Loader::new()
+        .read_path(svg_filename)
+        .expect("reading geometries SVG");
+    let renderer = CairoRenderer::new(&handle);
+    let dimensions = renderer.intrinsic_dimensions();
+    let (svg_width, svg_height) = renderer
+        .intrinsic_size_in_pixels()
+        .expect("intrinsic size in pixels");
+
+    assert!(matches!(dimensions.width.unit, LengthUnit::Px));
+    assert!(matches!(dimensions.height.unit, LengthUnit::Px));
+    assert_eq!(dimensions.width.length, svg_width);
+    assert_eq!(dimensions.height.length, svg_height);
+
+    for (id, expected) in geometries.0.iter() {
+        let expected = Element::from_element_geometry(id, expected);
+
+        let viewport = cairo::Rectangle {
+            x: 0.0,
+            y: 0.0,
+            width: svg_width,
+            height: svg_height,
+        };
+
+        let (ink_rect, logical_rect) = renderer
+            .geometry_for_layer(Some(id), &viewport)
+            .expect(&format!("getting geometry for {}", id));
+
+        let computed = Element::from_rectangles(id, ink_rect, logical_rect);
+
+        assert_eq!(expected, computed);
+    }
+}
 
 #[test]
 fn rect() {
-    let svg = load_svg(
-        br#"<?xml version="1.0" encoding="UTF-8"?>
-<svg xmlns="http://www.w3.org/2000/svg"; width="100" height="100">
-  <rect id="a" x="10" y="20" width="30" height="40"/>
-</svg>
-"#,
-    )
-    .unwrap();
-
-    let renderer = CairoRenderer::new(&svg).test_mode(true);
-
-    let (ink_rect, logical_rect) = renderer
-        .geometry_for_layer(
-            Some("#a"),
-            &cairo::Rectangle {
-                x: 0.0,
-                y: 0.0,
-                width: 100.0,
-                height: 100.0,
-            },
-        )
-        .unwrap();
-
-    let expected_ink = cairo::Rectangle {
-        x: 10.0,
-        y: 20.0,
-        width: 30.0,
-        height: 40.0,
-    };
-
-    let expected_logical = cairo::Rectangle {
-        x: 10.0,
-        y: 20.0,
-        width: 30.0,
-        height: 40.0,
-    };
-
-    assert_eq!(ink_rect, expected_ink);
-    assert_eq!(logical_rect, expected_logical);
+    test(
+        "tests/fixtures/primitive_geometries/rect.svg",
+        "tests/fixtures/primitive_geometries/rect.svg.geom",
+    );
 }
 
 #[test]
 fn rect_stroke() {
-    let svg = load_svg(
-        br#"<?xml version="1.0" encoding="UTF-8"?>
-<svg xmlns="http://www.w3.org/2000/svg"; width="100" height="100">
-  <rect id="a" x="10" y="20" width="30" height="40" stroke-width="10" stroke="black"/>
-</svg>
-"#,
-    )
-    .unwrap();
-
-    let renderer = CairoRenderer::new(&svg).test_mode(true);
-
-    let (ink_rect, logical_rect) = renderer
-        .geometry_for_layer(
-            Some("#a"),
-            &cairo::Rectangle {
-                x: 0.0,
-                y: 0.0,
-                width: 100.0,
-                height: 100.0,
-            },
-        )
-        .unwrap();
-
-    let expected_ink = cairo::Rectangle {
-        x: 5.0,
-        y: 15.0,
-        width: 40.0,
-        height: 50.0,
-    };
-
-    let expected_logical = cairo::Rectangle {
-        x: 10.0,
-        y: 20.0,
-        width: 30.0,
-        height: 40.0,
-    };
-
-    assert_eq!(ink_rect, expected_ink);
-    assert_eq!(logical_rect, expected_logical);
+    test(
+        "tests/fixtures/primitive_geometries/rect_stroke.svg",
+        "tests/fixtures/primitive_geometries/rect_stroke.svg.geom",
+    );
 }
 
 #[test]
 fn rect_stroke_unfilled() {
-    let svg = load_svg(
-        br#"<?xml version="1.0" encoding="UTF-8"?>
-<svg xmlns="http://www.w3.org/2000/svg"; width="100" height="100">
-  <rect id="a" x="10" y="20" width="30" height="40" stroke-width="10" stroke="black" fill="none"/>
-</svg>
-"#,
-    )
-    .unwrap();
-
-    let renderer = CairoRenderer::new(&svg).test_mode(true);
-
-    let (ink_rect, logical_rect) = renderer
-        .geometry_for_layer(
-            Some("#a"),
-            &cairo::Rectangle {
-                x: 0.0,
-                y: 0.0,
-                width: 100.0,
-                height: 100.0,
-            },
-        )
-        .unwrap();
-
-    let expected_ink = cairo::Rectangle {
-        x: 5.0,
-        y: 15.0,
-        width: 40.0,
-        height: 50.0,
-    };
-
-    let expected_logical = cairo::Rectangle {
-        x: 10.0,
-        y: 20.0,
-        width: 30.0,
-        height: 40.0,
-    };
-
-    assert_eq!(ink_rect, expected_ink);
-    assert_eq!(logical_rect, expected_logical);
+    test(
+        "tests/fixtures/primitive_geometries/rect_stroke_unfilled.svg",
+        "tests/fixtures/primitive_geometries/rect_stroke_unfilled.svg.geom",
+    );
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]