File indexing completed on 2025-01-19 03:57:45

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2010-01-17
0007  * Description : Test parsing gpx data.
0008  *
0009  * SPDX-FileCopyrightText: 2010 by Michael G. Hansen <mike at mghansen dot de>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "tracks_utest.h"
0016 
0017 // Qt includes
0018 
0019 #include <QDateTime>
0020 #include <QSignalSpy>
0021 
0022 // Local includes
0023 
0024 #include "digikam_debug.h"
0025 #include "trackmanager.h"
0026 #include "trackreader.h"
0027 #include "dtestdatadir.h"
0028 
0029 using namespace Digikam;
0030 
0031 QTEST_GUILESS_MAIN(TestTracks)
0032 
0033 /**
0034  * @brief Return the path of the directory containing the test data
0035  */
0036 QString GetTestDataDirectory()
0037 {
0038     QString filesPath = DTestDataDir::TestData(QString::fromUtf8("core/tests/geolocation/geoiface"))
0039                            .root().path() + QLatin1Char('/');
0040     qCDebug(DIGIKAM_TESTS_LOG) << "Test Data Dir:" << filesPath;
0041 
0042     return filesPath;
0043 }
0044 
0045 /**
0046  * @brief Dummy test that does nothing
0047  */
0048 void TestTracks::testNoOp()
0049 {
0050 }
0051 
0052 /**
0053  * @brief Test how well QDateTime deals with various string representations
0054  *
0055  * The behavior of QDateTime::fromString changed in some Qt version, so here
0056  * we can test what the current behavior is and quickly detect if Qt changes
0057  * again.
0058  */
0059 void TestTracks::testQDateTimeParsing()
0060 {
0061     {
0062         // strings ending with a 'Z' are taken to be in UTC, regardless of milliseconds
0063         QDateTime time1 = QDateTime::fromString(QString::fromLatin1("2009-03-11T13:39:55.622Z"), Qt::ISODate);
0064         QCOMPARE(time1.timeSpec(), Qt::UTC);
0065         QDateTime time2 = QDateTime::fromString(QString::fromLatin1("2009-03-11T13:39:55Z"), Qt::ISODate);
0066         QCOMPARE(time2.timeSpec(), Qt::UTC);
0067     }
0068 
0069     {
0070         // eCoach in N900 records GPX files with this kind of date format:
0071         // 2010-01-14T09:26:02.287+02:00
0072         QDateTime time1 = QDateTime::fromString(QString::fromLatin1("2010-01-14T09:26:02.287+02:00"), Qt::ISODate);
0073 
0074         /// @todo What about the timezone?
0075         QCOMPARE(time1.date(), QDate(2010, 01, 14));
0076         QCOMPARE(time1.time(), QTime(9, 26, 2, 287));
0077 
0078         // when we omit the time zone data, parsing succeeds
0079         // time is interpreted as local time
0080         QDateTime time2 = QDateTime::fromString(QString::fromLatin1("2010-01-14T09:26:02.287")/*"+02:00"*/, Qt::ISODate);
0081         QCOMPARE(time2.date(), QDate(2010, 01, 14));
0082         QCOMPARE(time2.time(), QTime(9, 26, 2, 287));
0083         QCOMPARE(time2.timeSpec(), Qt::LocalTime);
0084     }
0085 }
0086 
0087 /**
0088  * @brief Test our custom parsing function
0089  */
0090 void TestTracks::testCustomDateTimeParsing()
0091 {
0092     {
0093         // this should work as usual:
0094         const QDateTime time1 = TrackReader::ParseTime(QString::fromLatin1("2009-03-11T13:39:55.622Z"));
0095         QCOMPARE(time1.timeSpec(), Qt::UTC);
0096         QCOMPARE(time1.date(), QDate(2009, 03, 11));
0097         QCOMPARE(time1.time(), QTime(13, 39, 55, 622));
0098     }
0099 
0100     {
0101         // eCoach in N900: 2010-01-14T09:26:02.287+02:00
0102         const QDateTime time1 = TrackReader::ParseTime(QString::fromLatin1("2010-01-14T09:26:02.287+02:00"));
0103         QCOMPARE(time1.timeSpec(), Qt::UTC);
0104         QCOMPARE(time1.date(), QDate(2010, 01, 14));
0105         QCOMPARE(time1.time(), QTime(7, 26, 02, 287));
0106     }
0107 
0108     {
0109         // test negative time zone offset: 2010-01-14T09:26:02.287+02:00
0110         const QDateTime time1 = TrackReader::ParseTime(QString::fromLatin1("2010-01-14T09:26:02.287-02:00"));
0111         QCOMPARE(time1.timeSpec(), Qt::UTC);
0112         QCOMPARE(time1.date(), QDate(2010, 01, 14));
0113         QCOMPARE(time1.time(), QTime(11, 26, 02, 287));
0114     }
0115 
0116     {
0117         // test negative time zone offset with minutes: 2010-01-14T09:26:02.287+03:15
0118         const QDateTime time1 = TrackReader::ParseTime(QString::fromLatin1("2010-01-14T09:26:02.287-03:15"));
0119         QCOMPARE(time1.timeSpec(), Qt::UTC);
0120         QCOMPARE(time1.date(), QDate(2010, 01, 14));
0121         QCOMPARE(time1.time(), QTime(12, 41, 02, 287));
0122     }
0123 }
0124 
0125 /**
0126  * @brief Test loading of gpx files using TrackManager (threaded)
0127  */
0128 void TestTracks::testFileLoading()
0129 {
0130     QUrl testDataDir = QUrl::fromLocalFile(GetTestDataDirectory() + QLatin1Char('/') + QLatin1String("gpxfile-1.gpx"));
0131 
0132     QList<QUrl> fileList;
0133     fileList << testDataDir;
0134 
0135     TrackManager myParser;
0136 
0137     QSignalSpy spyTrackFiles(&myParser, SIGNAL(signalTracksChanged(QList<TrackManager::TrackChanges>)));
0138     QSignalSpy spyAllDone(&myParser, SIGNAL(signalAllTrackFilesReady()));
0139 
0140     myParser.loadTrackFiles(fileList);
0141 
0142     // wait until the files are loaded:
0143     while (spyAllDone.isEmpty())
0144     {
0145         QTest::qWait(100);
0146     }
0147 
0148     QCOMPARE(spyAllDone.count(), 1);
0149     QCOMPARE(spyTrackFiles.count(), 1);
0150 
0151     const TrackManager::Track& file1 = myParser.getTrack(0);
0152     QVERIFY(!file1.points.isEmpty());
0153 }
0154 
0155 /**
0156  * @brief Test loading of a GPX file directly
0157  */
0158 void TestTracks::testSaxLoader()
0159 {
0160     {
0161         QUrl testDataDir = QUrl::fromLocalFile(GetTestDataDirectory() + QLatin1Char('/') + QLatin1String("gpxfile-1.gpx"));
0162         TrackReader::TrackReadResult fileData = TrackReader::loadTrackFile(testDataDir);
0163         QVERIFY(fileData.isValid);
0164         QVERIFY(fileData.loadError.isEmpty());
0165 
0166         // verify that the points are sorted by date:
0167         for (int i = 1; i<fileData.track.points.count(); ++i)
0168         {
0169             QVERIFY(TrackManager::TrackPoint::EarlierThan(fileData.track.points.at(i-1), fileData.track.points.at(i)));
0170         }
0171     }
0172 
0173     {
0174         QUrl testDataDir = QUrl::fromLocalFile(GetTestDataDirectory() + QLatin1Char('/') + QLatin1String("gpx-child-elements.gpx"));
0175         TrackReader::TrackReadResult fileData = TrackReader::loadTrackFile(testDataDir);
0176         QVERIFY(fileData.isValid);
0177         QVERIFY(fileData.loadError.isEmpty());
0178         QVERIFY(fileData.track.points.size() == 6);
0179     }
0180 }
0181 
0182 /**
0183  * @brief Test loading of invalid GPX files
0184  */
0185 void TestTracks::testSaxLoaderError()
0186 {
0187     {
0188         QUrl testDataDir = QUrl::fromLocalFile(GetTestDataDirectory() + QLatin1Char('/') + QLatin1String("gpx-invalid-empty.gpx"));
0189         TrackReader::TrackReadResult fileData = TrackReader::loadTrackFile(testDataDir);
0190         QVERIFY(!fileData.isValid);
0191         QVERIFY(!fileData.loadError.isEmpty());
0192         qCDebug(DIGIKAM_TESTS_LOG) << fileData.loadError;
0193     }
0194 
0195     {
0196         QUrl testDataDir = QUrl::fromLocalFile(GetTestDataDirectory() + QLatin1Char('/') + QLatin1String("gpx-invalid-xml-error.gpx"));
0197         TrackReader::TrackReadResult fileData = TrackReader::loadTrackFile(testDataDir);
0198         QVERIFY(!fileData.isValid);
0199         QVERIFY(!fileData.loadError.isEmpty());
0200         qCDebug(DIGIKAM_TESTS_LOG) << fileData.loadError;
0201     }
0202 
0203     {
0204         QUrl testDataDir = QUrl::fromLocalFile(GetTestDataDirectory() + QLatin1Char('/') + QLatin1String("gpx-invalid-no-points.gpx"));
0205         TrackReader::TrackReadResult fileData = TrackReader::loadTrackFile(testDataDir);
0206         QVERIFY(!fileData.isValid);
0207         QVERIFY(!fileData.loadError.isEmpty());
0208         qCDebug(DIGIKAM_TESTS_LOG) << fileData.loadError;
0209     }
0210 }
0211 
0212 #include "moc_tracks_utest.cpp"