diff --git a/include/Variable/Variable.h b/include/Variable/Variable.h index 293d1fc..00ae78a 100644 --- a/include/Variable/Variable.h +++ b/include/Variable/Variable.h @@ -94,33 +94,10 @@ public: return variables; } -DEPRECATE( - - bool contains(const DateTimeRange &range) const noexcept; - bool intersect(const DateTimeRange &range) const noexcept; - bool isInside(const DateTimeRange &range) const noexcept; - - bool cacheContains(const DateTimeRange &range) const noexcept; - bool cacheIntersect(const DateTimeRange &range) const noexcept; - bool cacheIsInside(const DateTimeRange &range) const noexcept; - QVector provideNotInCacheRangeList(const DateTimeRange &range) const noexcept; - QVector provideInCacheRangeList(const DateTimeRange &range) const noexcept; - void mergeDataSeries(std::shared_ptr dataSeries) noexcept; - static QVector provideNotInCacheRangeList(const DateTimeRange &oldRange, - const DateTimeRange &nextRange); - - static QVector provideInCacheRangeList(const DateTimeRange &oldRange, - const DateTimeRange &nextRange); - ) - operator QUuid() {return _uuid;} QUuid ID(){return _uuid;} signals: void updated(); - DEPRECATE( - /// Signal emitted when when the data series of the variable is loaded for the first time - void dataInitialized(); - ) private: class VariablePrivate; spimpl::unique_impl_ptr impl; diff --git a/src/Variable/Variable.cpp b/src/Variable/Variable.cpp index a09a586..d83000e 100644 --- a/src/Variable/Variable.cpp +++ b/src/Variable/Variable.cpp @@ -54,6 +54,7 @@ static DataSeriesType findDataSeriesType(const QVariantHash &metadata) void Variable::setter(const type& getter) noexcept \ {\ impl->setter(getter);\ + emit updated();\ }\ struct Variable::VariablePrivate { @@ -179,34 +180,6 @@ std::optional Variable::realRange() const noexcept return impl->realRange(); } -void Variable::mergeDataSeries(std::shared_ptr dataSeries) noexcept -{ - qCDebug(LOG_Variable()) << "TORM Variable::mergeDataSeries" - << QThread::currentThread()->objectName(); - if (!dataSeries) { - /// @todo ALX : log - return; - } - - auto dataInit = false; - - // Add or merge the data - impl->lockWrite(); - if (!impl->m_DataSeries) { - impl->m_DataSeries = dataSeries->clone(); - dataInit = true; - } - else { - impl->m_DataSeries->merge(dataSeries.get()); - } - impl->purgeDataSeries(); - impl->unlock(); - - if (dataInit) { - emit dataInitialized(); - } -} - void Variable::updateData(const std::vector &dataSeries, const DateTimeRange &newRange, const DateTimeRange &newCacheRange, bool notify) { { @@ -239,198 +212,3 @@ QVariantHash Variable::metadata() const noexcept return metadata; } -bool Variable::contains(const DateTimeRange &range) const noexcept -{ - impl->lockRead(); - auto res = impl->m_Range.contains(range); - impl->unlock(); - return res; -} - -bool Variable::intersect(const DateTimeRange &range) const noexcept -{ - - impl->lockRead(); - auto res = impl->m_Range.intersect(range); - impl->unlock(); - return res; -} - -bool Variable::isInside(const DateTimeRange &range) const noexcept -{ - impl->lockRead(); - auto res = range.contains(DateTimeRange{impl->m_Range.m_TStart, impl->m_Range.m_TEnd}); - impl->unlock(); - return res; -} - -bool Variable::cacheContains(const DateTimeRange &range) const noexcept -{ - impl->lockRead(); - auto res = impl->m_CacheRange.contains(range); - impl->unlock(); - return res; -} - -bool Variable::cacheIntersect(const DateTimeRange &range) const noexcept -{ - impl->lockRead(); - auto res = impl->m_CacheRange.intersect(range); - impl->unlock(); - return res; -} - -bool Variable::cacheIsInside(const DateTimeRange &range) const noexcept -{ - impl->lockRead(); - auto res = range.contains(DateTimeRange{impl->m_CacheRange.m_TStart, impl->m_CacheRange.m_TEnd}); - impl->unlock(); - return res; -} - - -QVector Variable::provideNotInCacheRangeList(const DateTimeRange &range) const noexcept -{ - // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange - auto notInCache = QVector{}; - if (impl->m_CacheRange != INVALID_RANGE) { - - if (!this->cacheContains(range)) { - if (range.m_TEnd <= impl->m_CacheRange.m_TStart - || range.m_TStart >= impl->m_CacheRange.m_TEnd) { - notInCache << range; - } - else if (range.m_TStart < impl->m_CacheRange.m_TStart - && range.m_TEnd <= impl->m_CacheRange.m_TEnd) { - notInCache << DateTimeRange{range.m_TStart, impl->m_CacheRange.m_TStart}; - } - else if (range.m_TStart < impl->m_CacheRange.m_TStart - && range.m_TEnd > impl->m_CacheRange.m_TEnd) { - notInCache << DateTimeRange{range.m_TStart, impl->m_CacheRange.m_TStart} - << DateTimeRange{impl->m_CacheRange.m_TEnd, range.m_TEnd}; - } - else if (range.m_TStart < impl->m_CacheRange.m_TEnd) { - notInCache << DateTimeRange{impl->m_CacheRange.m_TEnd, range.m_TEnd}; - } - else { - qCCritical(LOG_Variable()) << tr("Detection of unknown case.") - << QThread::currentThread(); - } - } - } - else { - notInCache << range; - } - - return notInCache; -} - -QVector Variable::provideInCacheRangeList(const DateTimeRange &range) const noexcept -{ - // This code assume that cach in contigue. Can return 0 or 1 SqpRange - - auto inCache = QVector{}; - - if (impl->m_CacheRange != INVALID_RANGE) { - - if (this->cacheIntersect(range)) { - if (range.m_TStart <= impl->m_CacheRange.m_TStart - && range.m_TEnd >= impl->m_CacheRange.m_TStart - && range.m_TEnd < impl->m_CacheRange.m_TEnd) { - inCache << DateTimeRange{impl->m_CacheRange.m_TStart, range.m_TEnd}; - } - - else if (range.m_TStart >= impl->m_CacheRange.m_TStart - && range.m_TEnd <= impl->m_CacheRange.m_TEnd) { - inCache << range; - } - else if (range.m_TStart > impl->m_CacheRange.m_TStart - && range.m_TEnd > impl->m_CacheRange.m_TEnd) { - inCache << DateTimeRange{range.m_TStart, impl->m_CacheRange.m_TEnd}; - } - else if (range.m_TStart <= impl->m_CacheRange.m_TStart - && range.m_TEnd >= impl->m_CacheRange.m_TEnd) { - inCache << impl->m_CacheRange; - } - else { - qCCritical(LOG_Variable()) << tr("Detection of unknown case.") - << QThread::currentThread(); - } - } - } - - return inCache; -} - - -QVector Variable::provideNotInCacheRangeList(const DateTimeRange &oldRange, - const DateTimeRange &nextRange) -{ - - // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange - auto notInCache = QVector{}; - if (oldRange != INVALID_RANGE) { - - if (!oldRange.contains(nextRange)) { - if (nextRange.m_TEnd <= oldRange.m_TStart || nextRange.m_TStart >= oldRange.m_TEnd) { - notInCache << nextRange; - } - else if (nextRange.m_TStart < oldRange.m_TStart - && nextRange.m_TEnd <= oldRange.m_TEnd) { - notInCache << DateTimeRange{nextRange.m_TStart, oldRange.m_TStart}; - } - else if (nextRange.m_TStart < oldRange.m_TStart && nextRange.m_TEnd > oldRange.m_TEnd) { - notInCache << DateTimeRange{nextRange.m_TStart, oldRange.m_TStart} - << DateTimeRange{oldRange.m_TEnd, nextRange.m_TEnd}; - } - else if (nextRange.m_TStart < oldRange.m_TEnd) { - notInCache << DateTimeRange{oldRange.m_TEnd, nextRange.m_TEnd}; - } - else { - qCCritical(LOG_Variable()) << tr("Detection of unknown case.") - << QThread::currentThread(); - } - } - } - else { - notInCache << nextRange; - } - - return notInCache; -} - -QVector Variable::provideInCacheRangeList(const DateTimeRange &oldRange, - const DateTimeRange &nextRange) -{ - // This code assume that cach is contigue. Can return 0 or 1 SqpRange - - auto inCache = QVector{}; - - if (oldRange != INVALID_RANGE) { - - if (oldRange.intersect(nextRange)) { - if (nextRange.m_TStart <= oldRange.m_TStart && nextRange.m_TEnd >= oldRange.m_TStart - && nextRange.m_TEnd < oldRange.m_TEnd) { - inCache << DateTimeRange{oldRange.m_TStart, nextRange.m_TEnd}; - } - - else if (nextRange.m_TStart >= oldRange.m_TStart - && nextRange.m_TEnd <= oldRange.m_TEnd) { - inCache << nextRange; - } - else if (nextRange.m_TStart > oldRange.m_TStart && nextRange.m_TEnd > oldRange.m_TEnd) { - inCache << DateTimeRange{nextRange.m_TStart, oldRange.m_TEnd}; - } - else if (nextRange.m_TStart <= oldRange.m_TStart - && nextRange.m_TEnd >= oldRange.m_TEnd) { - inCache << oldRange; - } - else { - qCCritical(LOG_Variable()) << tr("Detection of unknown case.") - << QThread::currentThread(); - } - } - } - - return inCache; -} diff --git a/tests/Variable/TestVariable.cpp b/tests/Variable/TestVariable.cpp index b49299f..a4ba7f0 100644 --- a/tests/Variable/TestVariable.cpp +++ b/tests/Variable/TestVariable.cpp @@ -7,403 +7,16 @@ #include -namespace { -/// Generates a date in double -auto date = [](int year, int month, int day, int hours, int minutes, int seconds) { - return DateUtils::secondsSinceEpoch( - QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC}); -}; - -/// Generates a series of test data for a range -std::shared_ptr dataSeries(const DateTimeRange &range) -{ - auto xAxisData = std::vector{}; - auto valuesData = std::vector{}; - - auto value = 0; - for (auto x = range.m_TStart; x <= range.m_TEnd; ++x, ++value) { - xAxisData.push_back(x); - valuesData.push_back(value); - } - - return std::make_shared(std::move(xAxisData), std::move(valuesData), Unit{}, - Unit{}); -} - -} // namespace - -Q_DECLARE_METATYPE(std::shared_ptr) class TestVariable : public QObject { Q_OBJECT private slots: - void initTestCase() { QSKIP("Skip it"); } - void testClone_data(); - void testClone(); - - void testNotInCacheRangeList(); - void testInCacheRangeList(); - - void testNbPoints_data(); - void testNbPoints(); - - void testRealRange_data(); - void testRealRange(); + void initTestCase() { QSKIP("Please Write me! .·´¯`(>▂<)´¯`·. "); } }; -void TestVariable::testClone_data() -{ - // ////////////// // - // Test structure // - // ////////////// // - - QTest::addColumn("name"); - QTest::addColumn("metadata"); - QTest::addColumn("range"); - QTest::addColumn("cacheRange"); - QTest::addColumn >("dataSeries"); - - // ////////// // - // Test cases // - // ////////// // - - auto cacheRange = DateTimeRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 13, 0, 0)}; - QTest::newRow("clone1") << QStringLiteral("var1") - << QVariantHash{{"data1", 1}, {"data2", "abc"}} - << DateTimeRange{date(2017, 1, 1, 12, 30, 0), (date(2017, 1, 1, 12, 45, 0))} - << cacheRange << dataSeries(cacheRange); -} - -void TestVariable::testClone() -{ - // Creates variable - QFETCH(QString, name); - QFETCH(QVariantHash, metadata); - QFETCH(DateTimeRange, range); - QFETCH(DateTimeRange, cacheRange); - QFETCH(std::shared_ptr, dataSeries); - - Variable variable{name, metadata}; - variable.setRange(range); - variable.setCacheRange(cacheRange); - variable.mergeDataSeries(dataSeries); - - // Clones variable - auto clone = variable.clone(); - - // Checks cloned variable's state - QCOMPARE(clone->name(), name); - QCOMPARE(clone->metadata(), metadata); - QCOMPARE(clone->range(), range); - QCOMPARE(clone->cacheRange(), cacheRange); - - // Compares data series - if (dataSeries != nullptr) { - QVERIFY(clone->dataSeries() != nullptr); - QVERIFY(std::equal(dataSeries->cbegin(), dataSeries->cend(), clone->dataSeries()->cbegin(), - clone->dataSeries()->cend(), [](const auto &it1, const auto &it2) { - return it1.x() == it2.x() && it1.value() == it2.value(); - })); - } - else { - QVERIFY(clone->dataSeries() == nullptr); - } -} - -void TestVariable::testNotInCacheRangeList() -{ - auto varRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}}; - auto varRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 40, 0}}; - - auto sqpR = DateTimeRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)}; - - auto varCRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}}; - auto varCRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}}; - - auto sqpCR - = DateTimeRange{DateUtils::secondsSinceEpoch(varCRS), DateUtils::secondsSinceEpoch(varCRE)}; - - Variable var{"Var test"}; - var.setRange(sqpR); - var.setCacheRange(sqpCR); - - // 1: [ts,te] < varTS - auto ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}}; - auto te = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}}; - auto sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; - - auto notInCach = var.provideNotInCacheRangeList(sqp); - - QCOMPARE(notInCach.size(), 1); - - auto notInCachRange = notInCach.first(); - - QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); - QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); - - // 2: ts < varTS < te < varTE - ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}}; - te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}}; - sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; - notInCach = var.provideNotInCacheRangeList(sqp); - QCOMPARE(notInCach.size(), 1); - notInCachRange = notInCach.first(); - QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); - QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRS)); - - // 3: varTS < ts < te < varTE - ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}}; - te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}}; - sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; - notInCach = var.provideNotInCacheRangeList(sqp); - QCOMPARE(notInCach.size(), 0); - - - // 4: varTS < ts < varTE < te - ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}}; - te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}}; - sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; - notInCach = var.provideNotInCacheRangeList(sqp); - QCOMPARE(notInCach.size(), 1); - notInCachRange = notInCach.first(); - QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRE)); - QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); - - // 5: varTS < varTE < ts < te - ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 20, 0}}; - te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}}; - sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; - notInCach = var.provideNotInCacheRangeList(sqp); - QCOMPARE(notInCach.size(), 1); - notInCachRange = notInCach.first(); - QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); - QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); - - // 6: ts m_DataSeries; /// Series to merge in the variable - int m_ExpectedNbPoints; /// Number of points in the variable expected after operation -}; - -using NbPointsOperations = std::vector; - -} // namespace - -Q_DECLARE_METATYPE(NbPointsOperations) - -void TestVariable::testNbPoints_data() -{ - // ////////////// // - // Test structure // - // ////////////// // - - QTest::addColumn("operations"); - - // ////////// // - // Test cases // - // ////////// // - NbPointsOperations operations{}; - - // Sets cache range (expected nb points = values data) - auto cacheRange = DateTimeRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 12, 0, 9)}; - operations.push_back({cacheRange, dataSeries(cacheRange), 10}); - - // Doubles cache but don't add data series (expected nb points don't change) - cacheRange = DateTimeRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 12, 0, 19)}; - operations.push_back({cacheRange, dataSeries(INVALID_RANGE), 10}); - - // Doubles cache and data series (expected nb points change) - cacheRange = DateTimeRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 12, 0, 19)}; - operations.push_back({cacheRange, dataSeries(cacheRange), 20}); - - // Decreases cache (expected nb points decreases as the series is purged) - cacheRange = DateTimeRange{date(2017, 1, 1, 12, 0, 5), date(2017, 1, 1, 12, 0, 9)}; - operations.push_back({cacheRange, dataSeries(INVALID_RANGE), 5}); - - QTest::newRow("nbPoints1") << operations; -} - -void TestVariable::testNbPoints() -{ - // Creates variable - Variable variable{"var"}; - QCOMPARE(variable.nbPoints(), 0); - - QFETCH(NbPointsOperations, operations); - for (const auto &operation : operations) { - // Sets cache range and merge data series - variable.setCacheRange(operation.m_CacheRange); - if (operation.m_DataSeries != nullptr) { - variable.mergeDataSeries(operation.m_DataSeries); - } - - // Checks nb points - QCOMPARE(variable.nbPoints(), operation.m_ExpectedNbPoints); - } -} - -namespace { - -/// Struct used to represent a range operation on a variable -/// @sa TestVariable::testRealRange() -struct RangeOperation { - DateTimeRange m_CacheRange; /// Range to set for the variable - std::shared_ptr m_DataSeries; /// Series to merge in the variable - DateTimeRange m_ExpectedRealRange; /// Real Range expected after operation on the variable -}; - -using RangeOperations = std::vector; - -} // namespace - -Q_DECLARE_METATYPE(RangeOperations) - -void TestVariable::testRealRange_data() -{ - // ////////////// // - // Test structure // - // ////////////// // - - QTest::addColumn("operations"); - - // ////////// // - // Test cases // - // ////////// // - RangeOperations operations{}; - - // Inits cache range and data series (expected real range = cache range) - auto cacheRange = DateTimeRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 13, 0, 0)}; - operations.push_back({cacheRange, dataSeries(cacheRange), cacheRange}); - - // Changes cache range and updates data series (expected real range = cache range) - cacheRange = DateTimeRange{date(2017, 1, 1, 14, 0, 0), date(2017, 1, 1, 15, 0, 0)}; - operations.push_back({cacheRange, dataSeries(cacheRange), cacheRange}); - - // Changes cache range and update data series but with a lower range (expected real range = - // data series range) - cacheRange = DateTimeRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 16, 0, 0)}; - auto dataSeriesRange = DateTimeRange{date(2017, 1, 1, 14, 0, 0), date(2017, 1, 1, 15, 0, 0)}; - operations.push_back({cacheRange, dataSeries(dataSeriesRange), dataSeriesRange}); - - // Changes cache range but DON'T update data series (expected real range = cache range - // before operation) - cacheRange = DateTimeRange{date(2017, 1, 1, 10, 0, 0), date(2017, 1, 1, 17, 0, 0)}; - operations.push_back({cacheRange, nullptr, dataSeriesRange}); - - QTest::newRow("realRange1") << operations; -} - -void TestVariable::testRealRange() -{ - // Creates variable (real range is invalid) - Variable variable{"var"}; - QCOMPARE(variable.realRange(), INVALID_RANGE); - - QFETCH(RangeOperations, operations); - for (const auto &operation : operations) { - // Sets cache range and merge data series - variable.setCacheRange(operation.m_CacheRange); - if (operation.m_DataSeries != nullptr) { - variable.mergeDataSeries(operation.m_DataSeries); - } - // Checks real range - QCOMPARE(variable.realRange(), operation.m_ExpectedRealRange); - } -} QTEST_MAIN(TestVariable)