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