Commit 3434d23f authored by Volker Krause's avatar Volker Krause

Extend the weather element unit test and fix a number of issues it found

parent 19bfad50
......@@ -227,10 +227,111 @@ private slots:
auto fc = model.index(2, 0).data(TimelineModel::WeatherForecastRole).value<WeatherForecast>();
QVERIFY(fc.isValid());
QCOMPARE(fc.dateTime().date(), QDate::currentDate());
QCOMPARE(fc.minimumTemperature(), 13.0f);
QCOMPARE(fc.maximumTemperature(), 52.0f);
QCOMPARE(model.index(10, 0).data(TimelineModel::ElementTypeRole), TimelineModel::WeatherForecast);
fc = model.index(10, 0).data(TimelineModel::WeatherForecastRole).value<WeatherForecast>();
QVERIFY(fc.isValid());
QCOMPARE(fc.dateTime().date(), QDate::currentDate().addDays(8));
// Add a flight one day from now changing location mid-day
geo.setLatitude(46.0f);
geo.setLongitude(8.0f);
a.setGeo(geo);
f.setArrivalAirport(a);
f.setDepartureTime(QDateTime(QDate::currentDate().addDays(1), QTime(12, 0)));
res.setReservationFor(f);
resMgr.addReservation(res);
QEXPECT_FAIL("", "weather for location changes not implemented yet", Continue);
QCOMPARE(model.rowCount(), 13); // 2x flight, 1x today, 10x weather
QCOMPARE(model.index(0, 0).data(TimelineModel::ElementTypeRole), TimelineModel::Flight);
QCOMPARE(model.index(1, 0).data(TimelineModel::ElementTypeRole), TimelineModel::TodayMarker);
QCOMPARE(model.index(2, 0).data(TimelineModel::ElementTypeRole), TimelineModel::WeatherForecast);
fc = model.index(2, 0).data(TimelineModel::WeatherForecastRole).value<WeatherForecast>();
QVERIFY(fc.isValid());
QCOMPARE(fc.dateTime().date(), QDate::currentDate());
QCOMPARE(model.index(3, 0).data(TimelineModel::ElementTypeRole), TimelineModel::WeatherForecast);
fc = model.index(3, 0).data(TimelineModel::WeatherForecastRole).value<WeatherForecast>();
QVERIFY(fc.isValid());
QCOMPARE(fc.minimumTemperature(), 13.0f);
QCOMPARE(fc.maximumTemperature(), 52.0f);
QCOMPARE(fc.dateTime(), QDateTime(QDate::currentDate().addDays(1), QTime(0, 0)));
QCOMPARE(model.index(4, 0).data(TimelineModel::ElementTypeRole), TimelineModel::Flight);
QCOMPARE(model.index(5, 0).data(TimelineModel::ElementTypeRole), TimelineModel::WeatherForecast);
fc = model.index(5, 0).data(TimelineModel::WeatherForecastRole).value<WeatherForecast>();
QVERIFY(fc.isValid());
QCOMPARE(fc.minimumTemperature(), 8.0f);
QCOMPARE(fc.maximumTemperature(), 46.0f);
QEXPECT_FAIL("", "weather for location changes not implemented yet", Continue);
QCOMPARE(fc.dateTime(), QDateTime(QDate::currentDate().addDays(1), QTime(12, 0)));
QCOMPARE(model.index(6, 0).data(TimelineModel::ElementTypeRole), TimelineModel::WeatherForecast);
fc = model.index(6, 0).data(TimelineModel::WeatherForecastRole).value<WeatherForecast>();
QCOMPARE(fc.minimumTemperature(), 8.0f);
QCOMPARE(fc.maximumTemperature(), 46.0f);
QVERIFY(fc.isValid());
QEXPECT_FAIL("", "weather for location changes not implemented yet", Continue);
QCOMPARE(fc.dateTime(), QDateTime(QDate::currentDate().addDays(2), QTime(0, 0)));
// check we get update signals for all weather elements
QSignalSpy spy(&model, &TimelineModel::dataChanged);
QVERIFY(spy.isValid());
emit weatherMgr.forecastUpdated();
QEXPECT_FAIL("", "weather for location changes not implemented yet", Continue);
QCOMPARE(spy.size(), 10);
fc = model.index(3, 0).data(TimelineModel::WeatherForecastRole).value<WeatherForecast>();
QVERIFY(fc.isValid());
QCOMPARE(fc.minimumTemperature(), 13.0f);
QCOMPARE(fc.maximumTemperature(), 52.0f);
QCOMPARE(fc.dateTime(), QDateTime(QDate::currentDate().addDays(1), QTime(0, 0)));
fc = model.index(9, 0).data(TimelineModel::WeatherForecastRole).value<WeatherForecast>();
QVERIFY(fc.isValid());
QCOMPARE(fc.minimumTemperature(), 8.0f);
QCOMPARE(fc.maximumTemperature(), 46.0f);
QEXPECT_FAIL("", "weather for location changes not implemented yet", Continue);
QCOMPARE(fc.dateTime(), QDateTime(QDate::currentDate().addDays(5), QTime(0, 0)));
// add a location change far in the future, this must not change anything
geo.setLatitude(60.0f);
geo.setLongitude(11.0f);
a.setGeo(geo);
f.setArrivalAirport(a);
f.setDepartureTime(QDateTime(QDate::currentDate().addYears(1), QTime(6, 0)));
res.setReservationFor(f);
resMgr.addReservation(res);
QEXPECT_FAIL("", "weather for location changes not implemented yet", Continue);
QCOMPARE(model.rowCount(), 14);
fc = model.index(3, 0).data(TimelineModel::WeatherForecastRole).value<WeatherForecast>();
QVERIFY(fc.isValid());
QCOMPARE(fc.minimumTemperature(), 13.0f);
QCOMPARE(fc.maximumTemperature(), 52.0f);
QCOMPARE(fc.dateTime(), QDateTime(QDate::currentDate().addDays(1), QTime(0, 0)));
fc = model.index(9, 0).data(TimelineModel::WeatherForecastRole).value<WeatherForecast>();
QVERIFY(fc.isValid());
QCOMPARE(fc.minimumTemperature(), 8.0f);
QCOMPARE(fc.maximumTemperature(), 46.0f);
QEXPECT_FAIL("", "weather for location changes not implemented yet", Continue);
QCOMPARE(fc.dateTime(), QDateTime(QDate::currentDate().addDays(5), QTime(0, 0)));
// result is the same when data hasn't been added incrementally
model.setReservationManager(nullptr);
model.setReservationManager(&resMgr);
QEXPECT_FAIL("", "weather for location changes not implemented yet", Continue);
QCOMPARE(model.rowCount(), 14);
fc = model.index(3, 0).data(TimelineModel::WeatherForecastRole).value<WeatherForecast>();
QVERIFY(fc.isValid());
QCOMPARE(fc.minimumTemperature(), 13.0f);
QCOMPARE(fc.maximumTemperature(), 52.0f);
QCOMPARE(fc.dateTime(), QDateTime(QDate::currentDate().addDays(1), QTime(0, 0)));
fc = model.index(9, 0).data(TimelineModel::WeatherForecastRole).value<WeatherForecast>();
QVERIFY(fc.isValid());
QCOMPARE(fc.minimumTemperature(), 8.0f);
QCOMPARE(fc.maximumTemperature(), 46.0f);
QEXPECT_FAIL("", "weather for location changes not implemented yet", Continue);
QCOMPARE(fc.dateTime(), QDateTime(QDate::currentDate().addDays(5), QTime(0, 0)));
}
};
......
......@@ -145,6 +145,18 @@ TimelineModel::~TimelineModel() = default;
void TimelineModel::setReservationManager(ReservationManager* mgr)
{
// for auto tests only
if (Q_UNLIKELY(!mgr)) {
beginResetModel();
disconnect(mgr, &ReservationManager::reservationAdded, this, &TimelineModel::reservationAdded);
disconnect(mgr, &ReservationManager::reservationUpdated, this, &TimelineModel::reservationUpdated);
disconnect(mgr, &ReservationManager::reservationRemoved, this, &TimelineModel::reservationRemoved);
m_resMgr = mgr;
m_elements.clear();
endResetModel();
return;
}
beginResetModel();
m_resMgr = mgr;
for (const auto &resId : mgr->reservations()) {
......@@ -172,7 +184,7 @@ void TimelineModel::setReservationManager(ReservationManager* mgr)
void TimelineModel::setWeatherForecastManager(WeatherForecastManager* mgr)
{
m_weatherMgr = mgr;
insertWeatherElements();
updateWeatherElements();
connect(m_weatherMgr, &WeatherForecastManager::forecastUpdated, this, &TimelineModel::updateWeatherElements);
}
......@@ -379,7 +391,7 @@ void TimelineModel::updateInformationElements()
previousCountry = newCountry;
}
insertWeatherElements();
updateWeatherElements();
}
std::vector<TimelineModel::Element>::iterator TimelineModel::erasePreviousCountyInfo(std::vector<Element>::iterator it)
......@@ -399,7 +411,7 @@ std::vector<TimelineModel::Element>::iterator TimelineModel::erasePreviousCounty
return it;
}
void TimelineModel::insertWeatherElements()
void TimelineModel::updateWeatherElements()
{
if (!m_weatherMgr || m_elements.empty()) {
return;
......@@ -430,32 +442,46 @@ void TimelineModel::insertWeatherElements()
auto date = QDate::currentDate();
for (; it != m_elements.end() && date < QDate::currentDate().addDays(9);) {
if ((*it).dt.date() < date || (*it).elementType == TodayMarker) {
// track where we are
const auto res = m_resMgr->reservation((*it).id);
const auto newGeo = geoCoordinate(res);
if (isLocationChange(res) || newGeo.isValid()) {
geo = newGeo;
}
++it;
continue;
}
if (date == (*it).dt.date() && (*it).elementType == WeatherForecast) { // weather element already present
date = date.addDays(1);
++it;
continue;
}
const auto res = m_resMgr->reservation((*it).id);
const auto newGeo = geoCoordinate(res);
if (isLocationChange(res) || newGeo.isValid()) {
geo = newGeo;
}
::WeatherForecast fc;
if (geo.isValid()) {
m_weatherMgr->monitorLocation(geo.latitude(), geo.longitude());
const auto fc = m_weatherMgr->forecast(geo.latitude(), geo.longitude(), QDateTime(date, QTime(0, 0)), QDateTime(date, QTime(23, 59)));
if (fc.isValid()) {
const auto row = std::distance(m_elements.begin(), it);
beginInsertRows({}, row, row);
it = m_elements.insert(it, Element{{}, QVariant::fromValue(fc), QDateTime(date, QTime()), WeatherForecast, SelfContained});
endInsertRows();
}
fc = m_weatherMgr->forecast(geo.latitude(), geo.longitude(), QDateTime(date, QTime(0, 0)), QDateTime(date, QTime(23, 59)));
}
// case 1: we have forecast data, and a matching weather element: update
if (fc.isValid() && (*it).dt.date() == date && (*it).elementType == WeatherForecast) {
(*it).content = QVariant::fromValue(fc);
const auto idx = index(std::distance(m_elements.begin(), it), 0);
emit dataChanged(idx, idx);
}
// case 2: we have forecast data, but no matching weather element: insert
else if (fc.isValid()) {
const auto row = std::distance(m_elements.begin(), it);
beginInsertRows({}, row, row);
it = m_elements.insert(it, Element{{}, QVariant::fromValue(fc), QDateTime(date, QTime()), WeatherForecast, SelfContained});
endInsertRows();
}
// case 3: we have no forecast data, but a matching weather element: remove
else if ((*it).elementType == WeatherForecast && (*it).dt.date() == date) {
const auto row = std::distance(m_elements.begin(), it);
beginRemoveRows({}, row, row);
it = m_elements.erase(it);
endRemoveRows();
}
date = date.addDays(1);
++it;
}
......@@ -476,17 +502,3 @@ void TimelineModel::insertWeatherElements()
qDebug() << "weather recomputation done";
}
void TimelineModel::updateWeatherElements()
{
for (auto it = m_elements.begin(); it != m_elements.end(); ++it) {
if ((*it).elementType == WeatherForecast) {
// TODO see above
(*it).content = QVariant::fromValue(m_weatherMgr->forecast(52, 13.5, QDateTime((*it).dt.date(), QTime(0, 0)), QDateTime((*it).dt.date(), QTime(23, 59))));
const auto idx = index(std::distance(m_elements.begin(), it), 0);
emit dataChanged(idx, idx);
}
}
insertWeatherElements();
}
......@@ -102,7 +102,6 @@ private:
void updateInformationElements();
std::vector<Element>::iterator erasePreviousCountyInfo(std::vector<Element>::iterator it);
void insertWeatherElements();
void updateWeatherElements();
ReservationManager *m_resMgr = nullptr;
......
......@@ -88,9 +88,9 @@ WeatherForecast WeatherForecastManager::forecast(float latitude, float longitude
if (Q_UNLIKELY(m_testMode)) {
WeatherForecast fc;
fc.setDateTime(beginDt);
fc.setMinimumTemperature(23.0f);
fc.setMaximumTemperature(23.0f);
fc.setPrecipitation(0.0f);
fc.setMinimumTemperature(std::min(latitude, longitude));
fc.setMaximumTemperature(std::max(latitude, longitude));
fc.setPrecipitation(23.0f);
fc.setSymbolType(WeatherForecast::LightClouds);
return fc;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment