##// END OF EJS Templates
Add impletation for displaying data that are already in cache when...
perrinel -
r573:575eda7156d0
parent child
Show More
@@ -1,211 +1,195
1 #include "Visualization/VisualizationGraphHelper.h"
1 #include "Visualization/VisualizationGraphHelper.h"
2 #include "Visualization/qcustomplot.h"
2 #include "Visualization/qcustomplot.h"
3
3
4 #include <Data/ScalarSeries.h>
4 #include <Data/ScalarSeries.h>
5
5
6 #include <Variable/Variable.h>
6 #include <Variable/Variable.h>
7
7
8 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
8 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
9
9
10 namespace {
10 namespace {
11
11
12 class SqpDataContainer : public QCPGraphDataContainer {
12 class SqpDataContainer : public QCPGraphDataContainer {
13 public:
13 public:
14 void appendGraphData(const QCPGraphData &data) { mData.append(data); }
14 void appendGraphData(const QCPGraphData &data) { mData.append(data); }
15 };
15 };
16
16
17
17
18 /// Format for datetimes on a axis
18 /// Format for datetimes on a axis
19 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
19 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
20
20
21 /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or
21 /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or
22 /// non-time data
22 /// non-time data
23 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
23 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
24 {
24 {
25 if (isTimeAxis) {
25 if (isTimeAxis) {
26 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
26 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
27 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
27 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
28 dateTicker->setDateTimeSpec(Qt::UTC);
28 dateTicker->setDateTimeSpec(Qt::UTC);
29
29
30 return dateTicker;
30 return dateTicker;
31 }
31 }
32 else {
32 else {
33 // default ticker
33 // default ticker
34 return QSharedPointer<QCPAxisTicker>::create();
34 return QSharedPointer<QCPAxisTicker>::create();
35 }
35 }
36 }
36 }
37
37
38 void updateScalarData(QCPAbstractPlottable *component, std::shared_ptr<ScalarSeries> scalarSeries,
38 void updateScalarData(QCPAbstractPlottable *component, std::shared_ptr<ScalarSeries> scalarSeries,
39 const SqpRange &dateTime)
39 const SqpRange &range)
40 {
40 {
41 qCDebug(LOG_VisualizationGraphHelper()) << "TORM: updateScalarData"
41 qCDebug(LOG_VisualizationGraphHelper()) << "TORM: updateScalarData"
42 << QThread::currentThread()->objectName();
42 << QThread::currentThread()->objectName();
43 if (auto qcpGraph = dynamic_cast<QCPGraph *>(component)) {
43 if (auto qcpGraph = dynamic_cast<QCPGraph *>(component)) {
44 scalarSeries->lockRead();
44 scalarSeries->lockRead();
45 {
45 {
46 // auto bounds = scalarSeries->subData(rang
46 auto sqpDataContainer = QSharedPointer<SqpDataContainer>::create();
47 // const auto &xData = scalarSeries->xAxisData()->cdata();
47 qcpGraph->setData(sqpDataContainer);
48 // const auto &valuesData = scalarSeries->valuesData()->cdata();
48 auto bounds = scalarSeries->subData(range.m_TStart, range.m_TEnd);
49
49 for (auto it = bounds.first; it != bounds.second; ++it) {
50 // auto xDataBegin = xData.cbegin();
50 sqpDataContainer->appendGraphData(QCPGraphData(it->x(), it->value()));
51 // auto xDataEnd = xData.cend();
51 }
52
53 // qCInfo(LOG_VisualizationGraphHelper()) << "TODEBUG: Current points in cache"
54 // << xData.count();
55
56 // auto sqpDataContainer = QSharedPointer<SqpDataContainer>::create();
57 // qcpGraph->setData(sqpDataContainer);
58
59 // auto lowerIt = std::lower_bound(xDataBegin, xDataEnd, dateTime.m_TStart);
60 // auto upperIt = std::upper_bound(xDataBegin, xDataEnd, dateTime.m_TEnd);
61 // auto distance = std::distance(xDataBegin, lowerIt);
62
63 // auto valuesDataIt = valuesData.cbegin() + distance;
64 // for (auto xAxisDataIt = lowerIt; xAxisDataIt != upperIt;
65 // ++xAxisDataIt, ++valuesDataIt) {
66 // sqpDataContainer->appendGraphData(QCPGraphData(*xAxisDataIt, *valuesDataIt));
67 // }
68
52
69 qCInfo(LOG_VisualizationGraphHelper()) << "TODEBUG: Current points displayed"
53 qCInfo(LOG_VisualizationGraphHelper()) << "TODEBUG: Current points displayed"
70 << sqpDataContainer->size();
54 << sqpDataContainer->size();
71 }
55 }
72 scalarSeries->unlock();
56 scalarSeries->unlock();
73
57
74
58
75 // Display all data
59 // Display all data
76 component->parentPlot()->replot();
60 component->parentPlot()->replot();
77 }
61 }
78 else {
62 else {
79 /// @todo DEBUG
63 /// @todo DEBUG
80 }
64 }
81 }
65 }
82
66
83 QCPAbstractPlottable *createScalarSeriesComponentV2(std::shared_ptr<ScalarSeries> scalarSeries,
67 QCPAbstractPlottable *createScalarSeriesComponentV2(std::shared_ptr<ScalarSeries> scalarSeries,
84 QCustomPlot &plot)
68 QCustomPlot &plot)
85 {
69 {
86 auto component = plot.addGraph();
70 auto component = plot.addGraph();
87
71
88 if (component) {
72 if (component) {
89 // Axes properties
73 // Axes properties
90 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
74 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
91 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
75 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
92
76
93 auto setAxisProperties = [](auto axis, const auto &unit) {
77 auto setAxisProperties = [](auto axis, const auto &unit) {
94 // label (unit name)
78 // label (unit name)
95 axis->setLabel(unit.m_Name);
79 axis->setLabel(unit.m_Name);
96
80
97 // ticker (depending on the type of unit)
81 // ticker (depending on the type of unit)
98 axis->setTicker(axisTicker(unit.m_TimeUnit));
82 axis->setTicker(axisTicker(unit.m_TimeUnit));
99 };
83 };
100 setAxisProperties(plot.xAxis, scalarSeries->xAxisUnit());
84 setAxisProperties(plot.xAxis, scalarSeries->xAxisUnit());
101 setAxisProperties(plot.yAxis, scalarSeries->valuesUnit());
85 setAxisProperties(plot.yAxis, scalarSeries->valuesUnit());
102 }
86 }
103 return component;
87 return component;
104 }
88 }
105
89
106 QCPAbstractPlottable *createScalarSeriesComponent(std::shared_ptr<ScalarSeries> scalarSeries,
90 QCPAbstractPlottable *createScalarSeriesComponent(std::shared_ptr<ScalarSeries> scalarSeries,
107 QCustomPlot &plot, const SqpRange &dateTime)
91 QCustomPlot &plot, const SqpRange &dateTime)
108 {
92 {
109 auto component = plot.addGraph();
93 auto component = plot.addGraph();
110
94
111 if (component) {
95 if (component) {
112 // // Graph data
96 // // Graph data
113 component->setData(scalarSeries->xAxisData()->data(), scalarSeries->valuesData()->data(),
97 component->setData(scalarSeries->xAxisData()->data(), scalarSeries->valuesData()->data(),
114 true);
98 true);
115
99
116 updateScalarData(component, scalarSeries, dateTime);
100 updateScalarData(component, scalarSeries, dateTime);
117
101
118 // Axes properties
102 // Axes properties
119 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
103 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
120 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
104 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
121
105
122 auto setAxisProperties = [](auto axis, const auto &unit) {
106 auto setAxisProperties = [](auto axis, const auto &unit) {
123 // label (unit name)
107 // label (unit name)
124 axis->setLabel(unit.m_Name);
108 axis->setLabel(unit.m_Name);
125
109
126 // ticker (depending on the type of unit)
110 // ticker (depending on the type of unit)
127 axis->setTicker(axisTicker(unit.m_TimeUnit));
111 axis->setTicker(axisTicker(unit.m_TimeUnit));
128 };
112 };
129 setAxisProperties(plot.xAxis, scalarSeries->xAxisUnit());
113 setAxisProperties(plot.xAxis, scalarSeries->xAxisUnit());
130 setAxisProperties(plot.yAxis, scalarSeries->valuesUnit());
114 setAxisProperties(plot.yAxis, scalarSeries->valuesUnit());
131
115
132 // Display all data
116 // Display all data
133 component->rescaleAxes();
117 component->rescaleAxes();
134 plot.replot();
118 plot.replot();
135 }
119 }
136 else {
120 else {
137 qCDebug(LOG_VisualizationGraphHelper())
121 qCDebug(LOG_VisualizationGraphHelper())
138 << QObject::tr("Can't create graph for the scalar series");
122 << QObject::tr("Can't create graph for the scalar series");
139 }
123 }
140
124
141 return component;
125 return component;
142 }
126 }
143
127
144 } // namespace
128 } // namespace
145
129
146 QVector<QCPAbstractPlottable *>
130 QVector<QCPAbstractPlottable *>
147 VisualizationGraphHelper::createV2(std::shared_ptr<Variable> variable, QCustomPlot &plot) noexcept
131 VisualizationGraphHelper::createV2(std::shared_ptr<Variable> variable, QCustomPlot &plot) noexcept
148 {
132 {
149 auto result = QVector<QCPAbstractPlottable *>{};
133 auto result = QVector<QCPAbstractPlottable *>{};
150
134
151 if (variable) {
135 if (variable) {
152 // Gets the data series of the variable to call the creation of the right components
136 // Gets the data series of the variable to call the creation of the right components
153 // according to its type
137 // according to its type
154 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(variable->dataSeries())) {
138 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(variable->dataSeries())) {
155 result.append(createScalarSeriesComponentV2(scalarSeries, plot));
139 result.append(createScalarSeriesComponentV2(scalarSeries, plot));
156 }
140 }
157 else {
141 else {
158 qCDebug(LOG_VisualizationGraphHelper())
142 qCDebug(LOG_VisualizationGraphHelper())
159 << QObject::tr("Can't create graph plottables : unmanaged data series type");
143 << QObject::tr("Can't create graph plottables : unmanaged data series type");
160 }
144 }
161 }
145 }
162 else {
146 else {
163 qCDebug(LOG_VisualizationGraphHelper())
147 qCDebug(LOG_VisualizationGraphHelper())
164 << QObject::tr("Can't create graph plottables : the variable is null");
148 << QObject::tr("Can't create graph plottables : the variable is null");
165 }
149 }
166
150
167 return result;
151 return result;
168 }
152 }
169
153
170 QVector<QCPAbstractPlottable *> VisualizationGraphHelper::create(std::shared_ptr<Variable> variable,
154 QVector<QCPAbstractPlottable *> VisualizationGraphHelper::create(std::shared_ptr<Variable> variable,
171 QCustomPlot &plot) noexcept
155 QCustomPlot &plot) noexcept
172 {
156 {
173 auto result = QVector<QCPAbstractPlottable *>{};
157 auto result = QVector<QCPAbstractPlottable *>{};
174
158
175 if (variable) {
159 if (variable) {
176 // Gets the data series of the variable to call the creation of the right components
160 // Gets the data series of the variable to call the creation of the right components
177 // according to its type
161 // according to its type
178 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(variable->dataSeries())) {
162 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(variable->dataSeries())) {
179 result.append(createScalarSeriesComponent(scalarSeries, plot, variable->range()));
163 result.append(createScalarSeriesComponent(scalarSeries, plot, variable->range()));
180 }
164 }
181 else {
165 else {
182 qCDebug(LOG_VisualizationGraphHelper())
166 qCDebug(LOG_VisualizationGraphHelper())
183 << QObject::tr("Can't create graph plottables : unmanaged data series type");
167 << QObject::tr("Can't create graph plottables : unmanaged data series type");
184 }
168 }
185 }
169 }
186 else {
170 else {
187 qCDebug(LOG_VisualizationGraphHelper())
171 qCDebug(LOG_VisualizationGraphHelper())
188 << QObject::tr("Can't create graph plottables : the variable is null");
172 << QObject::tr("Can't create graph plottables : the variable is null");
189 }
173 }
190
174
191 return result;
175 return result;
192 }
176 }
193
177
194 void VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *> plotableVect,
178 void VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *> plotableVect,
195 std::shared_ptr<IDataSeries> dataSeries,
179 std::shared_ptr<IDataSeries> dataSeries,
196 const SqpRange &dateTime)
180 const SqpRange &dateTime)
197 {
181 {
198 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
182 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
199 if (plotableVect.size() == 1) {
183 if (plotableVect.size() == 1) {
200 updateScalarData(plotableVect.at(0), scalarSeries, dateTime);
184 updateScalarData(plotableVect.at(0), scalarSeries, dateTime);
201 }
185 }
202 else {
186 else {
203 qCCritical(LOG_VisualizationGraphHelper()) << QObject::tr(
187 qCCritical(LOG_VisualizationGraphHelper()) << QObject::tr(
204 "Can't update Data of a scalarSeries because there is not only one component "
188 "Can't update Data of a scalarSeries because there is not only one component "
205 "associated");
189 "associated");
206 }
190 }
207 }
191 }
208 else {
192 else {
209 /// @todo DEBUG
193 /// @todo DEBUG
210 }
194 }
211 }
195 }
@@ -1,310 +1,310
1 #include "AmdaResultParser.h"
1 #include "AmdaResultParser.h"
2
2
3 #include <Data/ScalarSeries.h>
3 #include <Data/ScalarSeries.h>
4 #include <Data/VectorSeries.h>
4 #include <Data/VectorSeries.h>
5
5
6 #include <QObject>
6 #include <QObject>
7 #include <QtTest>
7 #include <QtTest>
8
8
9 namespace {
9 namespace {
10
10
11 /// Path for the tests
11 /// Path for the tests
12 const auto TESTS_RESOURCES_PATH
12 const auto TESTS_RESOURCES_PATH
13 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaResultParser"}.absoluteFilePath();
13 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaResultParser"}.absoluteFilePath();
14
14
15 QDateTime dateTime(int year, int month, int day, int hours, int minutes, int seconds)
15 QDateTime dateTime(int year, int month, int day, int hours, int minutes, int seconds)
16 {
16 {
17 return QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC};
17 return QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC};
18 }
18 }
19
19
20 /// Compares two vectors that can potentially contain NaN values
20 /// Compares two vectors that can potentially contain NaN values
21 bool compareVectors(const QVector<double> &v1, const QVector<double> &v2)
21 bool compareVectors(const QVector<double> &v1, const QVector<double> &v2)
22 {
22 {
23 if (v1.size() != v2.size()) {
23 if (v1.size() != v2.size()) {
24 return false;
24 return false;
25 }
25 }
26
26
27 auto result = true;
27 auto result = true;
28 auto v2It = v2.cbegin();
28 auto v2It = v2.cbegin();
29 for (auto v1It = v1.cbegin(), v1End = v1.cend(); v1It != v1End && result; ++v1It, ++v2It) {
29 for (auto v1It = v1.cbegin(), v1End = v1.cend(); v1It != v1End && result; ++v1It, ++v2It) {
30 auto v1Value = *v1It;
30 auto v1Value = *v1It;
31 auto v2Value = *v2It;
31 auto v2Value = *v2It;
32
32
33 // If v1 is NaN, v2 has to be NaN too
33 // If v1 is NaN, v2 has to be NaN too
34 result = std::isnan(v1Value) ? std::isnan(v2Value) : (v1Value == v2Value);
34 result = std::isnan(v1Value) ? std::isnan(v2Value) : (v1Value == v2Value);
35 }
35 }
36
36
37 return result;
37 return result;
38 }
38 }
39
39
40 bool compareVectors(const QVector<QVector<double> > &v1, const QVector<QVector<double> > &v2)
40 bool compareVectors(const QVector<QVector<double> > &v1, const QVector<QVector<double> > &v2)
41 {
41 {
42 if (v1.size() != v2.size()) {
42 if (v1.size() != v2.size()) {
43 return false;
43 return false;
44 }
44 }
45
45
46 auto result = true;
46 auto result = true;
47 for (auto i = 0; i < v1.size() && result; ++i) {
47 for (auto i = 0; i < v1.size() && result; ++i) {
48 result &= compareVectors(v1.at(i), v2.at(i));
48 result &= compareVectors(v1.at(i), v2.at(i));
49 }
49 }
50
50
51 return result;
51 return result;
52 }
52 }
53
53
54 QVector<QVector<double> > valuesData(const ArrayData<1> &arrayData)
54 QVector<QVector<double> > valuesData(const ArrayData<1> &arrayData)
55 {
55 {
56 return QVector<QVector<double> >{arrayData.data()};
56 return QVector<QVector<double> >{arrayData.data()};
57 }
57 }
58
58
59 QVector<QVector<double> > valuesData(const ArrayData<2> &arrayData)
59 QVector<QVector<double> > valuesData(const ArrayData<2> &arrayData)
60 {
60 {
61 return arrayData.data();
61 return arrayData.data();
62 }
62 }
63
63
64
64
65 QString inputFilePath(const QString &inputFileName)
65 QString inputFilePath(const QString &inputFileName)
66 {
66 {
67 return QFileInfo{TESTS_RESOURCES_PATH, inputFileName}.absoluteFilePath();
67 return QFileInfo{TESTS_RESOURCES_PATH, inputFileName}.absoluteFilePath();
68 }
68 }
69
69
70 template <typename T>
70 template <typename T>
71 struct ExpectedResults {
71 struct ExpectedResults {
72 explicit ExpectedResults() = default;
72 explicit ExpectedResults() = default;
73
73
74 explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector<QDateTime> &xAxisData,
74 explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector<QDateTime> &xAxisData,
75 QVector<double> valuesData)
75 QVector<double> valuesData)
76 : ExpectedResults(xAxisUnit, valuesUnit, xAxisData,
76 : ExpectedResults(xAxisUnit, valuesUnit, xAxisData,
77 QVector<QVector<double> >{std::move(valuesData)})
77 QVector<QVector<double> >{std::move(valuesData)})
78 {
78 {
79 }
79 }
80
80
81 /// Ctor with QVector<QDateTime> as x-axis data. Datetimes are converted to doubles
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,
82 explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector<QDateTime> &xAxisData,
83 QVector<QVector<double> > valuesData)
83 QVector<QVector<double> > valuesData)
84 : m_ParsingOK{true},
84 : m_ParsingOK{true},
85 m_XAxisUnit{xAxisUnit},
85 m_XAxisUnit{xAxisUnit},
86 m_ValuesUnit{valuesUnit},
86 m_ValuesUnit{valuesUnit},
87 m_XAxisData{},
87 m_XAxisData{},
88 m_ValuesData{std::move(valuesData)}
88 m_ValuesData{std::move(valuesData)}
89 {
89 {
90 // Converts QVector<QDateTime> to QVector<double>
90 // Converts QVector<QDateTime> to QVector<double>
91 std::transform(xAxisData.cbegin(), xAxisData.cend(), std::back_inserter(m_XAxisData),
91 std::transform(xAxisData.cbegin(), xAxisData.cend(), std::back_inserter(m_XAxisData),
92 [](const auto &dateTime) { return dateTime.toMSecsSinceEpoch() / 1000.; });
92 [](const auto &dateTime) { return dateTime.toMSecsSinceEpoch() / 1000.; });
93 }
93 }
94
94
95 /**
95 /**
96 * Validates a DataSeries compared to the expected results
96 * Validates a DataSeries compared to the expected results
97 * @param results the DataSeries to validate
97 * @param results the DataSeries to validate
98 */
98 */
99 void validate(std::shared_ptr<IDataSeries> results)
99 void validate(std::shared_ptr<IDataSeries> results)
100 {
100 {
101 if (m_ParsingOK) {
101 if (m_ParsingOK) {
102 auto dataSeries = dynamic_cast<T *>(results.get());
102 auto dataSeries = dynamic_cast<T *>(results.get());
103 QVERIFY(dataSeries != nullptr);
103 QVERIFY(dataSeries != nullptr);
104
104
105 // Checks units
105 // Checks units
106 QVERIFY(dataSeries->xAxisUnit() == m_XAxisUnit);
106 QVERIFY(dataSeries->xAxisUnit() == m_XAxisUnit);
107 QVERIFY(dataSeries->valuesUnit() == m_ValuesUnit);
107 QVERIFY(dataSeries->valuesUnit() == m_ValuesUnit);
108
108
109 // Checks values : as the vectors can potentially contain NaN values, we must use a
109 // Checks values : as the vectors can potentially contain NaN values, we must use a
110 // custom vector comparison method
110 // custom vector comparison method
111 QVERIFY(compareVectors(dataSeries->xAxisData()->data(), m_XAxisData));
111 QVERIFY(compareVectors(dataSeries->xAxisData()->data(), m_XAxisData));
112 QVERIFY(compareVectors(valuesData(*dataSeries->valuesData()), m_ValuesData));
112 QVERIFY(compareVectors(valuesData(*dataSeries->valuesData()), m_ValuesData));
113 }
113 }
114 else {
114 else {
115 QVERIFY(results == nullptr);
115 QVERIFY(results == nullptr);
116 }
116 }
117 }
117 }
118
118
119 // Parsing was successfully completed
119 // Parsing was successfully completed
120 bool m_ParsingOK{false};
120 bool m_ParsingOK{false};
121 // Expected x-axis unit
121 // Expected x-axis unit
122 Unit m_XAxisUnit{};
122 Unit m_XAxisUnit{};
123 // Expected values unit
123 // Expected values unit
124 Unit m_ValuesUnit{};
124 Unit m_ValuesUnit{};
125 // Expected x-axis data
125 // Expected x-axis data
126 QVector<double> m_XAxisData{};
126 QVector<double> m_XAxisData{};
127 // Expected values data
127 // Expected values data
128 QVector<QVector<double> > m_ValuesData{};
128 QVector<QVector<double> > m_ValuesData{};
129 };
129 };
130
130
131 } // namespace
131 } // namespace
132
132
133 Q_DECLARE_METATYPE(ExpectedResults<ScalarSeries>)
133 Q_DECLARE_METATYPE(ExpectedResults<ScalarSeries>)
134 Q_DECLARE_METATYPE(ExpectedResults<VectorSeries>)
134 Q_DECLARE_METATYPE(ExpectedResults<VectorSeries>)
135
135
136 class TestAmdaResultParser : public QObject {
136 class TestAmdaResultParser : public QObject {
137 Q_OBJECT
137 Q_OBJECT
138 private:
138 private:
139 template <typename T>
139 template <typename T>
140 void testReadDataStructure()
140 void testReadDataStructure()
141 {
141 {
142 // ////////////// //
142 // ////////////// //
143 // Test structure //
143 // Test structure //
144 // ////////////// //
144 // ////////////// //
145
145
146 // Name of TXT file to read
146 // Name of TXT file to read
147 QTest::addColumn<QString>("inputFileName");
147 QTest::addColumn<QString>("inputFileName");
148 // Expected results
148 // Expected results
149 QTest::addColumn<ExpectedResults<T> >("expectedResults");
149 QTest::addColumn<ExpectedResults<T> >("expectedResults");
150 }
150 }
151
151
152 template <typename T>
152 template <typename T>
153 void testRead(AmdaResultParser::ValueType valueType)
153 void testRead(AmdaResultParser::ValueType valueType)
154 {
154 {
155 QFETCH(QString, inputFileName);
155 QFETCH(QString, inputFileName);
156 QFETCH(ExpectedResults<T>, expectedResults);
156 QFETCH(ExpectedResults<T>, expectedResults);
157
157
158 // Parses file
158 // Parses file
159 auto filePath = inputFilePath(inputFileName);
159 auto filePath = inputFilePath(inputFileName);
160 auto results = AmdaResultParser::readTxt(filePath, valueType);
160 auto results = AmdaResultParser::readTxt(filePath, valueType);
161
161
162 // ///////////////// //
162 // ///////////////// //
163 // Validates results //
163 // Validates results //
164 // ///////////////// //
164 // ///////////////// //
165 expectedResults.validate(results);
165 expectedResults.validate(results);
166 }
166 }
167
167
168 private slots:
168 private slots:
169 /// Input test data
169 /// Input test data
170 /// @sa testReadScalarTxt()
170 /// @sa testReadScalarTxt()
171 void testReadScalarTxt_data();
171 void testReadScalarTxt_data();
172
172
173 /// Tests parsing scalar series of a TXT file
173 /// Tests parsing scalar series of a TXT file
174 void testReadScalarTxt();
174 void testReadScalarTxt();
175
175
176 /// Input test data
176 /// Input test data
177 /// @sa testReadVectorTxt()
177 /// @sa testReadVectorTxt()
178 void testReadVectorTxt_data();
178 void testReadVectorTxt_data();
179
179
180 /// Tests parsing vector series of a TXT file
180 /// Tests parsing vector series of a TXT file
181 void testReadVectorTxt();
181 void testReadVectorTxt();
182 };
182 };
183
183
184 void TestAmdaResultParser::testReadScalarTxt_data()
184 void TestAmdaResultParser::testReadScalarTxt_data()
185 {
185 {
186 testReadDataStructure<ScalarSeries>();
186 testReadDataStructure<ScalarSeries>();
187
187
188 // ////////// //
188 // ////////// //
189 // Test cases //
189 // Test cases //
190 // ////////// //
190 // ////////// //
191
191
192 // Valid files
192 // Valid files
193 QTest::newRow("Valid file")
193 QTest::newRow("Valid file")
194 << QStringLiteral("ValidScalar1.txt")
194 << QStringLiteral("ValidScalar1.txt")
195 << ExpectedResults<ScalarSeries>{
195 << ExpectedResults<ScalarSeries>{
196 Unit{QStringLiteral("nT"), true}, Unit{},
196 Unit{QStringLiteral("nT"), true}, Unit{},
197 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
197 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
198 dateTime(2013, 9, 23, 9, 2, 30), dateTime(2013, 9, 23, 9, 3, 30),
198 dateTime(2013, 9, 23, 9, 2, 30), dateTime(2013, 9, 23, 9, 3, 30),
199 dateTime(2013, 9, 23, 9, 4, 30), dateTime(2013, 9, 23, 9, 5, 30),
199 dateTime(2013, 9, 23, 9, 4, 30), dateTime(2013, 9, 23, 9, 5, 30),
200 dateTime(2013, 9, 23, 9, 6, 30), dateTime(2013, 9, 23, 9, 7, 30),
200 dateTime(2013, 9, 23, 9, 6, 30), dateTime(2013, 9, 23, 9, 7, 30),
201 dateTime(2013, 9, 23, 9, 8, 30), dateTime(2013, 9, 23, 9, 9, 30)},
201 dateTime(2013, 9, 23, 9, 8, 30), dateTime(2013, 9, 23, 9, 9, 30)},
202 QVector<double>{-2.83950, -2.71850, -2.52150, -2.57633, -2.58050, -2.48325, -2.63025,
202 QVector<double>{-2.83950, -2.71850, -2.52150, -2.57633, -2.58050, -2.48325, -2.63025,
203 -2.55800, -2.43250, -2.42200}};
203 -2.55800, -2.43250, -2.42200}};
204
204
205 QTest::newRow("Valid file (value of first line is invalid but it is converted to NaN")
205 QTest::newRow("Valid file (value of first line is invalid but it is converted to NaN")
206 << QStringLiteral("WrongValue.txt")
206 << QStringLiteral("WrongValue.txt")
207 << ExpectedResults<ScalarSeries>{
207 << ExpectedResults<ScalarSeries>{
208 Unit{QStringLiteral("nT"), true}, Unit{},
208 Unit{QStringLiteral("nT"), true}, Unit{},
209 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
209 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
210 dateTime(2013, 9, 23, 9, 2, 30)},
210 dateTime(2013, 9, 23, 9, 2, 30)},
211 QVector<double>{std::numeric_limits<double>::quiet_NaN(), -2.71850, -2.52150}};
211 QVector<double>{std::numeric_limits<double>::quiet_NaN(), -2.71850, -2.52150}};
212
212
213 QTest::newRow("Valid file that contains NaN values")
213 QTest::newRow("Valid file that contains NaN values")
214 << QStringLiteral("NaNValue.txt")
214 << QStringLiteral("NaNValue.txt")
215 << ExpectedResults<ScalarSeries>{
215 << ExpectedResults<ScalarSeries>{
216 Unit{QStringLiteral("nT"), true}, Unit{},
216 Unit{QStringLiteral("nT"), true}, Unit{},
217 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
217 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
218 dateTime(2013, 9, 23, 9, 2, 30)},
218 dateTime(2013, 9, 23, 9, 2, 30)},
219 QVector<double>{std::numeric_limits<double>::quiet_NaN(), -2.71850, -2.52150}};
219 QVector<double>{std::numeric_limits<double>::quiet_NaN(), -2.71850, -2.52150}};
220
220
221 // Valid files but with some invalid lines (wrong unit, wrong values, etc.)
221 // Valid files but with some invalid lines (wrong unit, wrong values, etc.)
222 QTest::newRow("No unit file") << QStringLiteral("NoUnit.txt")
222 QTest::newRow("No unit file") << QStringLiteral("NoUnit.txt")
223 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral(""), true},
223 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral(""), true},
224 Unit{}, QVector<QDateTime>{},
224 Unit{}, QVector<QDateTime>{},
225 QVector<double>{}};
225 QVector<double>{}};
226 QTest::newRow("Wrong unit file")
226 QTest::newRow("Wrong unit file")
227 << QStringLiteral("WrongUnit.txt")
227 << QStringLiteral("WrongUnit.txt")
228 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral(""), true}, Unit{},
228 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral(""), true}, Unit{},
229 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30),
229 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30),
230 dateTime(2013, 9, 23, 9, 1, 30),
230 dateTime(2013, 9, 23, 9, 1, 30),
231 dateTime(2013, 9, 23, 9, 2, 30)},
231 dateTime(2013, 9, 23, 9, 2, 30)},
232 QVector<double>{-2.83950, -2.71850, -2.52150}};
232 QVector<double>{-2.83950, -2.71850, -2.52150}};
233
233
234 QTest::newRow("Wrong results file (date of first line is invalid")
234 QTest::newRow("Wrong results file (date of first line is invalid")
235 << QStringLiteral("WrongDate.txt")
235 << QStringLiteral("WrongDate.txt")
236 << ExpectedResults<ScalarSeries>{
236 << ExpectedResults<ScalarSeries>{
237 Unit{QStringLiteral("nT"), true}, Unit{},
237 Unit{QStringLiteral("nT"), true}, Unit{},
238 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
238 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
239 QVector<double>{-2.71850, -2.52150}};
239 QVector<double>{-2.71850, -2.52150}};
240
240
241 QTest::newRow("Wrong results file (too many values for first line")
241 QTest::newRow("Wrong results file (too many values for first line")
242 << QStringLiteral("TooManyValues.txt")
242 << QStringLiteral("TooManyValues.txt")
243 << ExpectedResults<ScalarSeries>{
243 << ExpectedResults<ScalarSeries>{
244 Unit{QStringLiteral("nT"), true}, Unit{},
244 Unit{QStringLiteral("nT"), true}, Unit{},
245 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
245 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
246 QVector<double>{-2.71850, -2.52150}};
246 QVector<double>{-2.71850, -2.52150}};
247
247
248 QTest::newRow("Wrong results file (x of first line is NaN")
248 QTest::newRow("Wrong results file (x of first line is NaN")
249 << QStringLiteral("NaNX.txt")
249 << QStringLiteral("NaNX.txt")
250 << ExpectedResults<ScalarSeries>{
250 << ExpectedResults<ScalarSeries>{
251 Unit{QStringLiteral("nT"), true}, Unit{},
251 Unit{QStringLiteral("nT"), true}, Unit{},
252 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
252 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
253 QVector<double>{-2.71850, -2.52150}};
253 QVector<double>{-2.71850, -2.52150}};
254
254
255 QTest::newRow("Invalid file type (vector)")
255 QTest::newRow("Invalid file type (vector)")
256 << QStringLiteral("ValidVector1.txt")
256 << QStringLiteral("ValidVector1.txt")
257 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral("nT"), true}, Unit{},
257 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral("nT"), true}, Unit{},
258 QVector<QDateTime>{}, QVector<double>{}};
258 QVector<QDateTime>{}, QVector<double>{}};
259
259
260 // Invalid files
260 // Invalid files
261 QTest::newRow("Invalid file (unexisting file)")
261 QTest::newRow("Invalid file (unexisting file)") << QStringLiteral("UnexistingFile.txt")
262 << QStringLiteral("UnexistingFile.txt") << ExpectedResults<ScalarSeries>{};
262 << ExpectedResults<ScalarSeries>{};
263
263
264 QTest::newRow("Invalid file (file not found on server)")
264 QTest::newRow("Invalid file (file not found on server)") << QStringLiteral("FileNotFound.txt")
265 << QStringLiteral("FileNotFound.txt") << ExpectedResults<ScalarSeries>{};
265 << ExpectedResults<ScalarSeries>{};
266 }
266 }
267
267
268 void TestAmdaResultParser::testReadScalarTxt()
268 void TestAmdaResultParser::testReadScalarTxt()
269 {
269 {
270 testRead<ScalarSeries>(AmdaResultParser::ValueType::SCALAR);
270 testRead<ScalarSeries>(AmdaResultParser::ValueType::SCALAR);
271 }
271 }
272
272
273 void TestAmdaResultParser::testReadVectorTxt_data()
273 void TestAmdaResultParser::testReadVectorTxt_data()
274 {
274 {
275 testReadDataStructure<VectorSeries>();
275 testReadDataStructure<VectorSeries>();
276
276
277 // ////////// //
277 // ////////// //
278 // Test cases //
278 // Test cases //
279 // ////////// //
279 // ////////// //
280
280
281 // Valid files
281 // Valid files
282 QTest::newRow("Valid file")
282 QTest::newRow("Valid file")
283 << QStringLiteral("ValidVector1.txt")
283 << QStringLiteral("ValidVector1.txt")
284 << ExpectedResults<VectorSeries>{
284 << ExpectedResults<VectorSeries>{
285 Unit{QStringLiteral("nT"), true}, Unit{},
285 Unit{QStringLiteral("nT"), true}, Unit{},
286 QVector<QDateTime>{dateTime(2013, 7, 2, 9, 13, 50), dateTime(2013, 7, 2, 9, 14, 6),
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),
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),
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),
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)},
290 dateTime(2013, 7, 2, 9, 15, 58), dateTime(2013, 7, 2, 9, 16, 14)},
291 QVector<QVector<double> >{
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},
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},
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}}};
294 {0.058, 0.496, 1.018, 1.485, 1.662, 1.505, 1.168, 1.244, 1.15, 1.358}}};
295
295
296 // Valid files but with some invalid lines (wrong unit, wrong values, etc.)
296 // Valid files but with some invalid lines (wrong unit, wrong values, etc.)
297 QTest::newRow("Invalid file type (scalar)")
297 QTest::newRow("Invalid file type (scalar)")
298 << QStringLiteral("ValidScalar1.txt")
298 << QStringLiteral("ValidScalar1.txt")
299 << ExpectedResults<VectorSeries>{Unit{QStringLiteral("nT"), true}, Unit{},
299 << ExpectedResults<VectorSeries>{Unit{QStringLiteral("nT"), true}, Unit{},
300 QVector<QDateTime>{},
300 QVector<QDateTime>{},
301 QVector<QVector<double> >{{}, {}, {}}};
301 QVector<QVector<double> >{{}, {}, {}}};
302 }
302 }
303
303
304 void TestAmdaResultParser::testReadVectorTxt()
304 void TestAmdaResultParser::testReadVectorTxt()
305 {
305 {
306 testRead<VectorSeries>(AmdaResultParser::ValueType::VECTOR);
306 testRead<VectorSeries>(AmdaResultParser::ValueType::VECTOR);
307 }
307 }
308
308
309 QTEST_MAIN(TestAmdaResultParser)
309 QTEST_MAIN(TestAmdaResultParser)
310 #include "TestAmdaResultParser.moc"
310 #include "TestAmdaResultParser.moc"
General Comments 0
You need to be logged in to leave comments. Login now