@@ -94,33 +94,10 public: | |||||
94 | return variables; |
|
94 | return variables; | |
95 | } |
|
95 | } | |
96 |
|
96 | |||
97 | DEPRECATE( |
|
|||
98 |
|
||||
99 | bool contains(const DateTimeRange &range) const noexcept; |
|
|||
100 | bool intersect(const DateTimeRange &range) const noexcept; |
|
|||
101 | bool isInside(const DateTimeRange &range) const noexcept; |
|
|||
102 |
|
||||
103 | bool cacheContains(const DateTimeRange &range) const noexcept; |
|
|||
104 | bool cacheIntersect(const DateTimeRange &range) const noexcept; |
|
|||
105 | bool cacheIsInside(const DateTimeRange &range) const noexcept; |
|
|||
106 | QVector<DateTimeRange> provideNotInCacheRangeList(const DateTimeRange &range) const noexcept; |
|
|||
107 | QVector<DateTimeRange> provideInCacheRangeList(const DateTimeRange &range) const noexcept; |
|
|||
108 | void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept; |
|
|||
109 | static QVector<DateTimeRange> provideNotInCacheRangeList(const DateTimeRange &oldRange, |
|
|||
110 | const DateTimeRange &nextRange); |
|
|||
111 |
|
||||
112 | static QVector<DateTimeRange> provideInCacheRangeList(const DateTimeRange &oldRange, |
|
|||
113 | const DateTimeRange &nextRange); |
|
|||
114 | ) |
|
|||
115 |
|
||||
116 | operator QUuid() {return _uuid;} |
|
97 | operator QUuid() {return _uuid;} | |
117 | QUuid ID(){return _uuid;} |
|
98 | QUuid ID(){return _uuid;} | |
118 | signals: |
|
99 | signals: | |
119 | void updated(); |
|
100 | void updated(); | |
120 | DEPRECATE( |
|
|||
121 | /// Signal emitted when when the data series of the variable is loaded for the first time |
|
|||
122 | void dataInitialized(); |
|
|||
123 | ) |
|
|||
124 | private: |
|
101 | private: | |
125 | class VariablePrivate; |
|
102 | class VariablePrivate; | |
126 | spimpl::unique_impl_ptr<VariablePrivate> impl; |
|
103 | spimpl::unique_impl_ptr<VariablePrivate> impl; |
@@ -54,6 +54,7 static DataSeriesType findDataSeriesType(const QVariantHash &metadata) | |||||
54 | void Variable::setter(const type& getter) noexcept \ |
|
54 | void Variable::setter(const type& getter) noexcept \ | |
55 | {\ |
|
55 | {\ | |
56 | impl->setter(getter);\ |
|
56 | impl->setter(getter);\ | |
|
57 | emit updated();\ | |||
57 | }\ |
|
58 | }\ | |
58 |
|
59 | |||
59 | struct Variable::VariablePrivate { |
|
60 | struct Variable::VariablePrivate { | |
@@ -179,34 +180,6 std::optional<DateTimeRange> Variable::realRange() const noexcept | |||||
179 | return impl->realRange(); |
|
180 | return impl->realRange(); | |
180 | } |
|
181 | } | |
181 |
|
182 | |||
182 | void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept |
|
|||
183 | { |
|
|||
184 | qCDebug(LOG_Variable()) << "TORM Variable::mergeDataSeries" |
|
|||
185 | << QThread::currentThread()->objectName(); |
|
|||
186 | if (!dataSeries) { |
|
|||
187 | /// @todo ALX : log |
|
|||
188 | return; |
|
|||
189 | } |
|
|||
190 |
|
||||
191 | auto dataInit = false; |
|
|||
192 |
|
||||
193 | // Add or merge the data |
|
|||
194 | impl->lockWrite(); |
|
|||
195 | if (!impl->m_DataSeries) { |
|
|||
196 | impl->m_DataSeries = dataSeries->clone(); |
|
|||
197 | dataInit = true; |
|
|||
198 | } |
|
|||
199 | else { |
|
|||
200 | impl->m_DataSeries->merge(dataSeries.get()); |
|
|||
201 | } |
|
|||
202 | impl->purgeDataSeries(); |
|
|||
203 | impl->unlock(); |
|
|||
204 |
|
||||
205 | if (dataInit) { |
|
|||
206 | emit dataInitialized(); |
|
|||
207 | } |
|
|||
208 | } |
|
|||
209 |
|
||||
210 | void Variable::updateData(const std::vector<IDataSeries *> &dataSeries, const DateTimeRange &newRange, const DateTimeRange &newCacheRange, bool notify) |
|
183 | void Variable::updateData(const std::vector<IDataSeries *> &dataSeries, const DateTimeRange &newRange, const DateTimeRange &newCacheRange, bool notify) | |
211 | { |
|
184 | { | |
212 | { |
|
185 | { | |
@@ -239,198 +212,3 QVariantHash Variable::metadata() const noexcept | |||||
239 | return metadata; |
|
212 | return metadata; | |
240 | } |
|
213 | } | |
241 |
|
214 | |||
242 | bool Variable::contains(const DateTimeRange &range) const noexcept |
|
|||
243 | { |
|
|||
244 | impl->lockRead(); |
|
|||
245 | auto res = impl->m_Range.contains(range); |
|
|||
246 | impl->unlock(); |
|
|||
247 | return res; |
|
|||
248 | } |
|
|||
249 |
|
||||
250 | bool Variable::intersect(const DateTimeRange &range) const noexcept |
|
|||
251 | { |
|
|||
252 |
|
||||
253 | impl->lockRead(); |
|
|||
254 | auto res = impl->m_Range.intersect(range); |
|
|||
255 | impl->unlock(); |
|
|||
256 | return res; |
|
|||
257 | } |
|
|||
258 |
|
||||
259 | bool Variable::isInside(const DateTimeRange &range) const noexcept |
|
|||
260 | { |
|
|||
261 | impl->lockRead(); |
|
|||
262 | auto res = range.contains(DateTimeRange{impl->m_Range.m_TStart, impl->m_Range.m_TEnd}); |
|
|||
263 | impl->unlock(); |
|
|||
264 | return res; |
|
|||
265 | } |
|
|||
266 |
|
||||
267 | bool Variable::cacheContains(const DateTimeRange &range) const noexcept |
|
|||
268 | { |
|
|||
269 | impl->lockRead(); |
|
|||
270 | auto res = impl->m_CacheRange.contains(range); |
|
|||
271 | impl->unlock(); |
|
|||
272 | return res; |
|
|||
273 | } |
|
|||
274 |
|
||||
275 | bool Variable::cacheIntersect(const DateTimeRange &range) const noexcept |
|
|||
276 | { |
|
|||
277 | impl->lockRead(); |
|
|||
278 | auto res = impl->m_CacheRange.intersect(range); |
|
|||
279 | impl->unlock(); |
|
|||
280 | return res; |
|
|||
281 | } |
|
|||
282 |
|
||||
283 | bool Variable::cacheIsInside(const DateTimeRange &range) const noexcept |
|
|||
284 | { |
|
|||
285 | impl->lockRead(); |
|
|||
286 | auto res = range.contains(DateTimeRange{impl->m_CacheRange.m_TStart, impl->m_CacheRange.m_TEnd}); |
|
|||
287 | impl->unlock(); |
|
|||
288 | return res; |
|
|||
289 | } |
|
|||
290 |
|
||||
291 |
|
||||
292 | QVector<DateTimeRange> Variable::provideNotInCacheRangeList(const DateTimeRange &range) const noexcept |
|
|||
293 | { |
|
|||
294 | // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange |
|
|||
295 | auto notInCache = QVector<DateTimeRange>{}; |
|
|||
296 | if (impl->m_CacheRange != INVALID_RANGE) { |
|
|||
297 |
|
||||
298 | if (!this->cacheContains(range)) { |
|
|||
299 | if (range.m_TEnd <= impl->m_CacheRange.m_TStart |
|
|||
300 | || range.m_TStart >= impl->m_CacheRange.m_TEnd) { |
|
|||
301 | notInCache << range; |
|
|||
302 | } |
|
|||
303 | else if (range.m_TStart < impl->m_CacheRange.m_TStart |
|
|||
304 | && range.m_TEnd <= impl->m_CacheRange.m_TEnd) { |
|
|||
305 | notInCache << DateTimeRange{range.m_TStart, impl->m_CacheRange.m_TStart}; |
|
|||
306 | } |
|
|||
307 | else if (range.m_TStart < impl->m_CacheRange.m_TStart |
|
|||
308 | && range.m_TEnd > impl->m_CacheRange.m_TEnd) { |
|
|||
309 | notInCache << DateTimeRange{range.m_TStart, impl->m_CacheRange.m_TStart} |
|
|||
310 | << DateTimeRange{impl->m_CacheRange.m_TEnd, range.m_TEnd}; |
|
|||
311 | } |
|
|||
312 | else if (range.m_TStart < impl->m_CacheRange.m_TEnd) { |
|
|||
313 | notInCache << DateTimeRange{impl->m_CacheRange.m_TEnd, range.m_TEnd}; |
|
|||
314 | } |
|
|||
315 | else { |
|
|||
316 | qCCritical(LOG_Variable()) << tr("Detection of unknown case.") |
|
|||
317 | << QThread::currentThread(); |
|
|||
318 | } |
|
|||
319 | } |
|
|||
320 | } |
|
|||
321 | else { |
|
|||
322 | notInCache << range; |
|
|||
323 | } |
|
|||
324 |
|
||||
325 | return notInCache; |
|
|||
326 | } |
|
|||
327 |
|
||||
328 | QVector<DateTimeRange> Variable::provideInCacheRangeList(const DateTimeRange &range) const noexcept |
|
|||
329 | { |
|
|||
330 | // This code assume that cach in contigue. Can return 0 or 1 SqpRange |
|
|||
331 |
|
||||
332 | auto inCache = QVector<DateTimeRange>{}; |
|
|||
333 |
|
||||
334 | if (impl->m_CacheRange != INVALID_RANGE) { |
|
|||
335 |
|
||||
336 | if (this->cacheIntersect(range)) { |
|
|||
337 | if (range.m_TStart <= impl->m_CacheRange.m_TStart |
|
|||
338 | && range.m_TEnd >= impl->m_CacheRange.m_TStart |
|
|||
339 | && range.m_TEnd < impl->m_CacheRange.m_TEnd) { |
|
|||
340 | inCache << DateTimeRange{impl->m_CacheRange.m_TStart, range.m_TEnd}; |
|
|||
341 | } |
|
|||
342 |
|
||||
343 | else if (range.m_TStart >= impl->m_CacheRange.m_TStart |
|
|||
344 | && range.m_TEnd <= impl->m_CacheRange.m_TEnd) { |
|
|||
345 | inCache << range; |
|
|||
346 | } |
|
|||
347 | else if (range.m_TStart > impl->m_CacheRange.m_TStart |
|
|||
348 | && range.m_TEnd > impl->m_CacheRange.m_TEnd) { |
|
|||
349 | inCache << DateTimeRange{range.m_TStart, impl->m_CacheRange.m_TEnd}; |
|
|||
350 | } |
|
|||
351 | else if (range.m_TStart <= impl->m_CacheRange.m_TStart |
|
|||
352 | && range.m_TEnd >= impl->m_CacheRange.m_TEnd) { |
|
|||
353 | inCache << impl->m_CacheRange; |
|
|||
354 | } |
|
|||
355 | else { |
|
|||
356 | qCCritical(LOG_Variable()) << tr("Detection of unknown case.") |
|
|||
357 | << QThread::currentThread(); |
|
|||
358 | } |
|
|||
359 | } |
|
|||
360 | } |
|
|||
361 |
|
||||
362 | return inCache; |
|
|||
363 | } |
|
|||
364 |
|
||||
365 |
|
||||
366 | QVector<DateTimeRange> Variable::provideNotInCacheRangeList(const DateTimeRange &oldRange, |
|
|||
367 | const DateTimeRange &nextRange) |
|
|||
368 | { |
|
|||
369 |
|
||||
370 | // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange |
|
|||
371 | auto notInCache = QVector<DateTimeRange>{}; |
|
|||
372 | if (oldRange != INVALID_RANGE) { |
|
|||
373 |
|
||||
374 | if (!oldRange.contains(nextRange)) { |
|
|||
375 | if (nextRange.m_TEnd <= oldRange.m_TStart || nextRange.m_TStart >= oldRange.m_TEnd) { |
|
|||
376 | notInCache << nextRange; |
|
|||
377 | } |
|
|||
378 | else if (nextRange.m_TStart < oldRange.m_TStart |
|
|||
379 | && nextRange.m_TEnd <= oldRange.m_TEnd) { |
|
|||
380 | notInCache << DateTimeRange{nextRange.m_TStart, oldRange.m_TStart}; |
|
|||
381 | } |
|
|||
382 | else if (nextRange.m_TStart < oldRange.m_TStart && nextRange.m_TEnd > oldRange.m_TEnd) { |
|
|||
383 | notInCache << DateTimeRange{nextRange.m_TStart, oldRange.m_TStart} |
|
|||
384 | << DateTimeRange{oldRange.m_TEnd, nextRange.m_TEnd}; |
|
|||
385 | } |
|
|||
386 | else if (nextRange.m_TStart < oldRange.m_TEnd) { |
|
|||
387 | notInCache << DateTimeRange{oldRange.m_TEnd, nextRange.m_TEnd}; |
|
|||
388 | } |
|
|||
389 | else { |
|
|||
390 | qCCritical(LOG_Variable()) << tr("Detection of unknown case.") |
|
|||
391 | << QThread::currentThread(); |
|
|||
392 | } |
|
|||
393 | } |
|
|||
394 | } |
|
|||
395 | else { |
|
|||
396 | notInCache << nextRange; |
|
|||
397 | } |
|
|||
398 |
|
||||
399 | return notInCache; |
|
|||
400 | } |
|
|||
401 |
|
||||
402 | QVector<DateTimeRange> Variable::provideInCacheRangeList(const DateTimeRange &oldRange, |
|
|||
403 | const DateTimeRange &nextRange) |
|
|||
404 | { |
|
|||
405 | // This code assume that cach is contigue. Can return 0 or 1 SqpRange |
|
|||
406 |
|
||||
407 | auto inCache = QVector<DateTimeRange>{}; |
|
|||
408 |
|
||||
409 | if (oldRange != INVALID_RANGE) { |
|
|||
410 |
|
||||
411 | if (oldRange.intersect(nextRange)) { |
|
|||
412 | if (nextRange.m_TStart <= oldRange.m_TStart && nextRange.m_TEnd >= oldRange.m_TStart |
|
|||
413 | && nextRange.m_TEnd < oldRange.m_TEnd) { |
|
|||
414 | inCache << DateTimeRange{oldRange.m_TStart, nextRange.m_TEnd}; |
|
|||
415 | } |
|
|||
416 |
|
||||
417 | else if (nextRange.m_TStart >= oldRange.m_TStart |
|
|||
418 | && nextRange.m_TEnd <= oldRange.m_TEnd) { |
|
|||
419 | inCache << nextRange; |
|
|||
420 | } |
|
|||
421 | else if (nextRange.m_TStart > oldRange.m_TStart && nextRange.m_TEnd > oldRange.m_TEnd) { |
|
|||
422 | inCache << DateTimeRange{nextRange.m_TStart, oldRange.m_TEnd}; |
|
|||
423 | } |
|
|||
424 | else if (nextRange.m_TStart <= oldRange.m_TStart |
|
|||
425 | && nextRange.m_TEnd >= oldRange.m_TEnd) { |
|
|||
426 | inCache << oldRange; |
|
|||
427 | } |
|
|||
428 | else { |
|
|||
429 | qCCritical(LOG_Variable()) << tr("Detection of unknown case.") |
|
|||
430 | << QThread::currentThread(); |
|
|||
431 | } |
|
|||
432 | } |
|
|||
433 | } |
|
|||
434 |
|
||||
435 | return inCache; |
|
|||
436 | } |
|
@@ -7,403 +7,16 | |||||
7 |
|
7 | |||
8 | #include <memory> |
|
8 | #include <memory> | |
9 |
|
9 | |||
10 | namespace { |
|
|||
11 |
|
10 | |||
12 | /// Generates a date in double |
|
|||
13 | auto date = [](int year, int month, int day, int hours, int minutes, int seconds) { |
|
|||
14 | return DateUtils::secondsSinceEpoch( |
|
|||
15 | QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC}); |
|
|||
16 | }; |
|
|||
17 |
|
||||
18 | /// Generates a series of test data for a range |
|
|||
19 | std::shared_ptr<ScalarSeries> dataSeries(const DateTimeRange &range) |
|
|||
20 | { |
|
|||
21 | auto xAxisData = std::vector<double>{}; |
|
|||
22 | auto valuesData = std::vector<double>{}; |
|
|||
23 |
|
||||
24 | auto value = 0; |
|
|||
25 | for (auto x = range.m_TStart; x <= range.m_TEnd; ++x, ++value) { |
|
|||
26 | xAxisData.push_back(x); |
|
|||
27 | valuesData.push_back(value); |
|
|||
28 | } |
|
|||
29 |
|
||||
30 | return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData), Unit{}, |
|
|||
31 | Unit{}); |
|
|||
32 | } |
|
|||
33 |
|
||||
34 | } // namespace |
|
|||
35 |
|
||||
36 | Q_DECLARE_METATYPE(std::shared_ptr<ScalarSeries>) |
|
|||
37 |
|
11 | |||
38 | class TestVariable : public QObject { |
|
12 | class TestVariable : public QObject { | |
39 | Q_OBJECT |
|
13 | Q_OBJECT | |
40 |
|
14 | |||
41 | private slots: |
|
15 | private slots: | |
42 |
void initTestCase() { QSKIP(" |
|
16 | void initTestCase() { QSKIP("Please Write me! .·´¯`(>β<)´¯`Β·. "); } | |
43 | void testClone_data(); |
|
|||
44 | void testClone(); |
|
|||
45 |
|
||||
46 | void testNotInCacheRangeList(); |
|
|||
47 | void testInCacheRangeList(); |
|
|||
48 |
|
||||
49 | void testNbPoints_data(); |
|
|||
50 | void testNbPoints(); |
|
|||
51 |
|
||||
52 | void testRealRange_data(); |
|
|||
53 | void testRealRange(); |
|
|||
54 | }; |
|
17 | }; | |
55 |
|
18 | |||
56 | void TestVariable::testClone_data() |
|
|||
57 | { |
|
|||
58 | // ////////////// // |
|
|||
59 | // Test structure // |
|
|||
60 | // ////////////// // |
|
|||
61 |
|
||||
62 | QTest::addColumn<QString>("name"); |
|
|||
63 | QTest::addColumn<QVariantHash>("metadata"); |
|
|||
64 | QTest::addColumn<DateTimeRange>("range"); |
|
|||
65 | QTest::addColumn<DateTimeRange>("cacheRange"); |
|
|||
66 | QTest::addColumn<std::shared_ptr<ScalarSeries> >("dataSeries"); |
|
|||
67 |
|
||||
68 | // ////////// // |
|
|||
69 | // Test cases // |
|
|||
70 | // ////////// // |
|
|||
71 |
|
||||
72 | auto cacheRange = DateTimeRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 13, 0, 0)}; |
|
|||
73 | QTest::newRow("clone1") << QStringLiteral("var1") |
|
|||
74 | << QVariantHash{{"data1", 1}, {"data2", "abc"}} |
|
|||
75 | << DateTimeRange{date(2017, 1, 1, 12, 30, 0), (date(2017, 1, 1, 12, 45, 0))} |
|
|||
76 | << cacheRange << dataSeries(cacheRange); |
|
|||
77 | } |
|
|||
78 |
|
||||
79 | void TestVariable::testClone() |
|
|||
80 | { |
|
|||
81 | // Creates variable |
|
|||
82 | QFETCH(QString, name); |
|
|||
83 | QFETCH(QVariantHash, metadata); |
|
|||
84 | QFETCH(DateTimeRange, range); |
|
|||
85 | QFETCH(DateTimeRange, cacheRange); |
|
|||
86 | QFETCH(std::shared_ptr<ScalarSeries>, dataSeries); |
|
|||
87 |
|
||||
88 | Variable variable{name, metadata}; |
|
|||
89 | variable.setRange(range); |
|
|||
90 | variable.setCacheRange(cacheRange); |
|
|||
91 | variable.mergeDataSeries(dataSeries); |
|
|||
92 |
|
||||
93 | // Clones variable |
|
|||
94 | auto clone = variable.clone(); |
|
|||
95 |
|
||||
96 | // Checks cloned variable's state |
|
|||
97 | QCOMPARE(clone->name(), name); |
|
|||
98 | QCOMPARE(clone->metadata(), metadata); |
|
|||
99 | QCOMPARE(clone->range(), range); |
|
|||
100 | QCOMPARE(clone->cacheRange(), cacheRange); |
|
|||
101 |
|
||||
102 | // Compares data series |
|
|||
103 | if (dataSeries != nullptr) { |
|
|||
104 | QVERIFY(clone->dataSeries() != nullptr); |
|
|||
105 | QVERIFY(std::equal(dataSeries->cbegin(), dataSeries->cend(), clone->dataSeries()->cbegin(), |
|
|||
106 | clone->dataSeries()->cend(), [](const auto &it1, const auto &it2) { |
|
|||
107 | return it1.x() == it2.x() && it1.value() == it2.value(); |
|
|||
108 | })); |
|
|||
109 | } |
|
|||
110 | else { |
|
|||
111 | QVERIFY(clone->dataSeries() == nullptr); |
|
|||
112 | } |
|
|||
113 | } |
|
|||
114 |
|
||||
115 | void TestVariable::testNotInCacheRangeList() |
|
|||
116 | { |
|
|||
117 | auto varRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}}; |
|
|||
118 | auto varRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 40, 0}}; |
|
|||
119 |
|
||||
120 | auto sqpR = DateTimeRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)}; |
|
|||
121 |
|
||||
122 | auto varCRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}}; |
|
|||
123 | auto varCRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}}; |
|
|||
124 |
|
||||
125 | auto sqpCR |
|
|||
126 | = DateTimeRange{DateUtils::secondsSinceEpoch(varCRS), DateUtils::secondsSinceEpoch(varCRE)}; |
|
|||
127 |
|
||||
128 | Variable var{"Var test"}; |
|
|||
129 | var.setRange(sqpR); |
|
|||
130 | var.setCacheRange(sqpCR); |
|
|||
131 |
|
||||
132 | // 1: [ts,te] < varTS |
|
|||
133 | auto ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}}; |
|
|||
134 | auto te = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}}; |
|
|||
135 | auto sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; |
|
|||
136 |
|
||||
137 | auto notInCach = var.provideNotInCacheRangeList(sqp); |
|
|||
138 |
|
||||
139 | QCOMPARE(notInCach.size(), 1); |
|
|||
140 |
|
||||
141 | auto notInCachRange = notInCach.first(); |
|
|||
142 |
|
||||
143 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); |
|
|||
144 | QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); |
|
|||
145 |
|
||||
146 | // 2: ts < varTS < te < varTE |
|
|||
147 | ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}}; |
|
|||
148 | te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}}; |
|
|||
149 | sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; |
|
|||
150 | notInCach = var.provideNotInCacheRangeList(sqp); |
|
|||
151 | QCOMPARE(notInCach.size(), 1); |
|
|||
152 | notInCachRange = notInCach.first(); |
|
|||
153 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); |
|
|||
154 | QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRS)); |
|
|||
155 |
|
||||
156 | // 3: varTS < ts < te < varTE |
|
|||
157 | ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}}; |
|
|||
158 | te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}}; |
|
|||
159 | sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; |
|
|||
160 | notInCach = var.provideNotInCacheRangeList(sqp); |
|
|||
161 | QCOMPARE(notInCach.size(), 0); |
|
|||
162 |
|
||||
163 |
|
||||
164 | // 4: varTS < ts < varTE < te |
|
|||
165 | ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}}; |
|
|||
166 | te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}}; |
|
|||
167 | sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; |
|
|||
168 | notInCach = var.provideNotInCacheRangeList(sqp); |
|
|||
169 | QCOMPARE(notInCach.size(), 1); |
|
|||
170 | notInCachRange = notInCach.first(); |
|
|||
171 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRE)); |
|
|||
172 | QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); |
|
|||
173 |
|
||||
174 | // 5: varTS < varTE < ts < te |
|
|||
175 | ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 20, 0}}; |
|
|||
176 | te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}}; |
|
|||
177 | sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; |
|
|||
178 | notInCach = var.provideNotInCacheRangeList(sqp); |
|
|||
179 | QCOMPARE(notInCach.size(), 1); |
|
|||
180 | notInCachRange = notInCach.first(); |
|
|||
181 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); |
|
|||
182 | QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); |
|
|||
183 |
|
||||
184 | // 6: ts <varTS < varTE < te |
|
|||
185 | ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}}; |
|
|||
186 | te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}}; |
|
|||
187 | sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; |
|
|||
188 | notInCach = var.provideNotInCacheRangeList(sqp); |
|
|||
189 | QCOMPARE(notInCach.size(), 2); |
|
|||
190 | notInCachRange = notInCach.first(); |
|
|||
191 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); |
|
|||
192 | QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRS)); |
|
|||
193 | notInCachRange = notInCach[1]; |
|
|||
194 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRE)); |
|
|||
195 | QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); |
|
|||
196 | } |
|
|||
197 |
|
||||
198 |
|
||||
199 | void TestVariable::testInCacheRangeList() |
|
|||
200 | { |
|
|||
201 | auto varRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}}; |
|
|||
202 | auto varRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 40, 0}}; |
|
|||
203 |
|
||||
204 | auto sqpR = DateTimeRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)}; |
|
|||
205 |
|
||||
206 | auto varCRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}}; |
|
|||
207 | auto varCRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}}; |
|
|||
208 | auto sqpCR |
|
|||
209 | = DateTimeRange{DateUtils::secondsSinceEpoch(varCRS), DateUtils::secondsSinceEpoch(varCRE)}; |
|
|||
210 |
|
||||
211 | Variable var{"Var test"}; |
|
|||
212 | var.setRange(sqpR); |
|
|||
213 | var.setCacheRange(sqpCR); |
|
|||
214 |
|
||||
215 | // 1: [ts,te] < varTS |
|
|||
216 | auto ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}}; |
|
|||
217 | auto te = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}}; |
|
|||
218 | auto sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; |
|
|||
219 |
|
||||
220 | auto notInCach = var.provideInCacheRangeList(sqp); |
|
|||
221 |
|
||||
222 | QCOMPARE(notInCach.size(), 0); |
|
|||
223 |
|
||||
224 | // 2: ts < varTS < te < varTE |
|
|||
225 | ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}}; |
|
|||
226 | te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}}; |
|
|||
227 | sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; |
|
|||
228 | notInCach = var.provideInCacheRangeList(sqp); |
|
|||
229 | QCOMPARE(notInCach.size(), 1); |
|
|||
230 | auto notInCachRange = notInCach.first(); |
|
|||
231 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRS)); |
|
|||
232 | QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); |
|
|||
233 |
|
||||
234 | // 3: varTS < ts < te < varTE |
|
|||
235 | ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}}; |
|
|||
236 | te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}}; |
|
|||
237 | sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; |
|
|||
238 | notInCach = var.provideInCacheRangeList(sqp); |
|
|||
239 | QCOMPARE(notInCach.size(), 1); |
|
|||
240 | notInCachRange = notInCach.first(); |
|
|||
241 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); |
|
|||
242 | QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(te)); |
|
|||
243 |
|
||||
244 | // 4: varTS < ts < varTE < te |
|
|||
245 | ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 20, 0}}; |
|
|||
246 | te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}}; |
|
|||
247 | sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; |
|
|||
248 | notInCach = var.provideInCacheRangeList(sqp); |
|
|||
249 | QCOMPARE(notInCach.size(), 1); |
|
|||
250 | notInCachRange = notInCach.first(); |
|
|||
251 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(ts)); |
|
|||
252 | QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRE)); |
|
|||
253 |
|
||||
254 | // 5: varTS < varTE < ts < te |
|
|||
255 | ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 20, 0}}; |
|
|||
256 | te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}}; |
|
|||
257 | sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; |
|
|||
258 | notInCach = var.provideInCacheRangeList(sqp); |
|
|||
259 | QCOMPARE(notInCach.size(), 0); |
|
|||
260 |
|
||||
261 | // 6: ts <varTS < varTE < te |
|
|||
262 | ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}}; |
|
|||
263 | te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}}; |
|
|||
264 | sqp = DateTimeRange{DateUtils::secondsSinceEpoch(ts), DateUtils::secondsSinceEpoch(te)}; |
|
|||
265 | notInCach = var.provideInCacheRangeList(sqp); |
|
|||
266 | QCOMPARE(notInCach.size(), 1); |
|
|||
267 | notInCachRange = notInCach.first(); |
|
|||
268 | QCOMPARE(notInCachRange.m_TStart, DateUtils::secondsSinceEpoch(varCRS)); |
|
|||
269 | QCOMPARE(notInCachRange.m_TEnd, DateUtils::secondsSinceEpoch(varCRE)); |
|
|||
270 | } |
|
|||
271 |
|
||||
272 | namespace { |
|
|||
273 |
|
||||
274 | /// Struct used to represent an operation for @sa TestVariable::testNbPoints() |
|
|||
275 | struct NbPointsOperation { |
|
|||
276 | DateTimeRange m_CacheRange; /// Range to set for the variable |
|
|||
277 | std::shared_ptr<ScalarSeries> m_DataSeries; /// Series to merge in the variable |
|
|||
278 | int m_ExpectedNbPoints; /// Number of points in the variable expected after operation |
|
|||
279 | }; |
|
|||
280 |
|
||||
281 | using NbPointsOperations = std::vector<NbPointsOperation>; |
|
|||
282 |
|
||||
283 | } // namespace |
|
|||
284 |
|
||||
285 | Q_DECLARE_METATYPE(NbPointsOperations) |
|
|||
286 |
|
||||
287 | void TestVariable::testNbPoints_data() |
|
|||
288 | { |
|
|||
289 | // ////////////// // |
|
|||
290 | // Test structure // |
|
|||
291 | // ////////////// // |
|
|||
292 |
|
||||
293 | QTest::addColumn<NbPointsOperations>("operations"); |
|
|||
294 |
|
||||
295 | // ////////// // |
|
|||
296 | // Test cases // |
|
|||
297 | // ////////// // |
|
|||
298 | NbPointsOperations operations{}; |
|
|||
299 |
|
||||
300 | // Sets cache range (expected nb points = values data) |
|
|||
301 | auto cacheRange = DateTimeRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 12, 0, 9)}; |
|
|||
302 | operations.push_back({cacheRange, dataSeries(cacheRange), 10}); |
|
|||
303 |
|
||||
304 | // Doubles cache but don't add data series (expected nb points don't change) |
|
|||
305 | cacheRange = DateTimeRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 12, 0, 19)}; |
|
|||
306 | operations.push_back({cacheRange, dataSeries(INVALID_RANGE), 10}); |
|
|||
307 |
|
||||
308 | // Doubles cache and data series (expected nb points change) |
|
|||
309 | cacheRange = DateTimeRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 12, 0, 19)}; |
|
|||
310 | operations.push_back({cacheRange, dataSeries(cacheRange), 20}); |
|
|||
311 |
|
||||
312 | // Decreases cache (expected nb points decreases as the series is purged) |
|
|||
313 | cacheRange = DateTimeRange{date(2017, 1, 1, 12, 0, 5), date(2017, 1, 1, 12, 0, 9)}; |
|
|||
314 | operations.push_back({cacheRange, dataSeries(INVALID_RANGE), 5}); |
|
|||
315 |
|
||||
316 | QTest::newRow("nbPoints1") << operations; |
|
|||
317 | } |
|
|||
318 |
|
||||
319 | void TestVariable::testNbPoints() |
|
|||
320 | { |
|
|||
321 | // Creates variable |
|
|||
322 | Variable variable{"var"}; |
|
|||
323 | QCOMPARE(variable.nbPoints(), 0); |
|
|||
324 |
|
||||
325 | QFETCH(NbPointsOperations, operations); |
|
|||
326 | for (const auto &operation : operations) { |
|
|||
327 | // Sets cache range and merge data series |
|
|||
328 | variable.setCacheRange(operation.m_CacheRange); |
|
|||
329 | if (operation.m_DataSeries != nullptr) { |
|
|||
330 | variable.mergeDataSeries(operation.m_DataSeries); |
|
|||
331 | } |
|
|||
332 |
|
||||
333 | // Checks nb points |
|
|||
334 | QCOMPARE(variable.nbPoints(), operation.m_ExpectedNbPoints); |
|
|||
335 | } |
|
|||
336 | } |
|
|||
337 |
|
||||
338 | namespace { |
|
|||
339 |
|
||||
340 | /// Struct used to represent a range operation on a variable |
|
|||
341 | /// @sa TestVariable::testRealRange() |
|
|||
342 | struct RangeOperation { |
|
|||
343 | DateTimeRange m_CacheRange; /// Range to set for the variable |
|
|||
344 | std::shared_ptr<ScalarSeries> m_DataSeries; /// Series to merge in the variable |
|
|||
345 | DateTimeRange m_ExpectedRealRange; /// Real Range expected after operation on the variable |
|
|||
346 | }; |
|
|||
347 |
|
||||
348 | using RangeOperations = std::vector<RangeOperation>; |
|
|||
349 |
|
||||
350 | } // namespace |
|
|||
351 |
|
||||
352 | Q_DECLARE_METATYPE(RangeOperations) |
|
|||
353 |
|
||||
354 | void TestVariable::testRealRange_data() |
|
|||
355 | { |
|
|||
356 | // ////////////// // |
|
|||
357 | // Test structure // |
|
|||
358 | // ////////////// // |
|
|||
359 |
|
||||
360 | QTest::addColumn<RangeOperations>("operations"); |
|
|||
361 |
|
||||
362 | // ////////// // |
|
|||
363 | // Test cases // |
|
|||
364 | // ////////// // |
|
|||
365 | RangeOperations operations{}; |
|
|||
366 |
|
||||
367 | // Inits cache range and data series (expected real range = cache range) |
|
|||
368 | auto cacheRange = DateTimeRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 13, 0, 0)}; |
|
|||
369 | operations.push_back({cacheRange, dataSeries(cacheRange), cacheRange}); |
|
|||
370 |
|
||||
371 | // Changes cache range and updates data series (expected real range = cache range) |
|
|||
372 | cacheRange = DateTimeRange{date(2017, 1, 1, 14, 0, 0), date(2017, 1, 1, 15, 0, 0)}; |
|
|||
373 | operations.push_back({cacheRange, dataSeries(cacheRange), cacheRange}); |
|
|||
374 |
|
||||
375 | // Changes cache range and update data series but with a lower range (expected real range = |
|
|||
376 | // data series range) |
|
|||
377 | cacheRange = DateTimeRange{date(2017, 1, 1, 12, 0, 0), date(2017, 1, 1, 16, 0, 0)}; |
|
|||
378 | auto dataSeriesRange = DateTimeRange{date(2017, 1, 1, 14, 0, 0), date(2017, 1, 1, 15, 0, 0)}; |
|
|||
379 | operations.push_back({cacheRange, dataSeries(dataSeriesRange), dataSeriesRange}); |
|
|||
380 |
|
||||
381 | // Changes cache range but DON'T update data series (expected real range = cache range |
|
|||
382 | // before operation) |
|
|||
383 | cacheRange = DateTimeRange{date(2017, 1, 1, 10, 0, 0), date(2017, 1, 1, 17, 0, 0)}; |
|
|||
384 | operations.push_back({cacheRange, nullptr, dataSeriesRange}); |
|
|||
385 |
|
||||
386 | QTest::newRow("realRange1") << operations; |
|
|||
387 | } |
|
|||
388 |
|
||||
389 | void TestVariable::testRealRange() |
|
|||
390 | { |
|
|||
391 | // Creates variable (real range is invalid) |
|
|||
392 | Variable variable{"var"}; |
|
|||
393 | QCOMPARE(variable.realRange(), INVALID_RANGE); |
|
|||
394 |
|
||||
395 | QFETCH(RangeOperations, operations); |
|
|||
396 | for (const auto &operation : operations) { |
|
|||
397 | // Sets cache range and merge data series |
|
|||
398 | variable.setCacheRange(operation.m_CacheRange); |
|
|||
399 | if (operation.m_DataSeries != nullptr) { |
|
|||
400 | variable.mergeDataSeries(operation.m_DataSeries); |
|
|||
401 | } |
|
|||
402 |
|
19 | |||
403 | // Checks real range |
|
|||
404 | QCOMPARE(variable.realRange(), operation.m_ExpectedRealRange); |
|
|||
405 | } |
|
|||
406 | } |
|
|||
407 |
|
20 | |||
408 |
|
21 | |||
409 | QTEST_MAIN(TestVariable) |
|
22 | QTEST_MAIN(TestVariable) |
General Comments 0
You need to be logged in to leave comments.
Login now