1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2014 Calin Cruceru <calin@rosedu.org>
4 //
5
6 #include <QObject>
7
8 #include "GeoDataContainer.h"
9 #include "GeoDataPoint.h"
10 #include "GeoDataPlacemark.h"
11 #include "GeoDataRelation.h"
12 #include "GeoDataCamera.h"
13 #include "MarbleGlobal.h"
14 #include "GeoDataPlaylist.h"
15 #include "GeoDataTour.h"
16 #include "TestUtils.h"
17
18
19 namespace Marble
20 {
21
22 class TestFeatureDetach : public QObject
23 {
24 Q_OBJECT
25
26 private Q_SLOTS:
27 /**
28 * FIXME: Doesn't work for the moment because calling detach() in
29 * GeoDataFeature::set/abstractView() doesn't help because the object
30 * isn't deep-copied in the private class.
31 *
32 * @brief testRelation shows that getting the abstractView() of a copied
33 * feature and modifying it doesn't modify the original one.
34 */
35 void testRelation();
36
37 /**
38 * @brief testDocument shows that getting some child and modifying it,
39 * doesn't modify the child at the same position in the original container.
40 */
41 void testDocument();
42
43 /**
44 * @brief testPlacemark shows that getting the geometry() and modifying it
45 * doesn't modify the geometry of the original placemark.
46 */
47 void testPlacemark();
48
49 /**
50 * @brief testTour shows that modifying the playlist of a copied tour doesn't
51 * modify the playlist of the original one.
52 */
53 void testTour();
54
55 /**
56 * @brief testGeometryParentInPlacemark shows that copying a placemark correctly
57 * keeps the geometries of both the copied one and the original one pointing to its
58 * parent. Before the changes made in GeoDataPlacemark (calling setParent() after
59 * each detach() call and not calling anymore in the
60 * GeoDataPlacemark( const GeoDataGeometry &other ) constructor), after the operation
61 * highlighted in this test, the geometry of the first one (the original one) ended
62 * pointing (its parent) to the second placemark and the second one had its geometry's
63 * parent a null pointer.
64 */
65 void testGeometryParentInPlacemark();
66
67 };
68
testRelation()69 void TestFeatureDetach::testRelation()
70 {
71 GeoDataRelation feat1;
72 GeoDataCamera *view1 = new GeoDataCamera();
73 view1->setAltitudeMode(Absolute);
74 feat1.setAbstractView(view1);
75
76 GeoDataRelation feat2 = feat1;
77 feat2.abstractView()->setAltitudeMode(ClampToSeaFloor);
78 // FIXME: See above (method description).
79 // QVERIFY(feat1.abstractView()->altitudeMode() == Absolute);
80 }
81
testDocument()82 void TestFeatureDetach::testDocument()
83 {
84 GeoDataDocument cont1;
85 GeoDataFeature *feat1 = new GeoDataPlacemark();
86 feat1->setName("Feat1");
87 cont1.insert(0, feat1);
88
89 GeoDataDocument cont2 = cont1;
90 cont2.child(0)->setName("Feat2");
91 QCOMPARE(cont1.child(0)->name(), QLatin1String("Feat1"));
92
93 const GeoDataDocument cont3 = cont1;
94 QCOMPARE(cont3.child(0)->name(), QLatin1String("Feat1"));
95 }
96
testPlacemark()97 void TestFeatureDetach::testPlacemark()
98 {
99 GeoDataCoordinates coords1(30, 30, 0, GeoDataCoordinates::Degree);
100 GeoDataPlacemark place1;
101 place1.setCoordinate(coords1);
102
103 GeoDataPlacemark place2 = place1;
104
105 GeoDataCoordinates coords2(60, 60, 0, GeoDataCoordinates::Degree);
106 GeoDataPoint *point = static_cast<GeoDataPoint*>( place2.geometry() );
107 point->setCoordinates(coords2);
108 QVERIFY(place1.coordinate() == coords1);
109
110 const GeoDataPlacemark place3 = place1;
111 QVERIFY(place3.coordinate() == coords1);
112 }
113
testTour()114 void TestFeatureDetach::testTour()
115 {
116 GeoDataPlaylist *newPlaylist = new GeoDataPlaylist;
117 newPlaylist->setId("Playlist1");
118 GeoDataTour tour1;
119 tour1.setPlaylist(newPlaylist);
120
121 GeoDataTour tour2 = tour1;
122 tour2.playlist()->setId("Playlist2");
123 QCOMPARE(tour1.playlist()->id(), QLatin1String("Playlist1"));
124
125 const GeoDataTour tour3 = tour1;
126 QCOMPARE(tour3.playlist()->id(), QLatin1String("Playlist1"));
127 }
128
testGeometryParentInPlacemark()129 void TestFeatureDetach::testGeometryParentInPlacemark()
130 {
131 GeoDataPlacemark place1;
132 QVERIFY(place1.geometry()->parent() == &place1);
133
134 GeoDataPlacemark place2 = place1;
135
136 // With the changes (regarding setParent() multiple calls after each
137 // detach() call) the only moment when some invariant is broken is right now,
138 // after the copy constructor has been called and no other method (which calls
139 // detach()) hasn't. This is because the geometry is not immediately copied,
140 // so the geometry of place2 has as parent place1. This is immediately solved
141 // when calling geometry() below.
142 QVERIFY(place2.geometry()->parent() == &place2);
143 QVERIFY(place1.geometry()->parent() == &place1);
144 }
145
146 }
147
148 QTEST_MAIN( Marble::TestFeatureDetach )
149
150 #include "TestFeatureDetach.moc"
151