1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Unit tests migrated from cxxtest
8 * Copyright (C) 2024 Authors
10 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
13 #include <gtest/gtest.h>
15 #include <src/document.h>
16 #include <src/inkscape.h>
17 #include <src/object/sp-root.h>
18 #include <src/object/sp-object.h>
20 using namespace Inkscape
;
21 using namespace Inkscape::XML
;
22 using namespace std::literals
;
24 class ObjectLinksTest
: public ::testing::Test
{
26 static void SetUpTestCase() {
27 Inkscape::Application::create(false);
30 void SetUp() override
{
31 constexpr auto docString
= R
"A(<?xml version="1.0" encoding="UTF
-8" standalone="no
"?>
32 <svg width="62.256149mm
" height="55.27673mm
" viewBox="0 0 62.256149 55.27673" version="1.1" id="svg1
" inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f
)" sodipodi:docname="g
.svg
" xmlns:inkscape="http
://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
33 <sodipodi
:namedview id
="namedview1" pagecolor
="#ffffff" bordercolor
="#000000" borderopacity
="0.25" inkscape
:showpageshadow
="2" inkscape
:pageopacity
="0.0" inkscape
:pagecheckerboard
="0" inkscape
:deskcolor
="#d1d1d1" inkscape
:document
-units
="mm" inkscape
:zoom
="2.7086912" inkscape
:cx
="246.79816" inkscape
:cy
="174.62308" inkscape
:window
-width
="2560" inkscape
:window
-height
="1295" inkscape
:window
-x
="0" inkscape
:window
-y
="32" inkscape
:window
-maximized
="1" inkscape
:current
-layer
="layer1" />
35 <clipPath clipPathUnits
="userSpaceOnUse" id
="clipPath2">
36 <rect style
="fill:#241f31;stroke-width:0.7;stroke-linejoin:round" id
="rect3" width
="61.610233" height
="54.703255" x
="16.41909" y
="45.084824" transform
="rotate(-18.396241)" />
38 <clipPath clipPathUnits
="userSpaceOnUse" id
="clipPath5">
39 <rect style
="fill:#241f31;stroke-width:0.7;stroke-linejoin:round" id
="rect6" width
="61.610233" height
="54.703255" x
="16.41909" y
="45.084824" transform
="rotate(-18.396241)" />
42 <g inkscape
:label
="Layer 1" inkscape
:groupmode
="layer" id
="layer1" transform
="translate(-31.562698,-31.792045)">
43 <path id
="rect1" clip
-path
="url(#clipPath2)" style
="fill:#a51d2d;stroke-width:0.7;stroke-linejoin:round" transform
="rotate(5.1388646)" d
="M 36.865765,26.479748 H 98.475998 V 81.183002 H 36.865765 Z" />
44 <path id
="rect4" clip
-path
="url(#clipPath5)" style
="fill:#a51d2d;stroke-width:0.7;stroke-linejoin:round" transform
="rotate(-5.1388646)" d
="M 36.865765,26.479748 H 98.475998 V 81.183002 H 36.865765 Z" />
45 <path d
="m 88.414007,34.281815 -27.684619,-2.48977 -27.05571,6.37429 -2.11098,23.47298 5.40432,22.93969 27.68461,2.48977 27.056229,-6.37429 2.11099,-23.47299 z" style
="mix-blend-mode:difference;fill:#a51d2d;fill-opacity:1;stroke-width:0.7;stroke-linejoin:round" id
="path5" />
46 <g id
="g14" transform
="translate(-69.610709,-8.3331963)" style
="fill:#f6f5f4">
47 <g id
="g9" transform
="translate(-3.2234202,-4.2002143)" style
="fill:#f6f5f4">
48 <g id
="g6" style
="fill:#f6f5f4">
49 <path id
="path6" style
="stroke-width:0.7;stroke-linejoin:round" d
="m 128.36298,61.92614 a 3.9560158,4.1513743 0 0 1 -3.95601,4.151374 3.9560158,4.1513743 0 0 1 -3.95602,-4.151374 3.9560158,4.1513743 0 0 1 3.95602,-4.151375 3.9560158,4.1513743 0 0 1 3.95601,4.151375 z" />
50 <path id
="ellipse6" style
="stroke-width:0.7;stroke-linejoin:round" d
="m 150.73156,62.512215 a 3.9560158,4.1513743 0 0 1 -3.95602,4.151374 3.9560158,4.1513743 0 0 1 -3.95601,-4.151374 3.9560158,4.1513743 0 0 1 3.95601,-4.151375 3.9560158,4.1513743 0 0 1 3.95602,4.151375 z" />
52 <g id
="g8" transform
="translate(0.0976794,20.610354)" style
="fill:#f6f5f4">
53 <path id
="ellipse7" style
="stroke-width:0.7;stroke-linejoin:round" transform
="scale(0.9)" d
="m 128.36298,61.92614 a 3.9560158,4.1513743 0 0 1 -3.95601,4.151374 3.9560158,4.1513743 0 0 1 -3.95602,-4.151374 3.9560158,4.1513743 0 0 1 3.95602,-4.151375 3.9560158,4.1513743 0 0 1 3.95601,4.151375 z" />
54 <path id
="ellipse8" style
="stroke-width:0.7;stroke-linejoin:round" transform
="scale(1.1)" d
="m 150.73156,62.512215 a 3.9560158,4.1513743 0 0 1 -3.95602,4.151374 3.9560158,4.1513743 0 0 1 -3.95601,-4.151374 3.9560158,4.1513743 0 0 1 3.95601,-4.151375 3.9560158,4.1513743 0 0 1 3.95602,4.151375 z" />
60 doc = SPDocument::createNewDocFromMem(docString, false);
63 ASSERT_TRUE(doc->getRoot());
66 std::vector<SPObject *> getObjects(std::vector<std::string> const &lst) {
67 std::vector<SPObject *> ret;
68 for (auto &id : lst) {
69 ret.push_back(doc->getObjectById(id));
74 std::unique_ptr<SPDocument> doc;
77 ::testing::AssertionResult RectNear(std::string expr1,
81 double abs_error = 0.01) {
84 for (auto x = 0; x < 2; x++) {
85 for (auto y = 0; y < 2; y++) {
86 diff += fabs(val1[x][y] - val2[x][y]);
90 if (diff <= abs_error)
91 return ::testing::AssertionSuccess();
93 return ::testing::AssertionFailure()
94 << "The difference between
" << expr1 << " and " << expr2
95 << " is
" << diff << ", which exceeds
" << abs_error << ", where
\n"
96 << expr1 << " evaluates to
" << val1 << ",\n"
97 << expr2 << " evaluates to
" << val2 << ".\n";
100 TEST_F(ObjectLinksTest, removeTransforms)
102 doc->ensureUpToDate();
104 std::vector<std::string> watch = {"rect1
", "rect4
", "path5
", "g14
", "g9
", "g6
", "path6
", "ellipse7
", "g8
"};
105 std::map<std::string, Geom::Rect> boxes;
107 for (auto id : watch) {
108 auto item = cast<SPItem>(doc->getObjectById(id));
109 ASSERT_TRUE(item) << " item by id
'" << id << "'";
110 auto obox = item->documentGeometricBounds();
111 ASSERT_TRUE(obox) << " item bounds
'" << id << "'";
115 doc->getActionGroup()->activate_action("remove
-all
-transforms
");
116 doc->ensureUpToDate();
118 for (auto id : watch) {
119 auto item = cast<SPItem>(doc->getObjectById(id));
120 ASSERT_TRUE(item) << " item by id
'" << id << "'";
121 ASSERT_FALSE(item->getAttribute("transform
")) << " item transform
'" << id << "'";
122 auto old_box = boxes[id];
123 auto new_box = item->documentGeometricBounds();
124 ASSERT_TRUE(new_box) << " item bounds
'" << id << "'";
125 EXPECT_TRUE(RectNear(id + ".old_box
", id + ".new_box
", old_box, *new_box, 0.01));