##// END OF EJS Templates
Refactors TestAmdaResultParser...
Alexandre Leroux -
r1011:ed386af0bc9b
parent child
Show More
@@ -1,286 +1,317
1 1 #include "AmdaResultParser.h"
2 2
3 3 #include <Data/ScalarSeries.h>
4 4 #include <Data/VectorSeries.h>
5 5
6 6 #include <QObject>
7 7 #include <QtTest>
8 8
9 9 namespace {
10 10
11 11 /// Path for the tests
12 12 const auto TESTS_RESOURCES_PATH
13 13 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaResultParser"}.absoluteFilePath();
14 14
15 15 QDateTime dateTime(int year, int month, int day, int hours, int minutes, int seconds)
16 16 {
17 17 return QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC};
18 18 }
19 19
20 20 QString inputFilePath(const QString &inputFileName)
21 21 {
22 22 return QFileInfo{TESTS_RESOURCES_PATH, inputFileName}.absoluteFilePath();
23 23 }
24 24
25 25 template <typename T>
26 26 struct ExpectedResults {
27 explicit ExpectedResults() = default;
28 27
29 explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector<QDateTime> &xAxisData,
30 QVector<double> valuesData)
31 : ExpectedResults(xAxisUnit, valuesUnit, xAxisData,
32 QVector<QVector<double> >{std::move(valuesData)})
28 ExpectedResults &setParsingOK(bool parsingOK)
33 29 {
30 m_ParsingOK = parsingOK;
31 return *this;
34 32 }
35 33
36 /// Ctor with QVector<QDateTime> as x-axis data. Datetimes are converted to doubles
37 explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector<QDateTime> &xAxisData,
38 QVector<QVector<double> > valuesData)
39 : m_ParsingOK{true},
40 m_XAxisUnit{xAxisUnit},
41 m_ValuesUnit{valuesUnit},
42 m_XAxisData{},
43 m_ValuesData{std::move(valuesData)}
34 ExpectedResults &setXAxisUnit(Unit xAxisUnit)
44 35 {
36 m_XAxisUnit = std::move(xAxisUnit);
37 return *this;
38 }
39
40 ExpectedResults &setXAxisData(const QVector<QDateTime> &xAxisData)
41 {
42 m_XAxisData.clear();
43
45 44 // Converts QVector<QDateTime> to QVector<double>
46 45 std::transform(xAxisData.cbegin(), xAxisData.cend(), std::back_inserter(m_XAxisData),
47 46 [](const auto &dateTime) { return dateTime.toMSecsSinceEpoch() / 1000.; });
47
48 return *this;
49 }
50
51 ExpectedResults &setValuesUnit(Unit valuesUnit)
52 {
53 m_ValuesUnit = std::move(valuesUnit);
54 return *this;
55 }
56
57 ExpectedResults &setValuesData(QVector<double> valuesData)
58 {
59 m_ValuesData.clear();
60 m_ValuesData.push_back(std::move(valuesData));
61 return *this;
62 }
63
64 ExpectedResults &setValuesData(QVector<QVector<double> > valuesData)
65 {
66 m_ValuesData = std::move(valuesData);
67 return *this;
48 68 }
49 69
50 70 /**
51 71 * Validates a DataSeries compared to the expected results
52 72 * @param results the DataSeries to validate
53 73 */
54 74 void validate(std::shared_ptr<IDataSeries> results)
55 75 {
56 76 if (m_ParsingOK) {
57 77 auto dataSeries = dynamic_cast<T *>(results.get());
58 78 if (dataSeries == nullptr) {
59 79
60 80 // No unit detected, parsink ok but data is nullptr
61 81 // TODO, improve the test to verify that the data is null
62 82 return;
63 83 }
64 84
65 85 // Checks units
66 86 QVERIFY(dataSeries->xAxisUnit() == m_XAxisUnit);
67 87 QVERIFY(dataSeries->valuesUnit() == m_ValuesUnit);
68 88
69 89 auto verifyRange = [dataSeries](const auto &expectedData, const auto &equalFun) {
70 90 QVERIFY(std::equal(dataSeries->cbegin(), dataSeries->cend(), expectedData.cbegin(),
71 91 expectedData.cend(),
72 92 [&equalFun](const auto &dataSeriesIt, const auto &expectedX) {
73 93 return equalFun(dataSeriesIt, expectedX);
74 94 }));
75 95 };
76 96
77 97 // Checks x-axis data
78 98 verifyRange(m_XAxisData, [](const auto &seriesIt, const auto &value) {
79 99 return seriesIt.x() == value;
80 100 });
81 101
82 102 // Checks values data of each component
83 103 for (auto i = 0; i < m_ValuesData.size(); ++i) {
84 104 verifyRange(m_ValuesData.at(i), [i](const auto &seriesIt, const auto &value) {
85 105 auto itValue = seriesIt.value(i);
86 106 return (std::isnan(itValue) && std::isnan(value)) || seriesIt.value(i) == value;
87 107 });
88 108 }
89 109 }
90 110 else {
91 111 QVERIFY(results == nullptr);
92 112 }
93 113 }
94 114
95 115 // Parsing was successfully completed
96 116 bool m_ParsingOK{false};
97 117 // Expected x-axis unit
98 118 Unit m_XAxisUnit{};
99 // Expected values unit
100 Unit m_ValuesUnit{};
101 119 // Expected x-axis data
102 120 QVector<double> m_XAxisData{};
121 // Expected values unit
122 Unit m_ValuesUnit{};
103 123 // Expected values data
104 124 QVector<QVector<double> > m_ValuesData{};
105 125 };
106 126
107 127 } // namespace
108 128
109 129 Q_DECLARE_METATYPE(ExpectedResults<ScalarSeries>)
110 130 Q_DECLARE_METATYPE(ExpectedResults<VectorSeries>)
111 131
112 132 class TestAmdaResultParser : public QObject {
113 133 Q_OBJECT
114 134 private:
115 135 template <typename T>
116 136 void testReadDataStructure()
117 137 {
118 138 // ////////////// //
119 139 // Test structure //
120 140 // ////////////// //
121 141
122 142 // Name of TXT file to read
123 143 QTest::addColumn<QString>("inputFileName");
124 144 // Expected results
125 145 QTest::addColumn<ExpectedResults<T> >("expectedResults");
126 146 }
127 147
128 148 template <typename T>
129 149 void testRead(AmdaResultParser::ValueType valueType)
130 150 {
131 151 QFETCH(QString, inputFileName);
132 152 QFETCH(ExpectedResults<T>, expectedResults);
133 153
134 154 // Parses file
135 155 auto filePath = inputFilePath(inputFileName);
136 156 auto results = AmdaResultParser::readTxt(filePath, valueType);
137 157
138 158 // ///////////////// //
139 159 // Validates results //
140 160 // ///////////////// //
141 161 expectedResults.validate(results);
142 162 }
143 163
144 164 private slots:
145 165 /// Input test data
146 166 /// @sa testReadScalarTxt()
147 167 void testReadScalarTxt_data();
148 168
149 169 /// Tests parsing scalar series of a TXT file
150 170 void testReadScalarTxt();
151 171
152 172 /// Input test data
153 173 /// @sa testReadVectorTxt()
154 174 void testReadVectorTxt_data();
155 175
156 176 /// Tests parsing vector series of a TXT file
157 177 void testReadVectorTxt();
158 178 };
159 179
160 180 void TestAmdaResultParser::testReadScalarTxt_data()
161 181 {
162 182 testReadDataStructure<ScalarSeries>();
163 183
164 184 // ////////// //
165 185 // Test cases //
166 186 // ////////// //
167 187
168 188 // Valid files
169 189 QTest::newRow("Valid file")
170 190 << QStringLiteral("ValidScalar1.txt")
171 << ExpectedResults<ScalarSeries>{
172 Unit{QStringLiteral("nT"), true}, Unit{},
173 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
174 dateTime(2013, 9, 23, 9, 2, 30), dateTime(2013, 9, 23, 9, 3, 30),
175 dateTime(2013, 9, 23, 9, 4, 30), dateTime(2013, 9, 23, 9, 5, 30),
176 dateTime(2013, 9, 23, 9, 6, 30), dateTime(2013, 9, 23, 9, 7, 30),
177 dateTime(2013, 9, 23, 9, 8, 30), dateTime(2013, 9, 23, 9, 9, 30)},
178 QVector<double>{-2.83950, -2.71850, -2.52150, -2.57633, -2.58050, -2.48325, -2.63025,
179 -2.55800, -2.43250, -2.42200}};
191 << ExpectedResults<ScalarSeries>{}
192 .setParsingOK(true)
193 .setXAxisUnit(Unit{"nT", true})
194 .setXAxisData({dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
195 dateTime(2013, 9, 23, 9, 2, 30), dateTime(2013, 9, 23, 9, 3, 30),
196 dateTime(2013, 9, 23, 9, 4, 30), dateTime(2013, 9, 23, 9, 5, 30),
197 dateTime(2013, 9, 23, 9, 6, 30), dateTime(2013, 9, 23, 9, 7, 30),
198 dateTime(2013, 9, 23, 9, 8, 30), dateTime(2013, 9, 23, 9, 9, 30)})
199 .setValuesData({-2.83950, -2.71850, -2.52150, -2.57633, -2.58050, -2.48325, -2.63025,
200 -2.55800, -2.43250, -2.42200});
180 201
181 202 QTest::newRow("Valid file (value of first line is invalid but it is converted to NaN")
182 203 << QStringLiteral("WrongValue.txt")
183 << ExpectedResults<ScalarSeries>{
184 Unit{QStringLiteral("nT"), true}, Unit{},
185 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
186 dateTime(2013, 9, 23, 9, 2, 30)},
187 QVector<double>{std::numeric_limits<double>::quiet_NaN(), -2.71850, -2.52150}};
204 << ExpectedResults<ScalarSeries>{}
205 .setParsingOK(true)
206 .setXAxisUnit(Unit{"nT", true})
207 .setXAxisData({dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
208 dateTime(2013, 9, 23, 9, 2, 30)})
209 .setValuesData({std::numeric_limits<double>::quiet_NaN(), -2.71850, -2.52150});
188 210
189 211 QTest::newRow("Valid file that contains NaN values")
190 212 << QStringLiteral("NaNValue.txt")
191 << ExpectedResults<ScalarSeries>{
192 Unit{QStringLiteral("nT"), true}, Unit{},
193 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
194 dateTime(2013, 9, 23, 9, 2, 30)},
195 QVector<double>{std::numeric_limits<double>::quiet_NaN(), -2.71850, -2.52150}};
213 << ExpectedResults<ScalarSeries>{}
214 .setParsingOK(true)
215 .setXAxisUnit(Unit{("nT"), true})
216 .setXAxisData({dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
217 dateTime(2013, 9, 23, 9, 2, 30)})
218 .setValuesData({std::numeric_limits<double>::quiet_NaN(), -2.71850, -2.52150});
196 219
197 220 // Valid files but with some invalid lines (wrong unit, wrong values, etc.)
198 QTest::newRow("No unit file") << QStringLiteral("NoUnit.txt")
199 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral(""), true},
200 Unit{}, QVector<QDateTime>{},
201 QVector<double>{}};
221 QTest::newRow("No unit file")
222 << QStringLiteral("NoUnit.txt")
223 << ExpectedResults<ScalarSeries>{}.setParsingOK(true).setXAxisUnit(Unit{"", true});
224
202 225 QTest::newRow("Wrong unit file")
203 226 << QStringLiteral("WrongUnit.txt")
204 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral(""), true}, Unit{},
205 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30),
206 dateTime(2013, 9, 23, 9, 1, 30),
207 dateTime(2013, 9, 23, 9, 2, 30)},
208 QVector<double>{-2.83950, -2.71850, -2.52150}};
227 << ExpectedResults<ScalarSeries>{}
228 .setParsingOK(true)
229 .setXAxisUnit(Unit{"", true})
230 .setXAxisData({dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
231 dateTime(2013, 9, 23, 9, 2, 30)})
232 .setValuesData({-2.83950, -2.71850, -2.52150});
209 233
210 234 QTest::newRow("Wrong results file (date of first line is invalid")
211 235 << QStringLiteral("WrongDate.txt")
212 << ExpectedResults<ScalarSeries>{
213 Unit{QStringLiteral("nT"), true}, Unit{},
214 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
215 QVector<double>{-2.71850, -2.52150}};
236 << ExpectedResults<ScalarSeries>{}
237 .setParsingOK(true)
238 .setXAxisUnit(Unit{"nT", true})
239 .setXAxisData({dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)})
240 .setValuesData({-2.71850, -2.52150});
216 241
217 242 QTest::newRow("Wrong results file (too many values for first line")
218 243 << QStringLiteral("TooManyValues.txt")
219 << ExpectedResults<ScalarSeries>{
220 Unit{QStringLiteral("nT"), true}, Unit{},
221 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
222 QVector<double>{-2.71850, -2.52150}};
244 << ExpectedResults<ScalarSeries>{}
245 .setParsingOK(true)
246 .setXAxisUnit(Unit{"nT", true})
247 .setXAxisData({dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)})
248 .setValuesData({-2.71850, -2.52150});
223 249
224 250 QTest::newRow("Wrong results file (x of first line is NaN")
225 251 << QStringLiteral("NaNX.txt")
226 << ExpectedResults<ScalarSeries>{
227 Unit{QStringLiteral("nT"), true}, Unit{},
228 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
229 QVector<double>{-2.71850, -2.52150}};
252 << ExpectedResults<ScalarSeries>{}
253 .setParsingOK(true)
254 .setXAxisUnit(Unit{"nT", true})
255 .setXAxisData({dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)})
256 .setValuesData({-2.71850, -2.52150});
230 257
231 258 QTest::newRow("Invalid file type (vector)")
232 259 << QStringLiteral("ValidVector1.txt")
233 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral("nT"), true}, Unit{},
234 QVector<QDateTime>{}, QVector<double>{}};
260 << ExpectedResults<ScalarSeries>{}.setParsingOK(true).setXAxisUnit(Unit{"nT", true});
235 261
236 262 // Invalid files
237 QTest::newRow("Invalid file (unexisting file)") << QStringLiteral("UnexistingFile.txt")
238 << ExpectedResults<ScalarSeries>{};
263 QTest::newRow("Invalid file (unexisting file)")
264 << QStringLiteral("UnexistingFile.txt")
265 << ExpectedResults<ScalarSeries>{}.setParsingOK(false);
239 266
240 QTest::newRow("Invalid file (file not found on server)") << QStringLiteral("FileNotFound.txt")
241 << ExpectedResults<ScalarSeries>{};
267 QTest::newRow("Invalid file (file not found on server)")
268 << QStringLiteral("FileNotFound.txt")
269 << ExpectedResults<ScalarSeries>{}.setParsingOK(false);
242 270 }
243 271
244 272 void TestAmdaResultParser::testReadScalarTxt()
245 273 {
246 274 testRead<ScalarSeries>(AmdaResultParser::ValueType::SCALAR);
247 275 }
248 276
249 277 void TestAmdaResultParser::testReadVectorTxt_data()
250 278 {
251 279 testReadDataStructure<VectorSeries>();
252 280
253 281 // ////////// //
254 282 // Test cases //
255 283 // ////////// //
256 284
257 285 // Valid files
258 286 QTest::newRow("Valid file")
259 287 << QStringLiteral("ValidVector1.txt")
260 << ExpectedResults<VectorSeries>{
261 Unit{QStringLiteral("nT"), true}, Unit{},
262 QVector<QDateTime>{dateTime(2013, 7, 2, 9, 13, 50), dateTime(2013, 7, 2, 9, 14, 6),
263 dateTime(2013, 7, 2, 9, 14, 22), dateTime(2013, 7, 2, 9, 14, 38),
264 dateTime(2013, 7, 2, 9, 14, 54), dateTime(2013, 7, 2, 9, 15, 10),
265 dateTime(2013, 7, 2, 9, 15, 26), dateTime(2013, 7, 2, 9, 15, 42),
266 dateTime(2013, 7, 2, 9, 15, 58), dateTime(2013, 7, 2, 9, 16, 14)},
267 QVector<QVector<double> >{
268 {-0.332, -1.011, -1.457, -1.293, -1.217, -1.443, -1.278, -1.202, -1.22, -1.259},
269 {3.206, 2.999, 2.785, 2.736, 2.612, 2.564, 2.892, 2.862, 2.859, 2.764},
270 {0.058, 0.496, 1.018, 1.485, 1.662, 1.505, 1.168, 1.244, 1.15, 1.358}}};
288 << ExpectedResults<VectorSeries>{}
289 .setParsingOK(true)
290 .setXAxisUnit(Unit{"nT", true})
291 .setXAxisData({dateTime(2013, 7, 2, 9, 13, 50), dateTime(2013, 7, 2, 9, 14, 6),
292 dateTime(2013, 7, 2, 9, 14, 22), dateTime(2013, 7, 2, 9, 14, 38),
293 dateTime(2013, 7, 2, 9, 14, 54), dateTime(2013, 7, 2, 9, 15, 10),
294 dateTime(2013, 7, 2, 9, 15, 26), dateTime(2013, 7, 2, 9, 15, 42),
295 dateTime(2013, 7, 2, 9, 15, 58), dateTime(2013, 7, 2, 9, 16, 14)})
296 .setValuesData(
297 {{-0.332, -1.011, -1.457, -1.293, -1.217, -1.443, -1.278, -1.202, -1.22, -1.259},
298 {3.206, 2.999, 2.785, 2.736, 2.612, 2.564, 2.892, 2.862, 2.859, 2.764},
299 {0.058, 0.496, 1.018, 1.485, 1.662, 1.505, 1.168, 1.244, 1.15, 1.358}});
271 300
272 301 // Valid files but with some invalid lines (wrong unit, wrong values, etc.)
273 302 QTest::newRow("Invalid file type (scalar)")
274 303 << QStringLiteral("ValidScalar1.txt")
275 << ExpectedResults<VectorSeries>{Unit{QStringLiteral("nT"), true}, Unit{},
276 QVector<QDateTime>{},
277 QVector<QVector<double> >{{}, {}, {}}};
304 << ExpectedResults<VectorSeries>{}
305 .setParsingOK(true)
306 .setXAxisUnit(Unit{"nT", true})
307 .setXAxisData({})
308 .setValuesData(QVector<QVector<double> >{{}, {}, {}});
278 309 }
279 310
280 311 void TestAmdaResultParser::testReadVectorTxt()
281 312 {
282 313 testRead<VectorSeries>(AmdaResultParser::ValueType::VECTOR);
283 314 }
284 315
285 316 QTEST_MAIN(TestAmdaResultParser)
286 317 #include "TestAmdaResultParser.moc"
General Comments 0
You need to be logged in to leave comments. Login now