File indexing completed on 2025-02-16 09:54:28
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2014 Calin Cruceru <calin@rosedu.org> 0004 // 0005 0006 #include <QObject> 0007 0008 #include "GeoDataContainer.h" 0009 #include "GeoDataPoint.h" 0010 #include "GeoDataPlacemark.h" 0011 #include "GeoDataRelation.h" 0012 #include "GeoDataCamera.h" 0013 #include "MarbleGlobal.h" 0014 #include "GeoDataPlaylist.h" 0015 #include "GeoDataTour.h" 0016 #include "TestUtils.h" 0017 0018 0019 namespace Marble 0020 { 0021 0022 class TestFeatureDetach : public QObject 0023 { 0024 Q_OBJECT 0025 0026 private Q_SLOTS: 0027 /** 0028 * FIXME: Doesn't work for the moment because calling detach() in 0029 * GeoDataFeature::set/abstractView() doesn't help because the object 0030 * isn't deep-copied in the private class. 0031 * 0032 * @brief testRelation shows that getting the abstractView() of a copied 0033 * feature and modifying it doesn't modify the original one. 0034 */ 0035 void testRelation(); 0036 0037 /** 0038 * @brief testDocument shows that getting some child and modifying it, 0039 * doesn't modify the child at the same position in the original container. 0040 */ 0041 void testDocument(); 0042 0043 /** 0044 * @brief testPlacemark shows that getting the geometry() and modifying it 0045 * doesn't modify the geometry of the original placemark. 0046 */ 0047 void testPlacemark(); 0048 0049 /** 0050 * @brief testTour shows that modifying the playlist of a copied tour doesn't 0051 * modify the playlist of the original one. 0052 */ 0053 void testTour(); 0054 0055 /** 0056 * @brief testGeometryParentInPlacemark shows that copying a placemark correctly 0057 * keeps the geometries of both the copied one and the original one pointing to its 0058 * parent. Before the changes made in GeoDataPlacemark (calling setParent() after 0059 * each detach() call and not calling anymore in the 0060 * GeoDataPlacemark( const GeoDataGeometry &other ) constructor), after the operation 0061 * highlighted in this test, the geometry of the first one (the original one) ended 0062 * pointing (its parent) to the second placemark and the second one had its geometry's 0063 * parent a null pointer. 0064 */ 0065 void testGeometryParentInPlacemark(); 0066 0067 }; 0068 0069 void TestFeatureDetach::testRelation() 0070 { 0071 GeoDataRelation feat1; 0072 GeoDataCamera *view1 = new GeoDataCamera(); 0073 view1->setAltitudeMode(Absolute); 0074 feat1.setAbstractView(view1); 0075 0076 GeoDataRelation feat2 = feat1; 0077 feat2.abstractView()->setAltitudeMode(ClampToSeaFloor); 0078 // FIXME: See above (method description). 0079 // QVERIFY(feat1.abstractView()->altitudeMode() == Absolute); 0080 } 0081 0082 void TestFeatureDetach::testDocument() 0083 { 0084 GeoDataDocument cont1; 0085 GeoDataFeature *feat1 = new GeoDataPlacemark(); 0086 feat1->setName("Feat1"); 0087 cont1.insert(0, feat1); 0088 0089 GeoDataDocument cont2 = cont1; 0090 cont2.child(0)->setName("Feat2"); 0091 QCOMPARE(cont1.child(0)->name(), QLatin1String("Feat1")); 0092 0093 const GeoDataDocument cont3 = cont1; 0094 QCOMPARE(cont3.child(0)->name(), QLatin1String("Feat1")); 0095 } 0096 0097 void TestFeatureDetach::testPlacemark() 0098 { 0099 GeoDataCoordinates coords1(30, 30, 0, GeoDataCoordinates::Degree); 0100 GeoDataPlacemark place1; 0101 place1.setCoordinate(coords1); 0102 0103 GeoDataPlacemark place2 = place1; 0104 0105 GeoDataCoordinates coords2(60, 60, 0, GeoDataCoordinates::Degree); 0106 GeoDataPoint *point = static_cast<GeoDataPoint*>( place2.geometry() ); 0107 point->setCoordinates(coords2); 0108 QVERIFY(place1.coordinate() == coords1); 0109 0110 const GeoDataPlacemark place3 = place1; 0111 QVERIFY(place3.coordinate() == coords1); 0112 } 0113 0114 void TestFeatureDetach::testTour() 0115 { 0116 GeoDataPlaylist *newPlaylist = new GeoDataPlaylist; 0117 newPlaylist->setId("Playlist1"); 0118 GeoDataTour tour1; 0119 tour1.setPlaylist(newPlaylist); 0120 0121 GeoDataTour tour2 = tour1; 0122 tour2.playlist()->setId("Playlist2"); 0123 QCOMPARE(tour1.playlist()->id(), QLatin1String("Playlist1")); 0124 0125 const GeoDataTour tour3 = tour1; 0126 QCOMPARE(tour3.playlist()->id(), QLatin1String("Playlist1")); 0127 } 0128 0129 void TestFeatureDetach::testGeometryParentInPlacemark() 0130 { 0131 GeoDataPlacemark place1; 0132 QVERIFY(place1.geometry()->parent() == &place1); 0133 0134 GeoDataPlacemark place2 = place1; 0135 0136 // With the changes (regarding setParent() multiple calls after each 0137 // detach() call) the only moment when some invariant is broken is right now, 0138 // after the copy constructor has been called and no other method (which calls 0139 // detach()) hasn't. This is because the geometry is not immediately copied, 0140 // so the geometry of place2 has as parent place1. This is immediately solved 0141 // when calling geometry() below. 0142 QVERIFY(place2.geometry()->parent() == &place2); 0143 QVERIFY(place1.geometry()->parent() == &place1); 0144 } 0145 0146 } 0147 0148 QTEST_MAIN( Marble::TestFeatureDetach ) 0149 0150 #include "TestFeatureDetach.moc"