File indexing completed on 2022-10-04 14:00:22

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"