##// END OF EJS Templates
VariableController2 tests refactoring...
jeandet -
r3:7c9c9e90e0b8
parent child
Show More
@@ -1,102 +1,102
1 1 #ifndef SCIQLOP_VARIABLE_H
2 2 #define SCIQLOP_VARIABLE_H
3 3
4 4 #include "CoreGlobal.h"
5 5
6 6 #include <Data/DataSeriesIterator.h>
7 7 #include <Data/DataSeriesType.h>
8 8 #include <Data/DateTimeRange.h>
9 9
10 10 #include <QLoggingCategory>
11 11 #include <QObject>
12 12 #include <QUuid>
13 13
14 14 #include <Common/deprecate.h>
15 15 #include <Common/MetaTypes.h>
16 16 #include <Common/spimpl.h>
17 17
18 18 Q_DECLARE_LOGGING_CATEGORY(LOG_Variable)
19 19
20 20 class IDataSeries;
21 21 class QString;
22 22
23 23 /**
24 24 * @brief The Variable class represents a variable in SciQlop.
25 25 */
26 26 class SCIQLOP_CORE_EXPORT Variable : public QObject {
27 27
28 28 Q_OBJECT
29 29
30 30 public:
31 31 explicit Variable(const QString &name, const QVariantHash &metadata = {});
32 32
33 33 /// Copy ctor
34 34 explicit Variable(const Variable &other);
35 35
36 36 std::shared_ptr<Variable> clone() const;
37 37
38 38 QString name() const noexcept;
39 39 void setName(const QString &name) noexcept;
40 40 DateTimeRange range() const noexcept;
41 41 void setRange(const DateTimeRange &range) noexcept;
42 42 DateTimeRange cacheRange() const noexcept;
43 43 void setCacheRange(const DateTimeRange &cacheRange) noexcept;
44 44
45 45 /// @return the number of points hold by the variable. The number of points is updated each time
46 46 /// the data series changes
47 int nbPoints() const noexcept;
47 unsigned int nbPoints() const noexcept;
48 48
49 49 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
50 50 /// series between the range of the variable. The real range is updated each time the variable
51 51 /// range or the data series changed
52 52 /// @return the real range, invalid range if the data series is null or empty
53 53 /// @sa setDataSeries()
54 54 /// @sa setRange()
55 55 DateTimeRange realRange() const noexcept;
56 56
57 57 /// @return the data of the variable, nullptr if there is no data
58 58 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
59 59
60 60 /// @return the type of data that the variable holds
61 61 DataSeriesType type() const noexcept;
62 62
63 63 QVariantHash metadata() const noexcept;
64 64
65 65 bool contains(const DateTimeRange &range) const noexcept;
66 66 bool intersect(const DateTimeRange &range) const noexcept;
67 67 bool isInside(const DateTimeRange &range) const noexcept;
68 68
69 69 bool cacheContains(const DateTimeRange &range) const noexcept;
70 70 bool cacheIntersect(const DateTimeRange &range) const noexcept;
71 71 bool cacheIsInside(const DateTimeRange &range) const noexcept;
72 72
73 73 QVector<DateTimeRange> provideNotInCacheRangeList(const DateTimeRange &range) const noexcept;
74 74 QVector<DateTimeRange> provideInCacheRangeList(const DateTimeRange &range) const noexcept;
75 75 DEPRECATE(
76 76 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
77 77 )
78 78 void mergeDataSeries(IDataSeries* dataSeries) noexcept;
79 79
80 80 static QVector<DateTimeRange> provideNotInCacheRangeList(const DateTimeRange &oldRange,
81 81 const DateTimeRange &nextRange);
82 82
83 83 static QVector<DateTimeRange> provideInCacheRangeList(const DateTimeRange &oldRange,
84 84 const DateTimeRange &nextRange);
85 85
86 86 QUuid ID(){return _uuid;}
87 87 signals:
88 88 void updated();
89 89 /// Signal emitted when when the data series of the variable is loaded for the first time
90 90 void dataInitialized();
91 91
92 92 private:
93 93 class VariablePrivate;
94 94 spimpl::unique_impl_ptr<VariablePrivate> impl;
95 95 QUuid _uuid;
96 96 };
97 97
98 98 // Required for using shared_ptr in signals/slots
99 99 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
100 100 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
101 101
102 102 #endif // SCIQLOP_VARIABLE_H
@@ -1,461 +1,461
1 1 #include "Variable/Variable.h"
2 2
3 3 #include <Data/IDataSeries.h>
4 4 #include <Data/DateTimeRange.h>
5 5
6 6 #include <QMutex>
7 7 #include <QReadWriteLock>
8 8 #include <QThread>
9 9 #include <Common/debug.h>
10 10
11 11 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
12 12
13 13 namespace {
14 14
15 15 /**
16 16 * Searches in metadata for a value that can be converted to DataSeriesType
17 17 * @param metadata the metadata where to search
18 18 * @return the value converted to a DataSeriesType if it was found, UNKNOWN type otherwise
19 19 * @sa DataSeriesType
20 20 */
21 21 DataSeriesType findDataSeriesType(const QVariantHash &metadata)
22 22 {
23 23 auto dataSeriesType = DataSeriesType::UNKNOWN;
24 24
25 25 // Go through the metadata and stop at the first value that could be converted to DataSeriesType
26 26 for (auto it = metadata.cbegin(), end = metadata.cend();
27 27 it != end && dataSeriesType == DataSeriesType::UNKNOWN; ++it) {
28 28 dataSeriesType = DataSeriesTypeUtils::fromString(it.value().toString());
29 29 }
30 30
31 31 return dataSeriesType;
32 32 }
33 33
34 34 } // namespace
35 35
36 36 struct Variable::VariablePrivate {
37 37 explicit VariablePrivate(const QString &name, const QVariantHash &metadata)
38 38 : m_Name{name},
39 39 m_Range{INVALID_RANGE},
40 40 m_CacheRange{INVALID_RANGE},
41 41 m_Metadata{metadata},
42 42 m_DataSeries{nullptr},
43 43 m_RealRange{INVALID_RANGE},
44 44 m_NbPoints{0},
45 45 m_Type{findDataSeriesType(m_Metadata)}
46 46 {
47 47 }
48 48
49 49 VariablePrivate(const VariablePrivate &other)
50 50 : m_Name{other.m_Name},
51 51 m_Range{other.m_Range},
52 52 m_CacheRange{other.m_CacheRange},
53 53 m_Metadata{other.m_Metadata},
54 54 m_DataSeries{other.m_DataSeries != nullptr ? other.m_DataSeries->clone() : nullptr},
55 55 m_RealRange{other.m_RealRange},
56 56 m_NbPoints{other.m_NbPoints},
57 57 m_Type{findDataSeriesType(m_Metadata)}
58 58 {
59 59 }
60 60
61 61 void lockRead() { m_Lock.lockForRead(); }
62 62 void lockWrite() { m_Lock.lockForWrite(); }
63 63 void unlock() { m_Lock.unlock(); }
64 64
65 65 void purgeDataSeries()
66 66 {
67 67 if (m_DataSeries) {
68 68 m_DataSeries->purge(m_CacheRange.m_TStart, m_CacheRange.m_TEnd);
69 69 }
70 70 updateRealRange();
71 71 updateNbPoints();
72 72 }
73 73
74 74 void updateNbPoints() { m_NbPoints = m_DataSeries ? m_DataSeries->nbPoints() : 0; }
75 75
76 76 /// Updates real range according to current variable range and data series
77 77 void updateRealRange()
78 78 {
79 79 if (m_DataSeries) {
80 80 m_DataSeries->lockRead();
81 81 auto end = m_DataSeries->cend();
82 82 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
83 83 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
84 84
85 85 m_RealRange
86 86 = (minXAxisIt != end && maxXAxisIt != end && minXAxisIt->x() <= maxXAxisIt->x())
87 87 ? DateTimeRange{minXAxisIt->x(), maxXAxisIt->x()}
88 88 : INVALID_RANGE;
89 89 m_DataSeries->unlock();
90 90 }
91 91 else {
92 92 m_RealRange = INVALID_RANGE;
93 93 }
94 94 }
95 95
96 96 QString m_Name;
97 97
98 98 DateTimeRange m_Range;
99 99 DateTimeRange m_CacheRange;
100 100 QVariantHash m_Metadata;
101 101 std::shared_ptr<IDataSeries> m_DataSeries;
102 102 DateTimeRange m_RealRange;
103 int m_NbPoints;
103 unsigned int m_NbPoints;
104 104 DataSeriesType m_Type;
105 105
106 106 QReadWriteLock m_Lock;
107 107 };
108 108
109 109 Variable::Variable(const QString &name, const QVariantHash &metadata)
110 110 : impl{spimpl::make_unique_impl<VariablePrivate>(name, metadata)},
111 111 _uuid{QUuid::createUuid()}
112 112 {
113 113 }
114 114
115 115 Variable::Variable(const Variable &other)
116 116 : impl{spimpl::make_unique_impl<VariablePrivate>(*other.impl)},
117 117 _uuid{QUuid::createUuid()} //is a clone but must have a != uuid
118 118 {
119 119 }
120 120
121 121 std::shared_ptr<Variable> Variable::clone() const
122 122 {
123 123 return std::make_shared<Variable>(*this);
124 124 }
125 125
126 126 QString Variable::name() const noexcept
127 127 {
128 128 impl->lockRead();
129 129 auto name = impl->m_Name;
130 130 impl->unlock();
131 131 return name;
132 132 }
133 133
134 134 void Variable::setName(const QString &name) noexcept
135 135 {
136 136 impl->lockWrite();
137 137 impl->m_Name = name;
138 138 impl->unlock();
139 139 }
140 140
141 141 DateTimeRange Variable::range() const noexcept
142 142 {
143 143 impl->lockRead();
144 144 auto range = impl->m_Range;
145 145 impl->unlock();
146 146 return range;
147 147 }
148 148
149 149 void Variable::setRange(const DateTimeRange &range) noexcept
150 150 {
151 151 impl->lockWrite();
152 152 impl->m_Range = range;
153 153 impl->updateRealRange();
154 154 impl->unlock();
155 155 }
156 156
157 157 DateTimeRange Variable::cacheRange() const noexcept
158 158 {
159 159 impl->lockRead();
160 160 auto cacheRange = impl->m_CacheRange;
161 161 impl->unlock();
162 162 return cacheRange;
163 163 }
164 164
165 165 void Variable::setCacheRange(const DateTimeRange &cacheRange) noexcept
166 166 {
167 167 impl->lockWrite();
168 168 if (cacheRange != impl->m_CacheRange) {
169 169 impl->m_CacheRange = cacheRange;
170 170 }
171 171 impl->unlock();
172 172 }
173 173
174 int Variable::nbPoints() const noexcept
174 unsigned int Variable::nbPoints() const noexcept
175 175 {
176 176 return impl->m_NbPoints;
177 177 }
178 178
179 179 DateTimeRange Variable::realRange() const noexcept
180 180 {
181 181 return impl->m_RealRange;
182 182 }
183 183
184 184 void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
185 185 {
186 186 qCDebug(LOG_Variable()) << "TORM Variable::mergeDataSeries"
187 187 << QThread::currentThread()->objectName();
188 188 if (!dataSeries) {
189 189 /// @todo ALX : log
190 190 return;
191 191 }
192 192
193 193 auto dataInit = false;
194 194
195 195 // Add or merge the data
196 196 impl->lockWrite();
197 197 if (!impl->m_DataSeries) {
198 198 impl->m_DataSeries = dataSeries->clone();
199 199 dataInit = true;
200 200 }
201 201 else {
202 202 impl->m_DataSeries->merge(dataSeries.get());
203 203 }
204 204 impl->purgeDataSeries();
205 205 impl->unlock();
206 206
207 207 if (dataInit) {
208 208 emit dataInitialized();
209 209 }
210 210 }
211 211
212 212 void Variable::mergeDataSeries(IDataSeries *dataSeries) noexcept
213 213 {
214 214 if (dataSeries==nullptr) {
215 215 SCIQLOP_ERROR("Given IDataSeries is nullptr");
216 216 return;
217 217 }
218 218
219 219 auto dataInit = false;
220 220 // @TODO move to impl to Pimpl this is what it stands for...
221 221 // Add or merge the data
222 222 impl->lockWrite();
223 223 if (!impl->m_DataSeries) {
224 224 //@TODO find a better way
225 225 impl->m_DataSeries = dataSeries->clone();
226 226 dataInit = true;
227 227 delete dataSeries;
228 228 }
229 229 else {
230 230 impl->m_DataSeries->merge(dataSeries);
231 231 }
232 232 impl->purgeDataSeries();
233 233 impl->unlock();
234 234
235 235 if (dataInit) {
236 236 emit dataInitialized();
237 237 }
238 238 }
239 239
240 240
241 241 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
242 242 {
243 243 impl->lockRead();
244 244 auto dataSeries = impl->m_DataSeries;
245 245 impl->unlock();
246 246
247 247 return dataSeries;
248 248 }
249 249
250 250 DataSeriesType Variable::type() const noexcept
251 251 {
252 252 impl->lockRead();
253 253 auto type = impl->m_Type;
254 254 impl->unlock();
255 255
256 256 return type;
257 257 }
258 258
259 259 QVariantHash Variable::metadata() const noexcept
260 260 {
261 261 impl->lockRead();
262 262 auto metadata = impl->m_Metadata;
263 263 impl->unlock();
264 264 return metadata;
265 265 }
266 266
267 267 bool Variable::contains(const DateTimeRange &range) const noexcept
268 268 {
269 269 impl->lockRead();
270 270 auto res = impl->m_Range.contains(range);
271 271 impl->unlock();
272 272 return res;
273 273 }
274 274
275 275 bool Variable::intersect(const DateTimeRange &range) const noexcept
276 276 {
277 277
278 278 impl->lockRead();
279 279 auto res = impl->m_Range.intersect(range);
280 280 impl->unlock();
281 281 return res;
282 282 }
283 283
284 284 bool Variable::isInside(const DateTimeRange &range) const noexcept
285 285 {
286 286 impl->lockRead();
287 287 auto res = range.contains(DateTimeRange{impl->m_Range.m_TStart, impl->m_Range.m_TEnd});
288 288 impl->unlock();
289 289 return res;
290 290 }
291 291
292 292 bool Variable::cacheContains(const DateTimeRange &range) const noexcept
293 293 {
294 294 impl->lockRead();
295 295 auto res = impl->m_CacheRange.contains(range);
296 296 impl->unlock();
297 297 return res;
298 298 }
299 299
300 300 bool Variable::cacheIntersect(const DateTimeRange &range) const noexcept
301 301 {
302 302 impl->lockRead();
303 303 auto res = impl->m_CacheRange.intersect(range);
304 304 impl->unlock();
305 305 return res;
306 306 }
307 307
308 308 bool Variable::cacheIsInside(const DateTimeRange &range) const noexcept
309 309 {
310 310 impl->lockRead();
311 311 auto res = range.contains(DateTimeRange{impl->m_CacheRange.m_TStart, impl->m_CacheRange.m_TEnd});
312 312 impl->unlock();
313 313 return res;
314 314 }
315 315
316 316
317 317 QVector<DateTimeRange> Variable::provideNotInCacheRangeList(const DateTimeRange &range) const noexcept
318 318 {
319 319 // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange
320 320 auto notInCache = QVector<DateTimeRange>{};
321 321 if (impl->m_CacheRange != INVALID_RANGE) {
322 322
323 323 if (!this->cacheContains(range)) {
324 324 if (range.m_TEnd <= impl->m_CacheRange.m_TStart
325 325 || range.m_TStart >= impl->m_CacheRange.m_TEnd) {
326 326 notInCache << range;
327 327 }
328 328 else if (range.m_TStart < impl->m_CacheRange.m_TStart
329 329 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
330 330 notInCache << DateTimeRange{range.m_TStart, impl->m_CacheRange.m_TStart};
331 331 }
332 332 else if (range.m_TStart < impl->m_CacheRange.m_TStart
333 333 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
334 334 notInCache << DateTimeRange{range.m_TStart, impl->m_CacheRange.m_TStart}
335 335 << DateTimeRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
336 336 }
337 337 else if (range.m_TStart < impl->m_CacheRange.m_TEnd) {
338 338 notInCache << DateTimeRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
339 339 }
340 340 else {
341 341 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
342 342 << QThread::currentThread();
343 343 }
344 344 }
345 345 }
346 346 else {
347 347 notInCache << range;
348 348 }
349 349
350 350 return notInCache;
351 351 }
352 352
353 353 QVector<DateTimeRange> Variable::provideInCacheRangeList(const DateTimeRange &range) const noexcept
354 354 {
355 355 // This code assume that cach in contigue. Can return 0 or 1 SqpRange
356 356
357 357 auto inCache = QVector<DateTimeRange>{};
358 358
359 359 if (impl->m_CacheRange != INVALID_RANGE) {
360 360
361 361 if (this->cacheIntersect(range)) {
362 362 if (range.m_TStart <= impl->m_CacheRange.m_TStart
363 363 && range.m_TEnd >= impl->m_CacheRange.m_TStart
364 364 && range.m_TEnd < impl->m_CacheRange.m_TEnd) {
365 365 inCache << DateTimeRange{impl->m_CacheRange.m_TStart, range.m_TEnd};
366 366 }
367 367
368 368 else if (range.m_TStart >= impl->m_CacheRange.m_TStart
369 369 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
370 370 inCache << range;
371 371 }
372 372 else if (range.m_TStart > impl->m_CacheRange.m_TStart
373 373 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
374 374 inCache << DateTimeRange{range.m_TStart, impl->m_CacheRange.m_TEnd};
375 375 }
376 376 else if (range.m_TStart <= impl->m_CacheRange.m_TStart
377 377 && range.m_TEnd >= impl->m_CacheRange.m_TEnd) {
378 378 inCache << impl->m_CacheRange;
379 379 }
380 380 else {
381 381 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
382 382 << QThread::currentThread();
383 383 }
384 384 }
385 385 }
386 386
387 387 return inCache;
388 388 }
389 389
390 390
391 391 QVector<DateTimeRange> Variable::provideNotInCacheRangeList(const DateTimeRange &oldRange,
392 392 const DateTimeRange &nextRange)
393 393 {
394 394
395 395 // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange
396 396 auto notInCache = QVector<DateTimeRange>{};
397 397 if (oldRange != INVALID_RANGE) {
398 398
399 399 if (!oldRange.contains(nextRange)) {
400 400 if (nextRange.m_TEnd <= oldRange.m_TStart || nextRange.m_TStart >= oldRange.m_TEnd) {
401 401 notInCache << nextRange;
402 402 }
403 403 else if (nextRange.m_TStart < oldRange.m_TStart
404 404 && nextRange.m_TEnd <= oldRange.m_TEnd) {
405 405 notInCache << DateTimeRange{nextRange.m_TStart, oldRange.m_TStart};
406 406 }
407 407 else if (nextRange.m_TStart < oldRange.m_TStart && nextRange.m_TEnd > oldRange.m_TEnd) {
408 408 notInCache << DateTimeRange{nextRange.m_TStart, oldRange.m_TStart}
409 409 << DateTimeRange{oldRange.m_TEnd, nextRange.m_TEnd};
410 410 }
411 411 else if (nextRange.m_TStart < oldRange.m_TEnd) {
412 412 notInCache << DateTimeRange{oldRange.m_TEnd, nextRange.m_TEnd};
413 413 }
414 414 else {
415 415 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
416 416 << QThread::currentThread();
417 417 }
418 418 }
419 419 }
420 420 else {
421 421 notInCache << nextRange;
422 422 }
423 423
424 424 return notInCache;
425 425 }
426 426
427 427 QVector<DateTimeRange> Variable::provideInCacheRangeList(const DateTimeRange &oldRange,
428 428 const DateTimeRange &nextRange)
429 429 {
430 430 // This code assume that cach is contigue. Can return 0 or 1 SqpRange
431 431
432 432 auto inCache = QVector<DateTimeRange>{};
433 433
434 434 if (oldRange != INVALID_RANGE) {
435 435
436 436 if (oldRange.intersect(nextRange)) {
437 437 if (nextRange.m_TStart <= oldRange.m_TStart && nextRange.m_TEnd >= oldRange.m_TStart
438 438 && nextRange.m_TEnd < oldRange.m_TEnd) {
439 439 inCache << DateTimeRange{oldRange.m_TStart, nextRange.m_TEnd};
440 440 }
441 441
442 442 else if (nextRange.m_TStart >= oldRange.m_TStart
443 443 && nextRange.m_TEnd <= oldRange.m_TEnd) {
444 444 inCache << nextRange;
445 445 }
446 446 else if (nextRange.m_TStart > oldRange.m_TStart && nextRange.m_TEnd > oldRange.m_TEnd) {
447 447 inCache << DateTimeRange{nextRange.m_TStart, oldRange.m_TEnd};
448 448 }
449 449 else if (nextRange.m_TStart <= oldRange.m_TStart
450 450 && nextRange.m_TEnd >= oldRange.m_TEnd) {
451 451 inCache << oldRange;
452 452 }
453 453 else {
454 454 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
455 455 << QThread::currentThread();
456 456 }
457 457 }
458 458 }
459 459
460 460 return inCache;
461 461 }
@@ -1,108 +1,139
1 1 #include <cmath>
2 #include <algorithm>
3 #include <numeric>
2 4 #include <QtTest>
3 5 #include <QObject>
4 6 #include <Variable/VariableController2.h>
5 7 #include <Data/DateTimeRange.h>
6 8 #include <Data/IDataProvider.h>
7 9 #include <Data/ScalarSeries.h>
8 10 #include <Data/DataProviderParameters.h>
9 11 #include <Common/containers.h>
10 12
11 class FakeProvider: public IDataProvider
13 template<int slope>
14 class SimpleRange: public IDataProvider
12 15 {
13 16 public:
14 FakeProvider() = default;
17 SimpleRange() = default;
15 18
16 std::shared_ptr<IDataProvider> clone() const override{ return std::make_shared<FakeProvider>(); }
19 std::shared_ptr<IDataProvider> clone() const override{ return std::make_shared<SimpleRange>(); }
17 20
18 21 IDataSeries* getData(const DataProviderParameters &parameters) override
19 22 {
20 23 auto tstart = parameters.m_Times[0].m_TStart;
21 24 auto tend = parameters.m_Times[0].m_TEnd;
22 25 std::vector<double> x;
23 26 std::vector<double> y;
24 27 for(auto i = tstart;i<tend;i+=1.) //1 seconde data resolution
25 28 {
26 29 x.push_back(i);
27 y.push_back(i);
30 y.push_back(i*slope);
28 31 }
29 32 auto serie = new ScalarSeries(std::move(x),std::move(y),Unit("Secondes",true),Unit("Volts",false));
30 33 return serie;
31 34 }
32 35
33 36
34 37
35 38 void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters) override
36 39 {
37 40 Q_UNUSED(acqIdentifier)
38 41 Q_UNUSED(parameters)
39 42 }
40 43
41 44 void requestDataAborting(QUuid acqIdentifier) override
42 45 {
43 46 Q_UNUSED(acqIdentifier)
44 47 }
45 48
46 49 };
47 50
51
52 template <class T>
53 auto sumdiff(T begin, T end)
54 {
55 std::vector<double> diff_vect(end-begin-1);
56 auto diff = [](auto next,auto item)
57 {
58 return next.value() - item.value();
59 };
60 std::transform (begin+1, end, begin, diff_vect.begin(),diff);
61 return std::accumulate(diff_vect.cbegin(), diff_vect.cend(), 0);
62 }
63
64 template <int slope=1>
65 struct RangeType
66 {
67 static void check_properties(std::shared_ptr<Variable> v, DateTimeRange r)
68 {
69 auto s = sumdiff(v->dataSeries()->cbegin(), v->dataSeries()->cend()) / slope;
70 QCOMPARE(v->nbPoints(), int(s)+1);
71 QCOMPARE(r.m_TStart, v->dataSeries()->begin()->value()/slope);
72 }
73 };
74
75 template <class T>
76 void check_variable_state(std::shared_ptr<Variable> v, DateTimeRange r)
77 {
78 QCOMPARE(v->nbPoints(), int(r.delta()));
79 T::check_properties(v,r);
80 }
81
48 82 class TestVariableController2 : public QObject
49 83 {
50 84 Q_OBJECT
51 85 public:
52 86 explicit TestVariableController2(QObject *parent = nullptr) : QObject(parent){}
53 87 signals:
54 88
55 89 private slots:
56 90 void initTestCase(){}
57 91 void cleanupTestCase(){}
58 92
59 93 void testCreateVariable()
60 94 {
61 95 VariableController2 vc;
62 96 bool callbackCalled = false;
63 97 connect(&vc,&VariableController2::variableAdded, [&callbackCalled](std::shared_ptr<Variable>){callbackCalled=true;});
64 auto provider = std::make_shared<FakeProvider>();
98 auto provider = std::make_shared<SimpleRange<1>>();
65 99 QVERIFY(!callbackCalled);
66 100 auto var1 = vc.createVariable("var1",{},provider,DateTimeRange());
67 101 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
68 102 QVERIFY(callbackCalled);
69 103 }
70 104
71 105 void testDeleteVariable()
72 106 {
73 107 VariableController2 vc;
74 108 bool callbackCalled = false;
75 109 connect(&vc,&VariableController2::variableDeleted, [&callbackCalled](std::shared_ptr<Variable>){callbackCalled=true;});
76 auto provider = std::make_shared<FakeProvider>();
110 auto provider = std::make_shared<SimpleRange<1>>();
77 111 auto var1 = vc.createVariable("var1",{},provider,DateTimeRange());
78 112 QVERIFY(SciQLop::containers::contains(vc.variables(), var1));
79 113 QVERIFY(!callbackCalled);
80 114 vc.deleteVariable(var1);
81 115 QVERIFY(!SciQLop::containers::contains(vc.variables(), var1));
82 116 QVERIFY(callbackCalled);
83 117 }
84 118
85 119 void testGetData()
86 120 {
87 121 VariableController2 vc;
88 auto provider = std::make_shared<FakeProvider>();
122 auto provider = std::make_shared<SimpleRange<10>>();
89 123 auto range1 = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(14,00),
90 124 QDate(2018,8,7),QTime(16,00));
91 125 auto range2 = DateTimeRange::fromDateTime(QDate(2018,8,7),QTime(12,00),
92 126 QDate(2018,8,7),QTime(18,00));
93 127 auto var1 = vc.createVariable("var1", {}, provider, range1);
94 QCOMPARE(var1->nbPoints(), int(range1.delta()));
128 check_variable_state<RangeType<10>>(var1, range1);
95 129 vc.changeRange(var1, range2);
96 QCOMPARE(var1->nbPoints(), int(range2.delta()));
97
130 check_variable_state<RangeType<10>>(var1, range2);
98 131 }
99 132
100 private:
101
102 133 };
103 134
104 135
105 136 QTEST_MAIN(TestVariableController2)
106 137
107 138 #include "TestVariableController2.moc"
108 139
General Comments 0
You need to be logged in to leave comments. Login now