TestVariable.cpp
409 lines
| 14.9 KiB
| text/x-c
|
CppLexer
r589 | #include <Variable/Variable.h> | |||
Alexandre Leroux
|
r801 | #include <Data/ScalarSeries.h> | ||
r589 | #include <QObject> | |||
#include <QtTest> | ||||
#include <memory> | ||||
Alexandre Leroux
|
r802 | 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<ScalarSeries> dataSeries(const SqpRange &range) | ||||
{ | ||||
auto xAxisData = std::vector<double>{}; | ||||
auto valuesData = std::vector<double>{}; | ||||
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<ScalarSeries>(std::move(xAxisData), std::move(valuesData), Unit{}, | ||||
Unit{}); | ||||
} | ||||
} // namespace | ||||
Alexandre Leroux
|
r801 | Q_DECLARE_METATYPE(std::shared_ptr<ScalarSeries>) | ||
r589 | class TestVariable : public QObject { | |||
Q_OBJECT | ||||
private slots: | ||||
Alexandre Leroux
|
r801 | void testClone_data(); | ||
void testClone(); | ||||
r589 | ||||
Alexandre Leroux
|
r801 | void testNotInCacheRangeList(); | ||
r589 | void testInCacheRangeList(); | |||
Alexandre Leroux
|
r802 | |||
Alexandre Leroux
|
r803 | void testNbPoints_data(); | ||
void testNbPoints(); | ||||
Alexandre Leroux
|
r802 | void testRealRange_data(); | ||
void testRealRange(); | ||||
r589 | }; | |||
Alexandre Leroux
|
r801 | void TestVariable::testClone_data() | ||
{ | ||||
// ////////////// // | ||||
// Test structure // | ||||
// ////////////// // | ||||
QTest::addColumn<QString>("name"); | ||||
QTest::addColumn<QVariantHash>("metadata"); | ||||
QTest::addColumn<SqpRange>("range"); | ||||
QTest::addColumn<SqpRange>("cacheRange"); | ||||
QTest::addColumn<std::shared_ptr<ScalarSeries> >("dataSeries"); | ||||
// ////////// // | ||||
// Test cases // | ||||
// ////////// // | ||||
auto cacheRange = SqpRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 13, 0, 0)}; | ||||
QTest::newRow("clone1") << QStringLiteral("var1") | ||||
<< QVariantHash{{"data1", 1}, {"data2", "abc"}} | ||||
<< SqpRange{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(SqpRange, range); | ||||
QFETCH(SqpRange, cacheRange); | ||||
QFETCH(std::shared_ptr<ScalarSeries>, 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); | ||||
} | ||||
} | ||||
r589 | ||||
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}}; | ||||
r593 | auto sqpR = SqpRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)}; | |||
r589 | ||||
auto varCRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}}; | ||||
auto varCRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}}; | ||||
r756 | ||||
r593 | auto sqpCR | |||
= SqpRange{DateUtils::secondsSinceEpoch(varCRS), DateUtils::secondsSinceEpoch(varCRE)}; | ||||
r589 | ||||
r756 | Variable var{"Var test"}; | |||
var.setRange(sqpR); | ||||
r589 | 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}}; | ||||
r593 | auto sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; | |||
r589 | ||||
auto notInCach = var.provideNotInCacheRangeList(sqp); | ||||
QCOMPARE(notInCach.size(), 1); | ||||
auto notInCachRange = notInCach.first(); | ||||
r593 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); | |||
QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); | ||||
r589 | ||||
// 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}}; | ||||
r593 | sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; | |||
r589 | notInCach = var.provideNotInCacheRangeList(sqp); | |||
QCOMPARE(notInCach.size(), 1); | ||||
notInCachRange = notInCach.first(); | ||||
r593 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); | |||
QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRS)); | ||||
r589 | ||||
// 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}}; | ||||
r593 | sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; | |||
r589 | 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}}; | ||||
r593 | sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; | |||
r589 | notInCach = var.provideNotInCacheRangeList(sqp); | |||
QCOMPARE(notInCach.size(), 1); | ||||
notInCachRange = notInCach.first(); | ||||
r593 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRE)); | |||
QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); | ||||
r589 | ||||
// 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}}; | ||||
r593 | sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; | |||
r589 | notInCach = var.provideNotInCacheRangeList(sqp); | |||
QCOMPARE(notInCach.size(), 1); | ||||
notInCachRange = notInCach.first(); | ||||
r593 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); | |||
QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); | ||||
r589 | ||||
// 6: ts <varTS < varTE < te | ||||
ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}}; | ||||
te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}}; | ||||
r593 | sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; | |||
r589 | notInCach = var.provideNotInCacheRangeList(sqp); | |||
QCOMPARE(notInCach.size(), 2); | ||||
notInCachRange = notInCach.first(); | ||||
r593 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); | |||
QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRS)); | ||||
r589 | notInCachRange = notInCach[1]; | |||
r593 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRE)); | |||
QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); | ||||
r589 | } | |||
void TestVariable::testInCacheRangeList() | ||||
{ | ||||
auto varRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}}; | ||||
auto varRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 40, 0}}; | ||||
r593 | auto sqpR = SqpRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)}; | |||
r589 | ||||
auto varCRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}}; | ||||
auto varCRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}}; | ||||
r593 | auto sqpCR | |||
= SqpRange{DateUtils::secondsSinceEpoch(varCRS), DateUtils::secondsSinceEpoch(varCRE)}; | ||||
r589 | ||||
r756 | Variable var{"Var test"}; | |||
var.setRange(sqpR); | ||||
r589 | 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}}; | ||||
r593 | auto sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; | |||
r589 | ||||
auto notInCach = var.provideInCacheRangeList(sqp); | ||||
QCOMPARE(notInCach.size(), 0); | ||||
// 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}}; | ||||
r593 | sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; | |||
r589 | notInCach = var.provideInCacheRangeList(sqp); | |||
QCOMPARE(notInCach.size(), 1); | ||||
auto notInCachRange = notInCach.first(); | ||||
r593 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRS)); | |||
QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); | ||||
r589 | ||||
// 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}}; | ||||
r593 | sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; | |||
r589 | notInCach = var.provideInCacheRangeList(sqp); | |||
QCOMPARE(notInCach.size(), 1); | ||||
notInCachRange = notInCach.first(); | ||||
r593 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); | |||
QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); | ||||
r589 | ||||
// 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}}; | ||||
r593 | sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; | |||
r589 | notInCach = var.provideInCacheRangeList(sqp); | |||
QCOMPARE(notInCach.size(), 1); | ||||
notInCachRange = notInCach.first(); | ||||
r593 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); | |||
QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRE)); | ||||
r589 | ||||
// 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}}; | ||||
r593 | sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; | |||
r589 | notInCach = var.provideInCacheRangeList(sqp); | |||
QCOMPARE(notInCach.size(), 0); | ||||
// 6: ts <varTS < varTE < te | ||||
ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}}; | ||||
te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}}; | ||||
r593 | sqp = SqpRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; | |||
r589 | notInCach = var.provideInCacheRangeList(sqp); | |||
QCOMPARE(notInCach.size(), 1); | ||||
notInCachRange = notInCach.first(); | ||||
r593 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRS)); | |||
QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRE)); | ||||
r589 | } | |||
Alexandre Leroux
|
r802 | namespace { | ||
Alexandre Leroux
|
r803 | /// Struct used to represent an operation for @sa TestVariable::testNbPoints() | ||
struct NbPointsOperation { | ||||
SqpRange m_CacheRange; /// Range to set for the variable | ||||
std::shared_ptr<ScalarSeries> m_DataSeries; /// Series to merge in the variable | ||||
int m_ExpectedNbPoints; /// Number of points in the variable expected after operation | ||||
}; | ||||
using NbPointsOperations = std::vector<NbPointsOperation>; | ||||
} // namespace | ||||
Q_DECLARE_METATYPE(NbPointsOperations) | ||||
void TestVariable::testNbPoints_data() | ||||
{ | ||||
// ////////////// // | ||||
// Test structure // | ||||
// ////////////// // | ||||
QTest::addColumn<NbPointsOperations>("operations"); | ||||
// ////////// // | ||||
// Test cases // | ||||
// ////////// // | ||||
NbPointsOperations operations{}; | ||||
Alexandre Leroux
|
r858 | // Sets cache range (expected nb points = values data) | ||
Alexandre Leroux
|
r803 | auto cacheRange = SqpRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 12, 0, 9)}; | ||
Alexandre Leroux
|
r858 | operations.push_back({cacheRange, dataSeries(cacheRange), 10}); | ||
Alexandre Leroux
|
r803 | |||
// Doubles cache but don't add data series (expected nb points don't change) | ||||
cacheRange = SqpRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 12, 0, 19)}; | ||||
Alexandre Leroux
|
r858 | operations.push_back({cacheRange, dataSeries(INVALID_RANGE), 10}); | ||
Alexandre Leroux
|
r803 | |||
// Doubles cache and data series (expected nb points change) | ||||
cacheRange = SqpRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 12, 0, 19)}; | ||||
Alexandre Leroux
|
r858 | operations.push_back({cacheRange, dataSeries(cacheRange), 20}); | ||
Alexandre Leroux
|
r803 | |||
// Decreases cache (expected nb points decreases as the series is purged) | ||||
cacheRange = SqpRange{date(2017, 1, 1, 12, 0, 5), date(2017, 1, 1, 12, 0, 9)}; | ||||
Alexandre Leroux
|
r858 | operations.push_back({cacheRange, dataSeries(INVALID_RANGE), 5}); | ||
Alexandre Leroux
|
r803 | |||
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 { | ||||
Alexandre Leroux
|
r802 | /// Struct used to represent a range operation on a variable | ||
/// @sa TestVariable::testRealRange() | ||||
struct RangeOperation { | ||||
SqpRange m_CacheRange; /// Range to set for the variable | ||||
std::shared_ptr<ScalarSeries> m_DataSeries; /// Series to merge in the variable | ||||
SqpRange m_ExpectedRealRange; /// Real Range expected after operation on the variable | ||||
}; | ||||
using RangeOperations = std::vector<RangeOperation>; | ||||
} // namespace | ||||
Q_DECLARE_METATYPE(RangeOperations) | ||||
void TestVariable::testRealRange_data() | ||||
{ | ||||
// ////////////// // | ||||
// Test structure // | ||||
// ////////////// // | ||||
QTest::addColumn<RangeOperations>("operations"); | ||||
// ////////// // | ||||
// Test cases // | ||||
// ////////// // | ||||
RangeOperations operations{}; | ||||
// Inits cache range and data series (expected real range = cache range) | ||||
auto cacheRange = SqpRange{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 = SqpRange{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 = SqpRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 16, 0, 0)}; | ||||
auto dataSeriesRange = SqpRange{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 = SqpRange{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); | ||||
} | ||||
} | ||||
r589 | ||||
QTEST_MAIN(TestVariable) | ||||
#include "TestVariable.moc" | ||||