##// END OF EJS Templates
Makes unit test templated to use it for vectors too
Alexandre Leroux -
r611:ca3efd807a86
parent child
Show More
@@ -1,452 +1,467
1 1 #include "Data/DataSeries.h"
2 2 #include "Data/ScalarSeries.h"
3 #include "Data/VectorSeries.h"
3 4
4 5 #include <QObject>
5 6 #include <QtTest>
6 7
7 8 Q_DECLARE_METATYPE(std::shared_ptr<ScalarSeries>)
9 Q_DECLARE_METATYPE(std::shared_ptr<VectorSeries>)
8 10
9 11 class TestDataSeries : public QObject {
10 12 Q_OBJECT
13 private:
14 template <typename T>
15 void testValuesBoundsStructure()
16 {
17 // ////////////// //
18 // Test structure //
19 // ////////////// //
20
21 // Data series to get values bounds
22 QTest::addColumn<std::shared_ptr<T> >("dataSeries");
23
24 // x-axis range
25 QTest::addColumn<double>("minXAxis");
26 QTest::addColumn<double>("maxXAxis");
27
28 // Expected results
29 QTest::addColumn<bool>(
30 "expectedOK"); // Test is expected to be ok (i.e. method doesn't return end iterators)
31 QTest::addColumn<double>("expectedMinValue");
32 QTest::addColumn<double>("expectedMaxValue");
33 }
34
35 template <typename T>
36 void testValuesBounds()
37 {
38 QFETCH(std::shared_ptr<T>, dataSeries);
39 QFETCH(double, minXAxis);
40 QFETCH(double, maxXAxis);
41
42 QFETCH(bool, expectedOK);
43 QFETCH(double, expectedMinValue);
44 QFETCH(double, expectedMaxValue);
45
46 auto minMaxIts = dataSeries->valuesBounds(minXAxis, maxXAxis);
47 auto end = dataSeries->cend();
48
49 // Checks iterators with expected result
50 QCOMPARE(expectedOK, minMaxIts.first != end && minMaxIts.second != end);
51
52 if (expectedOK) {
53 auto compare = [](const auto &v1, const auto &v2) {
54 return (std::isnan(v1) && std::isnan(v2)) || v1 == v2;
55 };
56
57 QVERIFY(compare(expectedMinValue, minMaxIts.first->minValue()));
58 QVERIFY(compare(expectedMaxValue, minMaxIts.second->maxValue()));
59 }
60 }
61
11 62 private slots:
12 63 /// Input test data
13 64 /// @sa testCtor()
14 65 void testCtor_data();
15 66
16 67 /// Tests construction of a data series
17 68 void testCtor();
18 69
19 70 /// Input test data
20 71 /// @sa testMerge()
21 72 void testMerge_data();
22 73
23 74 /// Tests merge of two data series
24 75 void testMerge();
25 76
26 77 /// Input test data
27 78 /// @sa testMinXAxisData()
28 79 void testMinXAxisData_data();
29 80
30 81 /// Tests get min x-axis data of a data series
31 82 void testMinXAxisData();
32 83
33 84 /// Input test data
34 85 /// @sa testMaxXAxisData()
35 86 void testMaxXAxisData_data();
36 87
37 88 /// Tests get max x-axis data of a data series
38 89 void testMaxXAxisData();
39 90
40 91 /// Input test data
41 92 /// @sa testXAxisRange()
42 93 void testXAxisRange_data();
43 94
44 95 /// Tests get x-axis range of a data series
45 96 void testXAxisRange();
46 97
47 98 /// Input test data
48 /// @sa testValuesBounds()
49 void testValuesBounds_data();
99 /// @sa testValuesBoundsScalar()
100 void testValuesBoundsScalar_data();
50 101
51 /// Tests get values bounds of a data series
52 void testValuesBounds();
102 /// Tests get values bounds of a scalar series
103 void testValuesBoundsScalar();
53 104 };
54 105
55 106 void TestDataSeries::testCtor_data()
56 107 {
57 108 // ////////////// //
58 109 // Test structure //
59 110 // ////////////// //
60 111
61 112 // x-axis data
62 113 QTest::addColumn<QVector<double> >("xAxisData");
63 114 // values data
64 115 QTest::addColumn<QVector<double> >("valuesData");
65 116
66 117 // expected x-axis data
67 118 QTest::addColumn<QVector<double> >("expectedXAxisData");
68 119 // expected values data
69 120 QTest::addColumn<QVector<double> >("expectedValuesData");
70 121
71 122 // ////////// //
72 123 // Test cases //
73 124 // ////////// //
74 125
75 126 QTest::newRow("invalidData (different sizes of vectors)")
76 127 << QVector<double>{1., 2., 3., 4., 5.} << QVector<double>{100., 200., 300.}
77 128 << QVector<double>{} << QVector<double>{};
78 129
79 130 QTest::newRow("sortedData") << QVector<double>{1., 2., 3., 4., 5.}
80 131 << QVector<double>{100., 200., 300., 400., 500.}
81 132 << QVector<double>{1., 2., 3., 4., 5.}
82 133 << QVector<double>{100., 200., 300., 400., 500.};
83 134
84 135 QTest::newRow("unsortedData") << QVector<double>{5., 4., 3., 2., 1.}
85 136 << QVector<double>{100., 200., 300., 400., 500.}
86 137 << QVector<double>{1., 2., 3., 4., 5.}
87 138 << QVector<double>{500., 400., 300., 200., 100.};
88 139
89 140 QTest::newRow("unsortedData2")
90 141 << QVector<double>{1., 4., 3., 5., 2.} << QVector<double>{100., 200., 300., 400., 500.}
91 142 << QVector<double>{1., 2., 3., 4., 5.} << QVector<double>{100., 500., 300., 200., 400.};
92 143 }
93 144
94 145 void TestDataSeries::testCtor()
95 146 {
96 147 // Creates series
97 148 QFETCH(QVector<double>, xAxisData);
98 149 QFETCH(QVector<double>, valuesData);
99 150
100 151 auto series = std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
101 152 Unit{}, Unit{});
102 153
103 154 // Validates results : we check that the data series is sorted on its x-axis data
104 155 QFETCH(QVector<double>, expectedXAxisData);
105 156 QFETCH(QVector<double>, expectedValuesData);
106 157
107 158 auto seriesXAxisData = series->xAxisData()->data();
108 159 auto seriesValuesData = series->valuesData()->data();
109 160
110 161 QVERIFY(
111 162 std::equal(expectedXAxisData.cbegin(), expectedXAxisData.cend(), seriesXAxisData.cbegin()));
112 163 QVERIFY(std::equal(expectedValuesData.cbegin(), expectedValuesData.cend(),
113 164 seriesValuesData.cbegin()));
114 165 }
115 166
116 167 namespace {
117 168
118 169 std::shared_ptr<ScalarSeries> createSeries(QVector<double> xAxisData, QVector<double> valuesData)
119 170 {
120 171 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData), Unit{},
121 172 Unit{});
122 173 }
123 174
124 175 } // namespace
125 176
126 177 void TestDataSeries::testMerge_data()
127 178 {
128 179 // ////////////// //
129 180 // Test structure //
130 181 // ////////////// //
131 182
132 183 // Data series to merge
133 184 QTest::addColumn<std::shared_ptr<ScalarSeries> >("dataSeries");
134 185 QTest::addColumn<std::shared_ptr<ScalarSeries> >("dataSeries2");
135 186
136 187 // Expected values in the first data series after merge
137 188 QTest::addColumn<QVector<double> >("expectedXAxisData");
138 189 QTest::addColumn<QVector<double> >("expectedValuesData");
139 190
140 191 // ////////// //
141 192 // Test cases //
142 193 // ////////// //
143 194
144 195 QTest::newRow("sortedMerge")
145 196 << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
146 197 << createSeries({6., 7., 8., 9., 10.}, {600., 700., 800., 900., 1000.})
147 198 << QVector<double>{1., 2., 3., 4., 5., 6., 7., 8., 9., 10.}
148 199 << QVector<double>{100., 200., 300., 400., 500., 600., 700., 800., 900., 1000.};
149 200
150 201 QTest::newRow("unsortedMerge")
151 202 << createSeries({6., 7., 8., 9., 10.}, {600., 700., 800., 900., 1000.})
152 203 << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
153 204 << QVector<double>{1., 2., 3., 4., 5., 6., 7., 8., 9., 10.}
154 205 << QVector<double>{100., 200., 300., 400., 500., 600., 700., 800., 900., 1000.};
155 206
156 207 QTest::newRow("unsortedMerge2")
157 208 << createSeries({1., 2., 8., 9., 10}, {100., 200., 300., 400., 500.})
158 209 << createSeries({3., 4., 5., 6., 7.}, {600., 700., 800., 900., 1000.})
159 210 << QVector<double>{1., 2., 3., 4., 5., 6., 7., 8., 9., 10.}
160 211 << QVector<double>{100., 200., 600., 700., 800., 900., 1000., 300., 400., 500.};
161 212
162 213 QTest::newRow("unsortedMerge3")
163 214 << createSeries({3., 5., 8., 7., 2}, {100., 200., 300., 400., 500.})
164 215 << createSeries({6., 4., 9., 10., 1.}, {600., 700., 800., 900., 1000.})
165 216 << QVector<double>{1., 2., 3., 4., 5., 6., 7., 8., 9., 10.}
166 217 << QVector<double>{1000., 500., 100., 700., 200., 600., 400., 300., 800., 900.};
167 218 }
168 219
169 220 void TestDataSeries::testMerge()
170 221 {
171 222 // Merges series
172 223 QFETCH(std::shared_ptr<ScalarSeries>, dataSeries);
173 224 QFETCH(std::shared_ptr<ScalarSeries>, dataSeries2);
174 225
175 226 dataSeries->merge(dataSeries2.get());
176 227
177 228 // Validates results : we check that the merge is valid and the data series is sorted on its
178 229 // x-axis data
179 230 QFETCH(QVector<double>, expectedXAxisData);
180 231 QFETCH(QVector<double>, expectedValuesData);
181 232
182 233 auto seriesXAxisData = dataSeries->xAxisData()->data();
183 234 auto seriesValuesData = dataSeries->valuesData()->data();
184 235
185 236 QVERIFY(
186 237 std::equal(expectedXAxisData.cbegin(), expectedXAxisData.cend(), seriesXAxisData.cbegin()));
187 238 QVERIFY(std::equal(expectedValuesData.cbegin(), expectedValuesData.cend(),
188 239 seriesValuesData.cbegin()));
189 240 }
190 241
191 242 void TestDataSeries::testMinXAxisData_data()
192 243 {
193 244 // ////////////// //
194 245 // Test structure //
195 246 // ////////////// //
196 247
197 248 // Data series to get min data
198 249 QTest::addColumn<std::shared_ptr<ScalarSeries> >("dataSeries");
199 250
200 251 // Min data
201 252 QTest::addColumn<double>("min");
202 253
203 254 // Expected results
204 255 QTest::addColumn<bool>(
205 256 "expectedOK"); // if true, expects to have a result (i.e. the iterator != end iterator)
206 257 QTest::addColumn<double>(
207 258 "expectedMin"); // Expected value when method doesn't return end iterator
208 259
209 260 // ////////// //
210 261 // Test cases //
211 262 // ////////// //
212 263
213 264 QTest::newRow("minData1") << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
214 265 << 0. << true << 1.;
215 266 QTest::newRow("minData2") << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
216 267 << 1. << true << 1.;
217 268 QTest::newRow("minData3") << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
218 269 << 1.1 << true << 2.;
219 270 QTest::newRow("minData4") << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
220 271 << 5. << true << 5.;
221 272 QTest::newRow("minData5") << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
222 273 << 5.1 << false << std::numeric_limits<double>::quiet_NaN();
223 274 QTest::newRow("minData6") << createSeries({}, {}) << 1.1 << false
224 275 << std::numeric_limits<double>::quiet_NaN();
225 276 }
226 277
227 278 void TestDataSeries::testMinXAxisData()
228 279 {
229 280 QFETCH(std::shared_ptr<ScalarSeries>, dataSeries);
230 281 QFETCH(double, min);
231 282
232 283 QFETCH(bool, expectedOK);
233 284 QFETCH(double, expectedMin);
234 285
235 286 auto it = dataSeries->minXAxisData(min);
236 287
237 288 QCOMPARE(expectedOK, it != dataSeries->cend());
238 289
239 290 // If the method doesn't return a end iterator, checks with expected value
240 291 if (expectedOK) {
241 292 QCOMPARE(expectedMin, it->x());
242 293 }
243 294 }
244 295
245 296 void TestDataSeries::testMaxXAxisData_data()
246 297 {
247 298 // ////////////// //
248 299 // Test structure //
249 300 // ////////////// //
250 301
251 302 // Data series to get max data
252 303 QTest::addColumn<std::shared_ptr<ScalarSeries> >("dataSeries");
253 304
254 305 // Max data
255 306 QTest::addColumn<double>("max");
256 307
257 308 // Expected results
258 309 QTest::addColumn<bool>(
259 310 "expectedOK"); // if true, expects to have a result (i.e. the iterator != end iterator)
260 311 QTest::addColumn<double>(
261 312 "expectedMax"); // Expected value when method doesn't return end iterator
262 313
263 314 // ////////// //
264 315 // Test cases //
265 316 // ////////// //
266 317
267 318 QTest::newRow("maxData1") << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
268 319 << 6. << true << 5.;
269 320 QTest::newRow("maxData2") << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
270 321 << 5. << true << 5.;
271 322 QTest::newRow("maxData3") << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
272 323 << 4.9 << true << 4.;
273 324 QTest::newRow("maxData4") << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
274 325 << 1.1 << true << 1.;
275 326 QTest::newRow("maxData5") << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.})
276 327 << 1. << true << 1.;
277 328 QTest::newRow("maxData6") << createSeries({}, {}) << 1.1 << false
278 329 << std::numeric_limits<double>::quiet_NaN();
279 330 }
280 331
281 332 void TestDataSeries::testMaxXAxisData()
282 333 {
283 334 QFETCH(std::shared_ptr<ScalarSeries>, dataSeries);
284 335 QFETCH(double, max);
285 336
286 337 QFETCH(bool, expectedOK);
287 338 QFETCH(double, expectedMax);
288 339
289 340 auto it = dataSeries->maxXAxisData(max);
290 341
291 342 QCOMPARE(expectedOK, it != dataSeries->cend());
292 343
293 344 // If the method doesn't return a end iterator, checks with expected value
294 345 if (expectedOK) {
295 346 QCOMPARE(expectedMax, it->x());
296 347 }
297 348 }
298 349
299 350 void TestDataSeries::testXAxisRange_data()
300 351 {
301 352 // ////////////// //
302 353 // Test structure //
303 354 // ////////////// //
304 355
305 356 // Data series to get x-axis range
306 357 QTest::addColumn<std::shared_ptr<ScalarSeries> >("dataSeries");
307 358
308 359 // Min/max values
309 360 QTest::addColumn<double>("min");
310 361 QTest::addColumn<double>("max");
311 362
312 363 // Expected values
313 364 QTest::addColumn<QVector<double> >("expectedXAxisData");
314 365 QTest::addColumn<QVector<double> >("expectedValuesData");
315 366
316 367 // ////////// //
317 368 // Test cases //
318 369 // ////////// //
319 370
320 371 QTest::newRow("xAxisRange1") << createSeries({1., 2., 3., 4., 5.},
321 372 {100., 200., 300., 400., 500.})
322 373 << -1. << 3.2 << QVector<double>{1., 2., 3.}
323 374 << QVector<double>{100., 200., 300.};
324 375 QTest::newRow("xAxisRange2") << createSeries({1., 2., 3., 4., 5.},
325 376 {100., 200., 300., 400., 500.})
326 377 << 1. << 4. << QVector<double>{1., 2., 3., 4.}
327 378 << QVector<double>{100., 200., 300., 400.};
328 379 QTest::newRow("xAxisRange3") << createSeries({1., 2., 3., 4., 5.},
329 380 {100., 200., 300., 400., 500.})
330 381 << 1. << 3.9 << QVector<double>{1., 2., 3.}
331 382 << QVector<double>{100., 200., 300.};
332 383 QTest::newRow("xAxisRange4") << createSeries({1., 2., 3., 4., 5.},
333 384 {100., 200., 300., 400., 500.})
334 385 << 0. << 0.9 << QVector<double>{} << QVector<double>{};
335 386 QTest::newRow("xAxisRange5") << createSeries({1., 2., 3., 4., 5.},
336 387 {100., 200., 300., 400., 500.})
337 388 << 0. << 1. << QVector<double>{1.} << QVector<double>{100.};
338 389 QTest::newRow("xAxisRange6") << createSeries({1., 2., 3., 4., 5.},
339 390 {100., 200., 300., 400., 500.})
340 391 << 2.1 << 6. << QVector<double>{3., 4., 5.}
341 392 << QVector<double>{300., 400., 500.};
342 393 QTest::newRow("xAxisRange7") << createSeries({1., 2., 3., 4., 5.},
343 394 {100., 200., 300., 400., 500.})
344 395 << 6. << 9. << QVector<double>{} << QVector<double>{};
345 396 QTest::newRow("xAxisRange8") << createSeries({1., 2., 3., 4., 5.},
346 397 {100., 200., 300., 400., 500.})
347 398 << 5. << 9. << QVector<double>{5.} << QVector<double>{500.};
348 399 }
349 400
350 401 void TestDataSeries::testXAxisRange()
351 402 {
352 403 QFETCH(std::shared_ptr<ScalarSeries>, dataSeries);
353 404 QFETCH(double, min);
354 405 QFETCH(double, max);
355 406
356 407 QFETCH(QVector<double>, expectedXAxisData);
357 408 QFETCH(QVector<double>, expectedValuesData);
358 409
359 410 auto bounds = dataSeries->xAxisRange(min, max);
360 411 QVERIFY(std::equal(bounds.first, bounds.second, expectedXAxisData.cbegin(),
361 412 expectedXAxisData.cend(),
362 413 [](const auto &it, const auto &expectedX) { return it.x() == expectedX; }));
363 414 QVERIFY(std::equal(
364 415 bounds.first, bounds.second, expectedValuesData.cbegin(), expectedValuesData.cend(),
365 416 [](const auto &it, const auto &expectedVal) { return it.value() == expectedVal; }));
366 417 }
367 418
368 void TestDataSeries::testValuesBounds_data()
419 void TestDataSeries::testValuesBoundsScalar_data()
369 420 {
370 // ////////////// //
371 // Test structure //
372 // ////////////// //
373
374 // Data series to get values bounds
375 QTest::addColumn<std::shared_ptr<ScalarSeries> >("dataSeries");
376
377 // x-axis range
378 QTest::addColumn<double>("minXAxis");
379 QTest::addColumn<double>("maxXAxis");
380
381 // Expected results
382 QTest::addColumn<bool>(
383 "expectedOK"); // Test is expected to be ok (i.e. method doesn't return end iterators)
384 QTest::addColumn<double>("expectedMinValue");
385 QTest::addColumn<double>("expectedMaxValue");
421 testValuesBoundsStructure<ScalarSeries>();
386 422
387 423 // ////////// //
388 424 // Test cases //
389 425 // ////////// //
390 426
391 427 QTest::newRow("valuesBounds1")
392 428 << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.}) << 0. << 6. << true
393 429 << 100. << 500.;
394 430 QTest::newRow("valuesBounds2")
395 431 << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.}) << 2. << 4. << true
396 432 << 200. << 400.;
397 433 QTest::newRow("valuesBounds3")
398 434 << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.}) << 0. << 0.5 << false
399 435 << std::numeric_limits<double>::quiet_NaN() << std::numeric_limits<double>::quiet_NaN();
400 436 QTest::newRow("valuesBounds4")
401 437 << createSeries({1., 2., 3., 4., 5.}, {100., 200., 300., 400., 500.}) << 5.1 << 6. << false
402 438 << std::numeric_limits<double>::quiet_NaN() << std::numeric_limits<double>::quiet_NaN();
403 439 QTest::newRow("valuesBounds5")
404 440 << createSeries({1.}, {100.}) << 0. << 2. << true << 100. << 100.;
405 441 QTest::newRow("valuesBounds6")
406 442 << createSeries({}, {}) << 0. << 2. << false << std::numeric_limits<double>::quiet_NaN()
407 443 << std::numeric_limits<double>::quiet_NaN();
408 444
409 445 // Tests with NaN values: NaN values are not included in min/max search
410 446 QTest::newRow("valuesBounds7")
411 447 << createSeries({1., 2., 3., 4., 5.},
412 448 {std::numeric_limits<double>::quiet_NaN(), 200., 300., 400.,
413 449 std::numeric_limits<double>::quiet_NaN()})
414 450 << 0. << 6. << true << 200. << 400.;
415 451 QTest::newRow("valuesBounds8")
416 452 << createSeries(
417 453 {1., 2., 3., 4., 5.},
418 454 {std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(),
419 455 std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(),
420 456 std::numeric_limits<double>::quiet_NaN()})
421 457 << 0. << 6. << true << std::numeric_limits<double>::quiet_NaN()
422 458 << std::numeric_limits<double>::quiet_NaN();
423 459 }
424 460
425 void TestDataSeries::testValuesBounds()
461 void TestDataSeries::testValuesBoundsScalar()
426 462 {
427 QFETCH(std::shared_ptr<ScalarSeries>, dataSeries);
428 QFETCH(double, minXAxis);
429 QFETCH(double, maxXAxis);
430
431 QFETCH(bool, expectedOK);
432 QFETCH(double, expectedMinValue);
433 QFETCH(double, expectedMaxValue);
434
435 auto minMaxIts = dataSeries->valuesBounds(minXAxis, maxXAxis);
436 auto end = dataSeries->cend();
437
438 // Checks iterators with expected result
439 QCOMPARE(expectedOK, minMaxIts.first != end && minMaxIts.second != end);
440
441 if (expectedOK) {
442 auto compare = [](const auto &v1, const auto &v2) {
443 return (std::isnan(v1) && std::isnan(v2)) || v1 == v2;
444 };
445
446 QVERIFY(compare(expectedMinValue, minMaxIts.first->minValue()));
447 QVERIFY(compare(expectedMaxValue, minMaxIts.second->maxValue()));
448 }
463 testValuesBounds<ScalarSeries>();
449 464 }
450 465
451 466 QTEST_MAIN(TestDataSeries)
452 467 #include "TestDataSeries.moc"
General Comments 0
You need to be logged in to leave comments. Login now