TestVariableSync.cpp
192 lines
| 5.4 KiB
| text/x-c
|
CppLexer
|
r712 | #include <QObject> | ||
#include <QtTest> | ||||
|
r714 | #include <memory> | ||
|
r715 | #include <Data/DataProviderParameters.h> | ||
#include <Data/IDataProvider.h> | ||||
#include <Data/ScalarSeries.h> | ||||
|
r713 | #include <Variable/Variable.h> | ||
#include <Variable/VariableController.h> | ||||
|
r714 | #include <Variable/VariableModel.h> | ||
|
r713 | namespace { | ||
|
r715 | /** | ||
* Generates values according to a range. The value generated for a time t is the number of seconds | ||||
* of difference between t and a reference value (which is midnight -> 00:00:00) | ||||
* | ||||
* Example: For a range between 00:00:10 and 00:00:20, the generated values are | ||||
* {10,11,12,13,14,15,16,17,18,19,20} | ||||
*/ | ||||
std::vector<double> values(const SqpRange &range) | ||||
{ | ||||
QTime referenceTime{0, 0}; | ||||
std::vector<double> result{}; | ||||
for (auto i = range.m_TStart; i <= range.m_TEnd; ++i) { | ||||
auto time = DateUtils::dateTime(i).time(); | ||||
result.push_back(referenceTime.secsTo(time)); | ||||
} | ||||
return result; | ||||
} | ||||
/// Provider used for the tests | ||||
class TestProvider : public IDataProvider { | ||||
std::shared_ptr<IDataProvider> clone() const { return std::make_shared<TestProvider>(); } | ||||
void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters ¶meters) override | ||||
{ | ||||
const auto &ranges = parameters.m_Times; | ||||
for (const auto &range : ranges) { | ||||
// Generates data series | ||||
auto valuesData = values(range); | ||||
std::vector<double> xAxisData{}; | ||||
for (auto i = range.m_TStart; i <= range.m_TEnd; ++i) { | ||||
xAxisData.push_back(i); | ||||
} | ||||
auto dataSeries = std::make_shared<ScalarSeries>( | ||||
std::move(xAxisData), std::move(valuesData), Unit{"t", true}, Unit{}); | ||||
emit dataProvided(acqIdentifier, dataSeries, range); | ||||
} | ||||
} | ||||
void requestDataAborting(QUuid acqIdentifier) override | ||||
{ | ||||
// Does nothing | ||||
} | ||||
}; | ||||
|
r713 | /** | ||
* Interface representing an operation performed on a variable controller. | ||||
* This interface is used in tests to apply a set of operations and check the status of the | ||||
* controller after each operation | ||||
*/ | ||||
struct IOperation { | ||||
virtual ~IOperation() = default; | ||||
/// Executes the operation on the variable controller | ||||
virtual void exec(VariableController &variableController) const = 0; | ||||
}; | ||||
|
r714 | /** | ||
*Variable creation operation in the controller | ||||
*/ | ||||
struct Create : public IOperation { | ||||
explicit Create(int index) : m_Index{index} {} | ||||
void exec(VariableController &variableController) const override | ||||
{ | ||||
auto variable = variableController.createVariable(QString::number(m_Index), {}, | ||||
std::make_unique<TestProvider>()); | ||||
} | ||||
int m_Index; ///< The index of the variable to create in the controller | ||||
}; | ||||
/** | ||||
* Variable move/shift operation in the controller | ||||
*/ | ||||
struct Move : public IOperation { | ||||
explicit Move(int index, const SqpRange &newRange, bool shift = false) | ||||
: m_Index{index}, m_NewRange{newRange}, m_Shift{shift} | ||||
{ | ||||
} | ||||
void exec(VariableController &variableController) const override | ||||
{ | ||||
if (auto variable = variableController.variableModel()->variable(m_Index)) { | ||||
variableController.onRequestDataLoading({variable}, m_NewRange, variable->range(), | ||||
!m_Shift); | ||||
} | ||||
} | ||||
int m_Index; ///< The index of the variable to move | ||||
SqpRange m_NewRange; ///< The new range of the variable | ||||
bool m_Shift; ///< Performs a shift ( | ||||
}; | ||||
/** | ||||
* Variable synchronization/desynchronization operation in the controller | ||||
*/ | ||||
struct Synchronize : public IOperation { | ||||
explicit Synchronize(int index, QUuid syncId, bool synchronize = true) | ||||
: m_Index{index}, m_SyncId{syncId}, m_Synchronize{synchronize} | ||||
{ | ||||
} | ||||
void exec(VariableController &variableController) const override | ||||
{ | ||||
if (auto variable = variableController.variableModel()->variable(m_Index)) { | ||||
if (m_Synchronize) { | ||||
variableController.onAddSynchronized(variable, m_SyncId); | ||||
} | ||||
else { | ||||
variableController.desynchronize(variable, m_SyncId); | ||||
} | ||||
} | ||||
} | ||||
int m_Index; ///< The index of the variable to sync/desync | ||||
QUuid m_SyncId; ///< The synchronization group of the variable | ||||
bool m_Synchronize; ///< Performs sync or desync operation | ||||
}; | ||||
|
r713 | /** | ||
* Test Iteration | ||||
* | ||||
* A test iteration includes an operation to be performed, and a set of expected ranges after each | ||||
* operation. Each range is tested after the operation to ensure that: | ||||
* - the range of the variable is the expected range | ||||
* - the data of the variable are those generated for the expected range | ||||
*/ | ||||
struct Iteration { | ||||
std::shared_ptr<IOperation> m_Operation; ///< Operation to perform | ||||
std::map<int, SqpRange> m_ExpectedRanges; ///< Expected ranges (by variable index) | ||||
}; | ||||
using Iterations = std::vector<Iteration>; | ||||
} // namespace | ||||
Q_DECLARE_METATYPE(Iterations) | ||||
|
r712 | class TestVariableSync : public QObject { | ||
Q_OBJECT | ||||
private slots: | ||||
/// Input data for @sa testSync() | ||||
void testSync_data(); | ||||
/// Tests synchronization between variables through several operations | ||||
void testSync(); | ||||
}; | ||||
void TestVariableSync::testSync_data() | ||||
{ | ||||
// ////////////// // | ||||
// Test structure // | ||||
// ////////////// // | ||||
/// @todo | ||||
// ////////// // | ||||
// Test cases // | ||||
// ////////// // | ||||
/// @todo | ||||
} | ||||
void TestVariableSync::testSync() | ||||
{ | ||||
/// @todo | ||||
} | ||||
QTEST_MAIN(TestVariableSync) | ||||
#include "TestVariableSync.moc" | ||||