##// END OF EJS Templates
Improve cosinus tests with:...
perrinel -
r808:5353ec1e417b
parent child
Show More
@@ -1,36 +1,41
1 #ifndef SCIQLOP_COSINUSPROVIDER_H
1 #ifndef SCIQLOP_COSINUSPROVIDER_H
2 #define SCIQLOP_COSINUSPROVIDER_H
2 #define SCIQLOP_COSINUSPROVIDER_H
3
3
4 #include "MockPluginGlobal.h"
4 #include "MockPluginGlobal.h"
5
5
6 #include <Data/IDataProvider.h>
6 #include <Data/IDataProvider.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9 #include <QUuid>
9 #include <QUuid>
10
10
11 #include <QHash>
11 #include <QHash>
12 Q_DECLARE_LOGGING_CATEGORY(LOG_CosinusProvider)
12 Q_DECLARE_LOGGING_CATEGORY(LOG_CosinusProvider)
13
13
14 /**
14 /**
15 * @brief The CosinusProvider class is an example of how a data provider can generate data
15 * @brief The CosinusProvider class is an example of how a data provider can generate data
16 */
16 */
17 class SCIQLOP_MOCKPLUGIN_EXPORT CosinusProvider : public IDataProvider {
17 class SCIQLOP_MOCKPLUGIN_EXPORT CosinusProvider : public IDataProvider {
18 public:
18 public:
19 std::shared_ptr<IDataProvider> clone() const override;
19 std::shared_ptr<IDataProvider> clone() const override;
20
20
21 /// @sa IDataProvider::requestDataLoading(). The current impl isn't thread safe.
21 /// @sa IDataProvider::requestDataLoading(). The current impl isn't thread safe.
22 void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters) override;
22 void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters) override;
23
23
24
24
25 /// @sa IDataProvider::requestDataAborting(). The current impl isn't thread safe.
25 /// @sa IDataProvider::requestDataAborting(). The current impl isn't thread safe.
26 void requestDataAborting(QUuid acqIdentifier) override;
26 void requestDataAborting(QUuid acqIdentifier) override;
27
27
28
28
29 /// Provide data
30 std::shared_ptr<IDataSeries> provideDataSeries(const SqpRange &dataRangeRequested,
31 const QVariantHash &data);
32
33
29 private:
34 private:
30 std::shared_ptr<IDataSeries>
35 std::shared_ptr<IDataSeries>
31 retrieveData(QUuid acqIdentifier, const SqpRange &dataRangeRequested, const QVariantHash &data);
36 retrieveData(QUuid acqIdentifier, const SqpRange &dataRangeRequested, const QVariantHash &data);
32
37
33 QHash<QUuid, bool> m_VariableToEnableProvider;
38 QHash<QUuid, bool> m_VariableToEnableProvider;
34 };
39 };
35
40
36 #endif // SCIQLOP_COSINUSPROVIDER_H
41 #endif // SCIQLOP_COSINUSPROVIDER_H
@@ -1,201 +1,213
1 #include "CosinusProvider.h"
1 #include "CosinusProvider.h"
2 #include "MockDefs.h"
2 #include "MockDefs.h"
3
3
4 #include <Data/DataProviderParameters.h>
4 #include <Data/DataProviderParameters.h>
5 #include <Data/ScalarSeries.h>
5 #include <Data/ScalarSeries.h>
6 #include <Data/VectorSeries.h>
6 #include <Data/VectorSeries.h>
7
7
8 #include <cmath>
8 #include <cmath>
9
9
10 #include <QFuture>
10 #include <QFuture>
11 #include <QThread>
11 #include <QThread>
12 #include <QtConcurrent/QtConcurrent>
12 #include <QtConcurrent/QtConcurrent>
13
13
14 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
14 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
15
15
16 namespace {
16 namespace {
17
17
18 /// Abstract cosinus type
18 /// Abstract cosinus type
19 struct ICosinusType {
19 struct ICosinusType {
20 virtual ~ICosinusType() = default;
20 virtual ~ICosinusType() = default;
21 /// @return the number of components generated for the type
21 /// @return the number of components generated for the type
22 virtual int componentCount() const = 0;
22 virtual int componentCount() const = 0;
23 /// @return the data series created for the type
23 /// @return the data series created for the type
24 virtual std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
24 virtual std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
25 std::vector<double> valuesData,
25 std::vector<double> valuesData,
26 Unit xAxisUnit,
26 Unit xAxisUnit,
27 Unit valuesUnit) const = 0;
27 Unit valuesUnit) const = 0;
28 };
28 };
29
29
30 struct ScalarCosinus : public ICosinusType {
30 struct ScalarCosinus : public ICosinusType {
31 int componentCount() const override { return 1; }
31 int componentCount() const override { return 1; }
32
32
33 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
33 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
34 std::vector<double> valuesData, Unit xAxisUnit,
34 std::vector<double> valuesData, Unit xAxisUnit,
35 Unit valuesUnit) const override
35 Unit valuesUnit) const override
36 {
36 {
37 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
37 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
38 xAxisUnit, valuesUnit);
38 xAxisUnit, valuesUnit);
39 }
39 }
40 };
40 };
41 struct VectorCosinus : public ICosinusType {
41 struct VectorCosinus : public ICosinusType {
42 int componentCount() const override { return 3; }
42 int componentCount() const override { return 3; }
43
43
44 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
44 std::shared_ptr<IDataSeries> createDataSeries(std::vector<double> xAxisData,
45 std::vector<double> valuesData, Unit xAxisUnit,
45 std::vector<double> valuesData, Unit xAxisUnit,
46 Unit valuesUnit) const override
46 Unit valuesUnit) const override
47 {
47 {
48 return std::make_shared<VectorSeries>(std::move(xAxisData), std::move(valuesData),
48 return std::make_shared<VectorSeries>(std::move(xAxisData), std::move(valuesData),
49 xAxisUnit, valuesUnit);
49 xAxisUnit, valuesUnit);
50 }
50 }
51 };
51 };
52
52
53 /// Converts string to cosinus type
53 /// Converts string to cosinus type
54 /// @return the cosinus type if the string could be converted, nullptr otherwise
54 /// @return the cosinus type if the string could be converted, nullptr otherwise
55 std::unique_ptr<ICosinusType> cosinusType(const QString &type) noexcept
55 std::unique_ptr<ICosinusType> cosinusType(const QString &type) noexcept
56 {
56 {
57 if (type.compare(QStringLiteral("scalar"), Qt::CaseInsensitive) == 0) {
57 if (type.compare(QStringLiteral("scalar"), Qt::CaseInsensitive) == 0) {
58 return std::make_unique<ScalarCosinus>();
58 return std::make_unique<ScalarCosinus>();
59 }
59 }
60 else if (type.compare(QStringLiteral("vector"), Qt::CaseInsensitive) == 0) {
60 else if (type.compare(QStringLiteral("vector"), Qt::CaseInsensitive) == 0) {
61 return std::make_unique<VectorCosinus>();
61 return std::make_unique<VectorCosinus>();
62 }
62 }
63 else {
63 else {
64 return nullptr;
64 return nullptr;
65 }
65 }
66 }
66 }
67
67
68 } // namespace
68 } // namespace
69
69
70 std::shared_ptr<IDataProvider> CosinusProvider::clone() const
70 std::shared_ptr<IDataProvider> CosinusProvider::clone() const
71 {
71 {
72 // No copy is made in clone
72 // No copy is made in clone
73 return std::make_shared<CosinusProvider>();
73 return std::make_shared<CosinusProvider>();
74 }
74 }
75
75
76 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier,
76 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid acqIdentifier,
77 const SqpRange &dataRangeRequested,
77 const SqpRange &dataRangeRequested,
78 const QVariantHash &data)
78 const QVariantHash &data)
79 {
79 {
80 // TODO: Add Mutex
80 // TODO: Add Mutex
81 auto dataIndex = 0;
81 auto dataIndex = 0;
82
82
83 // Retrieves cosinus type
83 // Retrieves cosinus type
84 auto typeVariant = data.value(COSINUS_TYPE_KEY, COSINUS_TYPE_DEFAULT_VALUE);
84 auto typeVariant = data.value(COSINUS_TYPE_KEY, COSINUS_TYPE_DEFAULT_VALUE);
85 if (!typeVariant.canConvert<QString>()) {
85 if (!typeVariant.canConvert<QString>()) {
86 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: invalid type");
86 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: invalid type");
87 return nullptr;
87 return nullptr;
88 }
88 }
89
89
90 auto type = cosinusType(typeVariant.toString());
90 auto type = cosinusType(typeVariant.toString());
91 if (!type) {
91 if (!type) {
92 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: unknown type");
92 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: unknown type");
93 return nullptr;
93 return nullptr;
94 }
94 }
95
95
96 // Retrieves frequency
96 // Retrieves frequency
97 auto freqVariant = data.value(COSINUS_FREQUENCY_KEY, COSINUS_FREQUENCY_DEFAULT_VALUE);
97 auto freqVariant = data.value(COSINUS_FREQUENCY_KEY, COSINUS_FREQUENCY_DEFAULT_VALUE);
98 if (!freqVariant.canConvert<double>()) {
98 if (!freqVariant.canConvert<double>()) {
99 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: invalid frequency");
99 qCCritical(LOG_CosinusProvider()) << tr("Can't retrieve data: invalid frequency");
100 return nullptr;
100 return nullptr;
101 }
101 }
102
102
103 // Gets the timerange from the parameters
103 // Gets the timerange from the parameters
104 double freq = freqVariant.toDouble();
104 double freq = freqVariant.toDouble();
105 double start = std::ceil(dataRangeRequested.m_TStart * freq);
105 double start = std::ceil(dataRangeRequested.m_TStart * freq);
106 double end = std::floor(dataRangeRequested.m_TEnd * freq);
106 double end = std::floor(dataRangeRequested.m_TEnd * freq);
107
107
108 // We assure that timerange is valid
108 // We assure that timerange is valid
109 if (end < start) {
109 if (end < start) {
110 std::swap(start, end);
110 std::swap(start, end);
111 }
111 }
112
112
113 // Generates scalar series containing cosinus values (one value per second, end value is
113 // Generates scalar series containing cosinus values (one value per second, end value is
114 // included)
114 // included)
115 auto dataCount = end - start + 1;
115 auto dataCount = end - start + 1;
116
116
117 // Number of components (depending on the cosinus type)
117 // Number of components (depending on the cosinus type)
118 auto componentCount = type->componentCount();
118 auto componentCount = type->componentCount();
119
119
120 auto xAxisData = std::vector<double>{};
120 auto xAxisData = std::vector<double>{};
121 xAxisData.resize(dataCount);
121 xAxisData.resize(dataCount);
122
122
123 auto valuesData = std::vector<double>{};
123 auto valuesData = std::vector<double>{};
124 valuesData.resize(dataCount * componentCount);
124 valuesData.resize(dataCount * componentCount);
125
125
126 int progress = 0;
126 int progress = 0;
127 auto progressEnd = dataCount;
127 auto progressEnd = dataCount;
128 for (auto time = start; time <= end; ++time, ++dataIndex) {
128 for (auto time = start; time <= end; ++time, ++dataIndex) {
129 auto it = m_VariableToEnableProvider.find(acqIdentifier);
129 auto it = m_VariableToEnableProvider.find(acqIdentifier);
130 if (it != m_VariableToEnableProvider.end() && it.value()) {
130 if (it != m_VariableToEnableProvider.end() && it.value()) {
131 const auto timeOnFreq = time / freq;
131 const auto timeOnFreq = time / freq;
132
132
133 xAxisData[dataIndex] = timeOnFreq;
133 xAxisData[dataIndex] = timeOnFreq;
134
134
135 // Generates all components' values
135 // Generates all components' values
136 // Example: for a vector, values will be : cos(x), cos(x)/2, cos(x)/3
136 // Example: for a vector, values will be : cos(x), cos(x)/2, cos(x)/3
137 auto value = std::cos(timeOnFreq);
137 auto value = std::cos(timeOnFreq);
138 for (auto i = 0; i < componentCount; ++i) {
138 for (auto i = 0; i < componentCount; ++i) {
139 valuesData[componentCount * dataIndex + i] = value / (i + 1);
139 valuesData[componentCount * dataIndex + i] = value / (i + 1);
140 }
140 }
141
141
142 // progression
142 // progression
143 int currentProgress = (time - start) * 100.0 / progressEnd;
143 int currentProgress = (time - start) * 100.0 / progressEnd;
144 if (currentProgress != progress) {
144 if (currentProgress != progress) {
145 progress = currentProgress;
145 progress = currentProgress;
146
146
147 emit dataProvidedProgress(acqIdentifier, progress);
147 emit dataProvidedProgress(acqIdentifier, progress);
148 qCInfo(LOG_CosinusProvider()) << "TORM: CosinusProvider::retrieveData"
148 qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::retrieveData"
149 << QThread::currentThread()->objectName() << progress;
149 << QThread::currentThread()->objectName()
150 << progress;
150 // NOTE: Try to use multithread if possible
151 // NOTE: Try to use multithread if possible
151 }
152 }
152 }
153 }
153 else {
154 else {
154 if (!it.value()) {
155 if (!it.value()) {
155 qCDebug(LOG_CosinusProvider())
156 qCDebug(LOG_CosinusProvider())
156 << "CosinusProvider::retrieveData: ARRET De l'acquisition detectΓ©"
157 << "CosinusProvider::retrieveData: ARRET De l'acquisition detectΓ©"
157 << end - time;
158 << end - time;
158 }
159 }
159 }
160 }
160 }
161 }
161 if (progress != 100) {
162 if (progress != 100) {
162 // We can close progression beacause all data has been retrieved
163 // We can close progression beacause all data has been retrieved
163 emit dataProvidedProgress(acqIdentifier, 100);
164 emit dataProvidedProgress(acqIdentifier, 100);
164 }
165 }
165 return type->createDataSeries(std::move(xAxisData), std::move(valuesData),
166 return type->createDataSeries(std::move(xAxisData), std::move(valuesData),
166 Unit{QStringLiteral("t"), true}, Unit{});
167 Unit{QStringLiteral("t"), true}, Unit{});
167 }
168 }
168
169
169 void CosinusProvider::requestDataLoading(QUuid acqIdentifier,
170 void CosinusProvider::requestDataLoading(QUuid acqIdentifier,
170 const DataProviderParameters &parameters)
171 const DataProviderParameters &parameters)
171 {
172 {
172 // TODO: Add Mutex
173 // TODO: Add Mutex
173 m_VariableToEnableProvider[acqIdentifier] = true;
174 m_VariableToEnableProvider[acqIdentifier] = true;
174 qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::requestDataLoading"
175 qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::requestDataLoading"
175 << QThread::currentThread()->objectName();
176 << QThread::currentThread()->objectName();
176 // NOTE: Try to use multithread if possible
177 // NOTE: Try to use multithread if possible
177 const auto times = parameters.m_Times;
178 const auto times = parameters.m_Times;
178
179
179 for (const auto &dateTime : qAsConst(times)) {
180 for (const auto &dateTime : qAsConst(times)) {
180 if (m_VariableToEnableProvider[acqIdentifier]) {
181 if (m_VariableToEnableProvider[acqIdentifier]) {
181 auto scalarSeries = this->retrieveData(acqIdentifier, dateTime, parameters.m_Data);
182 auto scalarSeries = this->retrieveData(acqIdentifier, dateTime, parameters.m_Data);
182 qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::dataProvided";
183 qCDebug(LOG_CosinusProvider()) << "TORM: CosinusProvider::dataProvided";
183 emit dataProvided(acqIdentifier, scalarSeries, dateTime);
184 emit dataProvided(acqIdentifier, scalarSeries, dateTime);
184 }
185 }
185 }
186 }
186 }
187 }
187
188
188 void CosinusProvider::requestDataAborting(QUuid acqIdentifier)
189 void CosinusProvider::requestDataAborting(QUuid acqIdentifier)
189 {
190 {
190 // TODO: Add Mutex
191 // TODO: Add Mutex
191 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataAborting" << acqIdentifier
192 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataAborting" << acqIdentifier
192 << QThread::currentThread()->objectName();
193 << QThread::currentThread()->objectName();
193 auto it = m_VariableToEnableProvider.find(acqIdentifier);
194 auto it = m_VariableToEnableProvider.find(acqIdentifier);
194 if (it != m_VariableToEnableProvider.end()) {
195 if (it != m_VariableToEnableProvider.end()) {
195 it.value() = false;
196 it.value() = false;
196 }
197 }
197 else {
198 else {
198 qCWarning(LOG_CosinusProvider())
199 qCWarning(LOG_CosinusProvider())
199 << tr("Aborting progression of inexistant identifier detected !!!");
200 << tr("Aborting progression of inexistant identifier detected !!!");
200 }
201 }
201 }
202 }
203
204 std::shared_ptr<IDataSeries> CosinusProvider::provideDataSeries(const SqpRange &dataRangeRequested,
205 const QVariantHash &data)
206 {
207 auto uid = QUuid::createUuid();
208 m_VariableToEnableProvider[uid] = true;
209 auto dataSeries = this->retrieveData(uid, dataRangeRequested, data);
210
211 m_VariableToEnableProvider.remove(uid);
212 return dataSeries;
213 }
@@ -1,193 +1,194
1 #include "CosinusProvider.h"
1 #include "CosinusProvider.h"
2 #include "MockDefs.h"
2 #include "MockDefs.h"
3
3
4 #include <Data/DataProviderParameters.h>
4 #include <Data/DataProviderParameters.h>
5 #include <Data/ScalarSeries.h>
5 #include <Data/ScalarSeries.h>
6 #include <SqpApplication.h>
6 #include <SqpApplication.h>
7 #include <Time/TimeController.h>
7 #include <Time/TimeController.h>
8 #include <Variable/Variable.h>
8 #include <Variable/Variable.h>
9 #include <Variable/VariableController.h>
9 #include <Variable/VariableController.h>
10
10
11 #include <QObject>
11 #include <QObject>
12 #include <QtTest>
12 #include <QtTest>
13
13
14 #include <cmath>
14 #include <cmath>
15 #include <memory>
15 #include <memory>
16
16
17 namespace {
17 namespace {
18
18
19 /// Path for the tests
19 /// Path for the tests
20 const auto TESTS_RESOURCES_PATH = QFileInfo{
20 const auto TESTS_RESOURCES_PATH = QFileInfo{
21 QString{MOCKPLUGIN_TESTS_RESOURCES_DIR},
21 QString{MOCKPLUGIN_TESTS_RESOURCES_DIR},
22 "TestCosinusAcquisition"}.absoluteFilePath();
22 "TestCosinusAcquisition"}.absoluteFilePath();
23
23
24 /// Format of dates in data files
24 /// Format of dates in data files
25 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz");
25 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz");
26
26
27 /// Delay after each operation on the variable before validating it (in ms)
28 const auto OPERATION_DELAY = 250;
29
30 /**
27 /**
31 * Verifies that the data in the candidate series are identical to the data in the reference series
28 * Verifies that the data in the candidate series are identical to the data in the reference series
32 * in a specific range
29 * in a specific range
33 * @param candidate the candidate data series
30 * @param candidate the candidate data series
34 * @param range the range to check
31 * @param range the range to check
35 * @param reference the reference data series
32 * @param reference the reference data series
36 * @return true if the data of the candidate series and the reference series are identical in the
33 * @return true if the data of the candidate series and the reference series are identical in the
37 * range, false otherwise
34 * range, false otherwise
38 */
35 */
39 bool checkDataSeries(std::shared_ptr<IDataSeries> candidate, const SqpRange &range,
36 bool checkDataSeries(std::shared_ptr<IDataSeries> candidate, const SqpRange &range,
40 std::shared_ptr<IDataSeries> reference)
37 std::shared_ptr<IDataSeries> reference)
41 {
38 {
42 if (candidate == nullptr || reference == nullptr) {
39 if (candidate == nullptr || reference == nullptr) {
43 return candidate == reference;
40 return candidate == reference;
44 }
41 }
45
42
46 auto referenceIt = reference->xAxisRange(range.m_TStart, range.m_TEnd);
43 auto referenceIt = reference->xAxisRange(range.m_TStart, range.m_TEnd);
47
44
45 qInfo() << "candidateSize" << std::distance(candidate->cbegin(), candidate->cend());
46 qInfo() << "refSize" << std::distance(referenceIt.first, referenceIt.second);
47
48 return std::equal(candidate->cbegin(), candidate->cend(), referenceIt.first, referenceIt.second,
48 return std::equal(candidate->cbegin(), candidate->cend(), referenceIt.first, referenceIt.second,
49 [](const auto &it1, const auto &it2) {
49 [](const auto &it1, const auto &it2) {
50 // - milliseconds precision for time
50 // - milliseconds precision for time
51 // - 1e-6 precision for value
51 // - 1e-6 precision for value
52 return std::abs(it1.x() - it2.x()) < 1e-3
52 return std::abs(it1.x() - it2.x()) < 1e-3
53 && std::abs(it1.value() - it2.value()) < 1e-6;
53 && std::abs(it1.value() - it2.value()) < 1e-6;
54 });
54 });
55 }
55 }
56
56
57 /// Generates the data series from the reading of a data stream
58 std::shared_ptr<IDataSeries> readDataStream(QTextStream &stream)
59 {
60 std::vector<double> xAxisData, valuesData;
61
62 QString line{};
63 while (stream.readLineInto(&line)) {
64 // Separates date (x-axis data) to value data
65 auto splitLine = line.split('\t');
66 if (splitLine.size() == 2) {
67 // Converts datetime to double
68 auto dateTime = QDateTime::fromString(splitLine[0], DATETIME_FORMAT);
69 dateTime.setTimeSpec(Qt::UTC);
70 xAxisData.push_back(DateUtils::secondsSinceEpoch(dateTime));
71
72 valuesData.push_back(splitLine[1].toDouble());
73 }
74 }
75
76 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
77 Unit{{}, true}, Unit{});
78 }
79
80 } // namespace
57 } // namespace
81
58
82 /**
59 /**
83 * @brief The TestCosinusAcquisition class tests acquisition in SciQlop (operations like zooms in,
60 * @brief The TestCosinusAcquisition class tests acquisition in SciQlop (operations like zooms in,
84 * zooms out, pans) of data from CosinusProvider
61 * zooms out, pans) of data from CosinusProvider
85 * @sa CosinusProvider
62 * @sa CosinusProvider
86 */
63 */
87 class TestCosinusAcquisition : public QObject {
64 class TestCosinusAcquisition : public QObject {
88 Q_OBJECT
65 Q_OBJECT
89
66
90 private slots:
67 private slots:
91 /// Input data for @sa testAcquisition()
68 /// Input data for @sa testAcquisition()
92 void testAcquisition_data();
69 void testAcquisition_data();
93 void testAcquisition();
70 void testAcquisition();
94 };
71 };
95
72
96 void TestCosinusAcquisition::testAcquisition_data()
73 void TestCosinusAcquisition::testAcquisition_data()
97 {
74 {
98 // ////////////// //
75 // ////////////// //
99 // Test structure //
76 // Test structure //
100 // ////////////// //
77 // ////////////// //
101
78
102 QTest::addColumn<QString>("dataFilename"); // File containing expected data of acquisitions
79 QTest::addColumn<SqpRange>("referenceRange"); // Range for generating reference series
103 QTest::addColumn<SqpRange>("initialRange"); // First acquisition
80 QTest::addColumn<SqpRange>("initialRange"); // First acquisition
81 QTest::addColumn<int>("operationDelay"); // Acquisitions to make
104 QTest::addColumn<std::vector<SqpRange> >("operations"); // Acquisitions to make
82 QTest::addColumn<std::vector<SqpRange> >("operations"); // Acquisitions to make
105
83
106 // ////////// //
84 // ////////// //
107 // Test cases //
85 // Test cases //
108 // ////////// //
86 // ////////// //
109
87
110 auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) {
88 auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) {
111 return DateUtils::secondsSinceEpoch(
89 return DateUtils::secondsSinceEpoch(
112 QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC});
90 QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC});
113 };
91 };
114
92
115 QTest::newRow("cosinus")
93 QTest::newRow("cosinus")
116 << "Cosinus_100Hz_20170101_1200_20170101_1300.txt"
94 << SqpRange{dateTime(2017, 1, 1, 12, 0, 0), dateTime(2017, 1, 1, 13, 0, 0)}
117 << SqpRange{dateTime(2017, 1, 1, 12, 30, 0), dateTime(2017, 1, 1, 12, 35, 1)}
95 << SqpRange{dateTime(2017, 1, 1, 12, 30, 0), dateTime(2017, 1, 1, 12, 35, 1)} << 250
118 << std::vector<SqpRange>{
96 << std::vector<SqpRange>{
119 // Pan (jump) left
97 // Pan (jump) left
120 SqpRange{dateTime(2017, 1, 1, 12, 45, 0), dateTime(2017, 1, 1, 12, 50, 0)},
98 SqpRange{dateTime(2017, 1, 1, 12, 45, 0), dateTime(2017, 1, 1, 12, 50, 0)},
121 // Pan (jump) right
99 // Pan (jump) right
122 SqpRange{dateTime(2017, 1, 1, 12, 15, 0), dateTime(2017, 1, 1, 12, 20, 0)},
100 SqpRange{dateTime(2017, 1, 1, 12, 15, 0), dateTime(2017, 1, 1, 12, 20, 0)},
123 // Pan (overlay) right
101 // Pan (overlay) right
124 SqpRange{dateTime(2017, 1, 1, 12, 14, 0), dateTime(2017, 1, 1, 12, 19, 0)},
102 SqpRange{dateTime(2017, 1, 1, 12, 14, 0), dateTime(2017, 1, 1, 12, 19, 0)},
125 // Pan (overlay) left
103 // Pan (overlay) left
126 SqpRange{dateTime(2017, 1, 1, 12, 15, 0), dateTime(2017, 1, 1, 12, 20, 0)},
104 SqpRange{dateTime(2017, 1, 1, 12, 15, 0), dateTime(2017, 1, 1, 12, 20, 0)},
127 // Pan (overlay) left
105 // Pan (overlay) left
128 SqpRange{dateTime(2017, 1, 1, 12, 16, 0), dateTime(2017, 1, 1, 12, 21, 0)},
106 SqpRange{dateTime(2017, 1, 1, 12, 16, 0), dateTime(2017, 1, 1, 12, 21, 0)},
129 // Zoom in
107 // Zoom in
130 SqpRange{dateTime(2017, 1, 1, 12, 17, 30), dateTime(2017, 1, 1, 12, 19, 30)},
108 SqpRange{dateTime(2017, 1, 1, 12, 17, 30), dateTime(2017, 1, 1, 12, 19, 30)},
131 // Zoom out
109 // Zoom out
132 SqpRange{dateTime(2017, 1, 1, 12, 12, 30), dateTime(2017, 1, 1, 12, 24, 30)}};
110 SqpRange{dateTime(2017, 1, 1, 12, 12, 30), dateTime(2017, 1, 1, 12, 24, 30)}};
111
112 QTest::newRow("cosinus_big")
113 << SqpRange{dateTime(2017, 1, 1, 1, 0, 0), dateTime(2017, 1, 5, 13, 0, 0)}
114 << SqpRange{dateTime(2017, 1, 2, 6, 30, 0), dateTime(2017, 1, 2, 18, 30, 0)} << 5000
115 << std::vector<SqpRange>{
116 // Pan (jump) left
117 SqpRange{dateTime(2017, 1, 1, 13, 30, 0), dateTime(2017, 1, 1, 18, 30, 0)},
118 // Pan (jump) right
119 SqpRange{dateTime(2017, 1, 3, 4, 30, 0), dateTime(2017, 1, 3, 10, 30, 0)},
120 // Pan (overlay) right
121 SqpRange{dateTime(2017, 1, 3, 8, 30, 0), dateTime(2017, 1, 3, 12, 30, 0)},
122 // Pan (overlay) left
123 SqpRange{dateTime(2017, 1, 2, 8, 30, 0), dateTime(2017, 1, 3, 10, 30, 0)},
124 // Pan (overlay) left
125 SqpRange{dateTime(2017, 1, 1, 12, 30, 0), dateTime(2017, 1, 3, 5, 30, 0)},
126 // Zoom in
127 SqpRange{dateTime(2017, 1, 2, 2, 30, 0), dateTime(2017, 1, 2, 8, 30, 0)},
128 // Zoom out
129 SqpRange{dateTime(2017, 1, 1, 14, 30, 0), dateTime(2017, 1, 3, 12, 30, 0)}};
133 }
130 }
134
131
135 void TestCosinusAcquisition::testAcquisition()
132 void TestCosinusAcquisition::testAcquisition()
136 {
133 {
137 // Retrieves data file
134 // Retrieves reference range
138 QFETCH(QString, dataFilename);
135 QFETCH(SqpRange, referenceRange);
139
136 CosinusProvider referenceProvider{};
140 auto dataFilePath = QFileInfo{TESTS_RESOURCES_PATH, dataFilename}.absoluteFilePath();
137 auto dataSeries = referenceProvider.provideDataSeries(
141 QFile dataFile{dataFilePath};
138 referenceRange, {{COSINUS_TYPE_KEY, "scalar"}, {COSINUS_FREQUENCY_KEY, 100.}});
142
139
143 if (dataFile.open(QFile::ReadOnly)) {
140 auto end = dataSeries->cend() - 1;
144 // Generates data series to compare with
141 qInfo() << dataSeries->nbPoints() << dataSeries->cbegin()->x() << end->x();
145 QTextStream dataStream{&dataFile};
146 auto dataSeries = readDataStream(dataStream);
147
142
148 /// Lambda used to validate a variable at each step
143 /// Lambda used to validate a variable at each step
149 auto validateVariable = [dataSeries](std::shared_ptr<Variable> variable,
144 auto validateVariable
150 const SqpRange &range) {
145 = [dataSeries](std::shared_ptr<Variable> variable, const SqpRange &range) {
151 // Checks that the variable's range has changed
146 // Checks that the variable's range has changed
152 QCOMPARE(variable->range(), range);
147 QCOMPARE(variable->range(), range);
153
148
154 // Checks the variable's data series
149 // Checks the variable's data series
155 QVERIFY(checkDataSeries(variable->dataSeries(), variable->cacheRange(), dataSeries));
150 QVERIFY(checkDataSeries(variable->dataSeries(), variable->cacheRange(), dataSeries));
156 };
151 };
157
152
158 // Creates variable
153 // Creates variable
159 QFETCH(SqpRange, initialRange);
154 QFETCH(SqpRange, initialRange);
160 sqpApp->timeController().onTimeToUpdate(initialRange);
155 sqpApp->timeController().onTimeToUpdate(initialRange);
161 auto provider = std::make_shared<CosinusProvider>();
156 auto provider = std::make_shared<CosinusProvider>();
162 auto variable = sqpApp->variableController().createVariable(
157 auto variable = sqpApp->variableController().createVariable(
163 "MMS", {{COSINUS_TYPE_KEY, "scalar"}, {COSINUS_FREQUENCY_KEY, 100.}}, provider);
158 "MMS", {{COSINUS_TYPE_KEY, "scalar"}, {COSINUS_FREQUENCY_KEY, 100.}}, provider);
164
159
165 QTest::qWait(OPERATION_DELAY);
160 QFETCH(int, operationDelay);
161 QTest::qWait(operationDelay);
166 validateVariable(variable, initialRange);
162 validateVariable(variable, initialRange);
167
163
168 // Makes operations on the variable
164 // Makes operations on the variable
169 QFETCH(std::vector<SqpRange>, operations);
165 QFETCH(std::vector<SqpRange>, operations);
170 for (const auto &operation : operations) {
166 for (const auto &operation : operations) {
171 // Asks request on the variable and waits during its execution
167 // Asks request on the variable and waits during its execution
172 sqpApp->variableController().onRequestDataLoading({variable}, operation,
168 sqpApp->variableController().onRequestDataLoading({variable}, operation, variable->range(),
173 variable->range(), true);
169 true);
174
170
175 QTest::qWait(OPERATION_DELAY);
171 QTest::qWait(operationDelay);
176 validateVariable(variable, operation);
172 validateVariable(variable, operation);
177 }
173 }
174
175
176 for (const auto &operation : operations) {
177 // Asks request on the variable and waits during its execution
178 sqpApp->variableController().onRequestDataLoading({variable}, operation, variable->range(),
179 true);
178 }
180 }
179 else {
181 QTest::qWait(operationDelay);
180 QFAIL("Can't read input data file");
182 validateVariable(variable, operations.back());
181 }
182 }
183 }
183
184
184 int main(int argc, char *argv[])
185 int main(int argc, char *argv[])
185 {
186 {
186 SqpApplication app{argc, argv};
187 SqpApplication app{argc, argv};
187 app.setAttribute(Qt::AA_Use96Dpi, true);
188 app.setAttribute(Qt::AA_Use96Dpi, true);
188 TestCosinusAcquisition testObject{};
189 TestCosinusAcquisition testObject{};
189 QTEST_SET_MAIN_SOURCE_PATH
190 QTEST_SET_MAIN_SOURCE_PATH
190 return QTest::qExec(&testObject, argc, argv);
191 return QTest::qExec(&testObject, argc, argv);
191 }
192 }
192
193
193 #include "TestCosinusAcquisition.moc"
194 #include "TestCosinusAcquisition.moc"
General Comments 0
You need to be logged in to leave comments. Login now