File indexing completed on 2024-05-12 05:13:48

0001 /*
0002     SPDX-FileCopyrightText: 2018 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "itinerary_version.h"
0008 
0009 #include "weatherforecast.h"
0010 #include "weatherforecastmanager.h"
0011 
0012 #include <QCoreApplication>
0013 #include <QDebug>
0014 #include <QDir>
0015 #include <QFile>
0016 #include <QSignalSpy>
0017 #include <QStandardPaths>
0018 #include <QTest>
0019 #include <QXmlStreamReader>
0020 
0021 class WeatherTest : public QObject
0022 {
0023     Q_OBJECT
0024 private Q_SLOTS:
0025     void initTestCase()
0026     {
0027         QCoreApplication::setApplicationName(QStringLiteral("kde-itinerary-weatherunittest"));
0028         QCoreApplication::setApplicationVersion(QStringLiteral(ITINERARY_VERSION_STRING));
0029 
0030         QStandardPaths::setTestModeEnabled(true);
0031         QDir d(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1StringView("/weather"));
0032         d.removeRecursively();
0033         QVERIFY(!d.exists());
0034     }
0035 
0036     void testParseForecastData()
0037     {
0038         // NOTE: the data file is transformed 100 years into the future to avoid the parser cutting of outdated data
0039         QFile f(QLatin1StringView(SOURCE_DIR "/data/524-135-forecast.xml"));
0040         QVERIFY(f.open(QFile::ReadOnly));
0041         WeatherForecastManager mgr;
0042         QXmlStreamReader reader(&f);
0043         auto forecasts = mgr.parseForecast(reader, {52.4, 13.5});
0044         QCOMPARE(forecasts.size(), 1034);
0045 
0046         mgr.mergeForecasts(forecasts);
0047         QCOMPARE(forecasts.size(), 233);
0048 
0049         for (unsigned int i = 0; i < (forecasts.size() - 1); ++i) {
0050             QVERIFY(forecasts[i].dateTime() < forecasts[i+1].dateTime());
0051         }
0052 
0053         QDateTime dt(QDate(2118, 7, 26), QTime(6,0), Qt::UTC);
0054         auto it = std::lower_bound(forecasts.begin(), forecasts.end(), dt, [](const WeatherForecast &lhs, const QDateTime &rhs) {
0055             return lhs.dateTime() < rhs;
0056         });
0057         QCOMPARE((*it).minimumTemperature(), 21.6f);
0058         QCOMPARE((*it).maximumTemperature(), 21.6f);
0059         QCOMPARE((*it).precipitation(), 0.0f);
0060         QCOMPARE((*it).symbolType(), WeatherForecast::Clear);
0061         QCOMPARE((*it).windSpeed(), 1.6f);
0062         QCOMPARE((*it).isSevere(), false);
0063     }
0064 
0065     void testWeatherSymbol()
0066     {
0067         WeatherForecast fc;
0068         fc.setDateTime({QDate(2018, 8, 1), QTime(2, 0), Qt::UTC}); // CEST is UTC +2
0069         fc.setTile({52.4, 13.5});
0070         fc.setRange(1);
0071         fc.setSymbolType(WeatherForecast::Clear);
0072         QCOMPARE(fc.symbolIconName(), QStringLiteral("weather-clear-night"));
0073         fc.setRange(2);
0074         QCOMPARE(fc.symbolIconName(), QStringLiteral("weather-clear"));
0075         fc.setRange(19);
0076         fc.setSymbolType(WeatherForecast::Clear | WeatherForecast::LightClouds);
0077         QCOMPARE(fc.symbolIconName(), QStringLiteral("weather-few-clouds"));
0078         fc.setDateTime({QDate(2018, 8, 1), QTime(21, 0), Qt::UTC});
0079         fc.setRange(1);
0080         QCOMPARE(fc.symbolIconName(), QStringLiteral("weather-few-clouds-night"));
0081 
0082         fc.setDateTime({QDate(2018, 8, 1), QTime(22, 0), Qt::UTC});
0083         fc.setRange(24);
0084         QCOMPARE(fc.symbolIconName(), QStringLiteral("weather-few-clouds"));
0085 
0086         QVERIFY(!(fc.symbolType() & WeatherForecast::Wind));
0087         fc.setWindSpeed(20.0f);
0088         QVERIFY(fc.symbolType() & WeatherForecast::Wind);
0089     }
0090 
0091     void testForecastRetrieval()
0092     {
0093         if (qEnvironmentVariableIsEmpty("ITINERARY_NO_SKIP_NETWORK_TESTS")) {
0094             QSKIP("Skipping network tests by default, activsate with ITINERARY_NO_SKIP_NETWORK_TESTS=1");
0095             return;
0096         }
0097 
0098         WeatherForecastManager mgr;
0099         mgr.setAllowNetworkAccess(true);
0100         const auto now = QDateTime::currentDateTimeUtc().addSecs(1800);
0101         auto fc = mgr.forecast(46.1, 7.78, now);
0102         QVERIFY(!fc.isValid());
0103 
0104         QSignalSpy updateSpy(&mgr, &WeatherForecastManager::forecastUpdated);
0105         QVERIFY(updateSpy.isValid());
0106 
0107         mgr.monitorLocation(46.1, 7.78);
0108         QVERIFY(updateSpy.wait());
0109 
0110         fc = mgr.forecast(46.1, 7.78, now);
0111         qDebug() << fc.dateTime() << fc.minimumTemperature() << fc.maximumTemperature() << fc.symbolType() << fc.symbolIconName();
0112         QVERIFY(fc.isValid());
0113         QVERIFY(fc.dateTime().isValid());
0114         QVERIFY(fc.dateTime() <= now.addSecs(1800));
0115         QVERIFY(fc.symbolType() != WeatherForecast::None);
0116         QVERIFY(fc.minimumTemperature() > -50);
0117         QVERIFY(fc.minimumTemperature() < 50);
0118         QVERIFY(fc.maximumTemperature() > -50);
0119         QVERIFY(fc.maximumTemperature() < 50);
0120         QVERIFY(fc.maximumTemperature() >= fc.minimumTemperature());
0121         QVERIFY(fc.precipitation() >= 0.0f);
0122         QVERIFY(fc.windSpeed() >= 0.0f);
0123     }
0124 };
0125 
0126 QTEST_GUILESS_MAIN(WeatherTest)
0127 
0128 #include "weathertest.moc"