##// END OF EJS Templates
Updates unit tests to handle NaN values...
Alexandre Leroux -
r497:59327bc75bab
parent child
Show More
@@ -0,0 +1,6
1 #Sampling Time : 60
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
4 NaN -3.01425
5 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
@@ -1,182 +1,212
1 #include "AmdaResultParser.h"
1 #include "AmdaResultParser.h"
2
2
3 #include <Data/ScalarSeries.h>
3 #include <Data/ScalarSeries.h>
4
4
5 #include <QObject>
5 #include <QObject>
6 #include <QtTest>
6 #include <QtTest>
7
7
8 namespace {
8 namespace {
9
9
10 /// Path for the tests
10 /// Path for the tests
11 const auto TESTS_RESOURCES_PATH
11 const auto TESTS_RESOURCES_PATH
12 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaResultParser"}.absoluteFilePath();
12 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaResultParser"}.absoluteFilePath();
13
13
14 /// Compares two vectors that can potentially contain NaN values
15 bool compareVectors(const QVector<double> &v1, const QVector<double> &v2)
16 {
17 if (v1.size() != v2.size()) {
18 return false;
19 }
20
21 auto result = true;
22 auto v2It = v2.cbegin();
23 for (auto v1It = v1.cbegin(), v1End = v1.cend(); v1It != v1End && result; ++v1It, ++v2It) {
24 auto v1Value = *v1It;
25 auto v2Value = *v2It;
26
27 // If v1 is NaN, v2 has to be NaN too
28 result = std::isnan(v1Value) ? std::isnan(v2Value) : (v1Value == v2Value);
29 }
30
31 return result;
32 }
33
14 QString inputFilePath(const QString &inputFileName)
34 QString inputFilePath(const QString &inputFileName)
15 {
35 {
16 return QFileInfo{TESTS_RESOURCES_PATH, inputFileName}.absoluteFilePath();
36 return QFileInfo{TESTS_RESOURCES_PATH, inputFileName}.absoluteFilePath();
17 }
37 }
18
38
19 struct ExpectedResults {
39 struct ExpectedResults {
20 explicit ExpectedResults() = default;
40 explicit ExpectedResults() = default;
21
41
22 /// Ctor with QVector<QDateTime> as x-axis data. Datetimes are converted to doubles
42 /// Ctor with QVector<QDateTime> as x-axis data. Datetimes are converted to doubles
23 explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector<QDateTime> &xAxisData,
43 explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector<QDateTime> &xAxisData,
24 QVector<double> valuesData)
44 QVector<double> valuesData)
25 : m_ParsingOK{true},
45 : m_ParsingOK{true},
26 m_XAxisUnit{xAxisUnit},
46 m_XAxisUnit{xAxisUnit},
27 m_ValuesUnit{valuesUnit},
47 m_ValuesUnit{valuesUnit},
28 m_XAxisData{},
48 m_XAxisData{},
29 m_ValuesData{std::move(valuesData)}
49 m_ValuesData{std::move(valuesData)}
30 {
50 {
31 // Converts QVector<QDateTime> to QVector<double>
51 // Converts QVector<QDateTime> to QVector<double>
32 std::transform(xAxisData.cbegin(), xAxisData.cend(), std::back_inserter(m_XAxisData),
52 std::transform(xAxisData.cbegin(), xAxisData.cend(), std::back_inserter(m_XAxisData),
33 [](const auto &dateTime) { return dateTime.toMSecsSinceEpoch() / 1000.; });
53 [](const auto &dateTime) { return dateTime.toMSecsSinceEpoch() / 1000.; });
34 }
54 }
35
55
36 /**
56 /**
37 * Validates a DataSeries compared to the expected results
57 * Validates a DataSeries compared to the expected results
38 * @param results the DataSeries to validate
58 * @param results the DataSeries to validate
39 */
59 */
40 void validate(std::shared_ptr<IDataSeries> results)
60 void validate(std::shared_ptr<IDataSeries> results)
41 {
61 {
42 if (m_ParsingOK) {
62 if (m_ParsingOK) {
43 auto scalarSeries = dynamic_cast<ScalarSeries *>(results.get());
63 auto scalarSeries = dynamic_cast<ScalarSeries *>(results.get());
44 QVERIFY(scalarSeries != nullptr);
64 QVERIFY(scalarSeries != nullptr);
45
65
46 // Checks units
66 // Checks units
47 QVERIFY(scalarSeries->xAxisUnit() == m_XAxisUnit);
67 QVERIFY(scalarSeries->xAxisUnit() == m_XAxisUnit);
48 QVERIFY(scalarSeries->valuesUnit() == m_ValuesUnit);
68 QVERIFY(scalarSeries->valuesUnit() == m_ValuesUnit);
49
69
50 // Checks values
70 // Checks values : as the vectors can potentially contain NaN values, we must use a
51 QVERIFY(scalarSeries->xAxisData()->data() == m_XAxisData);
71 // custom vector comparison method
52 QVERIFY(scalarSeries->valuesData()->data() == m_ValuesData);
72 QVERIFY(compareVectors(scalarSeries->xAxisData()->data(), m_XAxisData));
73 QVERIFY(compareVectors(scalarSeries->valuesData()->data(), m_ValuesData));
53 }
74 }
54 else {
75 else {
55 QVERIFY(results == nullptr);
76 QVERIFY(results == nullptr);
56 }
77 }
57 }
78 }
58
79
59 // Parsing was successfully completed
80 // Parsing was successfully completed
60 bool m_ParsingOK{false};
81 bool m_ParsingOK{false};
61 // Expected x-axis unit
82 // Expected x-axis unit
62 Unit m_XAxisUnit{};
83 Unit m_XAxisUnit{};
63 // Expected values unit
84 // Expected values unit
64 Unit m_ValuesUnit{};
85 Unit m_ValuesUnit{};
65 // Expected x-axis data
86 // Expected x-axis data
66 QVector<double> m_XAxisData{};
87 QVector<double> m_XAxisData{};
67 // Expected values data
88 // Expected values data
68 QVector<double> m_ValuesData{};
89 QVector<double> m_ValuesData{};
69 };
90 };
70
91
71 } // namespace
92 } // namespace
72
93
73 Q_DECLARE_METATYPE(ExpectedResults)
94 Q_DECLARE_METATYPE(ExpectedResults)
74
95
75 class TestAmdaResultParser : public QObject {
96 class TestAmdaResultParser : public QObject {
76 Q_OBJECT
97 Q_OBJECT
77 private slots:
98 private slots:
78 /// Input test data
99 /// Input test data
79 /// @sa testTxtJson()
100 /// @sa testTxtJson()
80 void testReadTxt_data();
101 void testReadTxt_data();
81
102
82 /// Tests parsing of a TXT file
103 /// Tests parsing of a TXT file
83 void testReadTxt();
104 void testReadTxt();
84 };
105 };
85
106
86 void TestAmdaResultParser::testReadTxt_data()
107 void TestAmdaResultParser::testReadTxt_data()
87 {
108 {
88 // ////////////// //
109 // ////////////// //
89 // Test structure //
110 // Test structure //
90 // ////////////// //
111 // ////////////// //
91
112
92 // Name of TXT file to read
113 // Name of TXT file to read
93 QTest::addColumn<QString>("inputFileName");
114 QTest::addColumn<QString>("inputFileName");
94 // Expected results
115 // Expected results
95 QTest::addColumn<ExpectedResults>("expectedResults");
116 QTest::addColumn<ExpectedResults>("expectedResults");
96
117
97 // ////////// //
118 // ////////// //
98 // Test cases //
119 // Test cases //
99 // ////////// //
120 // ////////// //
100
121
101 auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) {
122 auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) {
102 return QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC};
123 return QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC};
103 };
124 };
104
125
105 // Valid file
126 // Valid files
106 QTest::newRow("Valid file")
127 QTest::newRow("Valid file")
107 << QStringLiteral("ValidScalar1.txt")
128 << QStringLiteral("ValidScalar1.txt")
108 << ExpectedResults{
129 << ExpectedResults{
109 Unit{QStringLiteral("nT"), true}, Unit{},
130 Unit{QStringLiteral("nT"), true}, Unit{},
110 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
131 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
111 dateTime(2013, 9, 23, 9, 2, 30), dateTime(2013, 9, 23, 9, 3, 30),
132 dateTime(2013, 9, 23, 9, 2, 30), dateTime(2013, 9, 23, 9, 3, 30),
112 dateTime(2013, 9, 23, 9, 4, 30), dateTime(2013, 9, 23, 9, 5, 30),
133 dateTime(2013, 9, 23, 9, 4, 30), dateTime(2013, 9, 23, 9, 5, 30),
113 dateTime(2013, 9, 23, 9, 6, 30), dateTime(2013, 9, 23, 9, 7, 30),
134 dateTime(2013, 9, 23, 9, 6, 30), dateTime(2013, 9, 23, 9, 7, 30),
114 dateTime(2013, 9, 23, 9, 8, 30), dateTime(2013, 9, 23, 9, 9, 30)},
135 dateTime(2013, 9, 23, 9, 8, 30), dateTime(2013, 9, 23, 9, 9, 30)},
115 QVector<double>{-2.83950, -2.71850, -2.52150, -2.57633, -2.58050, -2.48325, -2.63025,
136 QVector<double>{-2.83950, -2.71850, -2.52150, -2.57633, -2.58050, -2.48325, -2.63025,
116 -2.55800, -2.43250, -2.42200}};
137 -2.55800, -2.43250, -2.42200}};
117
138
139 QTest::newRow("Valid file (value of first line is invalid but it is converted to NaN")
140 << QStringLiteral("WrongValue.txt")
141 << ExpectedResults{
142 Unit{QStringLiteral("nT"), true}, Unit{},
143 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
144 dateTime(2013, 9, 23, 9, 2, 30)},
145 QVector<double>{std::numeric_limits<double>::quiet_NaN(), -2.71850, -2.52150}};
146
147 QTest::newRow("Valid file that contains NaN values")
148 << QStringLiteral("NaNValue.txt")
149 << ExpectedResults{
150 Unit{QStringLiteral("nT"), true}, Unit{},
151 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
152 dateTime(2013, 9, 23, 9, 2, 30)},
153 QVector<double>{std::numeric_limits<double>::quiet_NaN(), -2.71850, -2.52150}};
154
118 // Valid files but with some invalid lines (wrong unit, wrong values, etc.)
155 // Valid files but with some invalid lines (wrong unit, wrong values, etc.)
119 QTest::newRow("No unit file") << QStringLiteral("NoUnit.txt")
156 QTest::newRow("No unit file") << QStringLiteral("NoUnit.txt")
120 << ExpectedResults{Unit{QStringLiteral(""), true}, Unit{},
157 << ExpectedResults{Unit{QStringLiteral(""), true}, Unit{},
121 QVector<QDateTime>{}, QVector<double>{}};
158 QVector<QDateTime>{}, QVector<double>{}};
122 QTest::newRow("Wrong unit file")
159 QTest::newRow("Wrong unit file")
123 << QStringLiteral("WrongUnit.txt")
160 << QStringLiteral("WrongUnit.txt")
124 << ExpectedResults{Unit{QStringLiteral(""), true}, Unit{},
161 << ExpectedResults{Unit{QStringLiteral(""), true}, Unit{},
125 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30),
162 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30),
126 dateTime(2013, 9, 23, 9, 1, 30),
163 dateTime(2013, 9, 23, 9, 1, 30),
127 dateTime(2013, 9, 23, 9, 2, 30)},
164 dateTime(2013, 9, 23, 9, 2, 30)},
128 QVector<double>{-2.83950, -2.71850, -2.52150}};
165 QVector<double>{-2.83950, -2.71850, -2.52150}};
129
166
130 QTest::newRow("Wrong results file (date of first line is invalid")
167 QTest::newRow("Wrong results file (date of first line is invalid")
131 << QStringLiteral("WrongDate.txt")
168 << QStringLiteral("WrongDate.txt")
132 << ExpectedResults{
169 << ExpectedResults{
133 Unit{QStringLiteral("nT"), true}, Unit{},
170 Unit{QStringLiteral("nT"), true}, Unit{},
134 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
171 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
135 QVector<double>{-2.71850, -2.52150}};
172 QVector<double>{-2.71850, -2.52150}};
136
173
137 QTest::newRow("Wrong results file (too many values for first line")
174 QTest::newRow("Wrong results file (too many values for first line")
138 << QStringLiteral("TooManyValues.txt")
175 << QStringLiteral("TooManyValues.txt")
139 << ExpectedResults{
176 << ExpectedResults{
140 Unit{QStringLiteral("nT"), true}, Unit{},
177 Unit{QStringLiteral("nT"), true}, Unit{},
141 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
178 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
142 QVector<double>{-2.71850, -2.52150}};
179 QVector<double>{-2.71850, -2.52150}};
143
180
144 QTest::newRow("Wrong results file (value of first line is invalid")
181 QTest::newRow("Wrong results file (x of first line is NaN")
145 << QStringLiteral("WrongValue.txt")
182 << QStringLiteral("NaNX.txt")
146 << ExpectedResults{
147 Unit{QStringLiteral("nT"), true}, Unit{},
148 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
149 QVector<double>{-2.71850, -2.52150}};
150
151 QTest::newRow("Wrong results file (value of first line is NaN")
152 << QStringLiteral("NaNValue.txt")
153 << ExpectedResults{
183 << ExpectedResults{
154 Unit{QStringLiteral("nT"), true}, Unit{},
184 Unit{QStringLiteral("nT"), true}, Unit{},
155 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
185 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
156 QVector<double>{-2.71850, -2.52150}};
186 QVector<double>{-2.71850, -2.52150}};
157
187
158 // Invalid files
188 // Invalid files
159 QTest::newRow("Invalid file (unexisting file)") << QStringLiteral("UnexistingFile.txt")
189 QTest::newRow("Invalid file (unexisting file)") << QStringLiteral("UnexistingFile.txt")
160 << ExpectedResults{};
190 << ExpectedResults{};
161
191
162 QTest::newRow("Invalid file (file not found on server)") << QStringLiteral("FileNotFound.txt")
192 QTest::newRow("Invalid file (file not found on server)") << QStringLiteral("FileNotFound.txt")
163 << ExpectedResults{};
193 << ExpectedResults{};
164 }
194 }
165
195
166 void TestAmdaResultParser::testReadTxt()
196 void TestAmdaResultParser::testReadTxt()
167 {
197 {
168 QFETCH(QString, inputFileName);
198 QFETCH(QString, inputFileName);
169 QFETCH(ExpectedResults, expectedResults);
199 QFETCH(ExpectedResults, expectedResults);
170
200
171 // Parses file
201 // Parses file
172 auto filePath = inputFilePath(inputFileName);
202 auto filePath = inputFilePath(inputFileName);
173 auto results = AmdaResultParser::readTxt(filePath);
203 auto results = AmdaResultParser::readTxt(filePath);
174
204
175 // ///////////////// //
205 // ///////////////// //
176 // Validates results //
206 // Validates results //
177 // ///////////////// //
207 // ///////////////// //
178 expectedResults.validate(results);
208 expectedResults.validate(results);
179 }
209 }
180
210
181 QTEST_MAIN(TestAmdaResultParser)
211 QTEST_MAIN(TestAmdaResultParser)
182 #include "TestAmdaResultParser.moc"
212 #include "TestAmdaResultParser.moc"
General Comments 0
You need to be logged in to leave comments. Login now