From a7ded9f58584b939e3574d4bf3927078fc114cd4 2017-08-17 08:28:45 From: Alexandre Leroux Date: 2017-08-17 08:28:45 Subject: [PATCH] Adds unit tests for reading vectors in AMDA --- diff --git a/core/include/Data/ArrayData.h b/core/include/Data/ArrayData.h index 9f5a240..18eb70c 100644 --- a/core/include/Data/ArrayData.h +++ b/core/include/Data/ArrayData.h @@ -290,6 +290,21 @@ public: return m_Data[0]; } + // ///////////// // + // 2-dim methods // + // ///////////// // + + /** + * @return the data + * @remarks this method is only available for a two-dimensional ArrayData + */ + template > + DataContainer data() const noexcept + { + QReadLocker locker{&m_Lock}; + return m_Data; + } + private: DataContainer m_Data; mutable QReadWriteLock m_Lock; diff --git a/plugins/amda/tests-resources/TestAmdaResultParser/ValidVector1.txt b/plugins/amda/tests-resources/TestAmdaResultParser/ValidVector1.txt new file mode 100644 index 0000000..cadabb8 --- /dev/null +++ b/plugins/amda/tests-resources/TestAmdaResultParser/ValidVector1.txt @@ -0,0 +1,12 @@ +#Time Format : YYYY-MM-DDThh:mm:ss.mls +#imf - Type : Local Parameter @ CDPP/AMDA - Name : imf_gse - Units : nT - Size : 3 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim +2013-07-02T09:13:50.000 -0.332000 3.20600 0.0580000 +2013-07-02T09:14:06.000 -1.01100 2.99900 0.496000 +2013-07-02T09:14:22.000 -1.45700 2.78500 1.01800 +2013-07-02T09:14:38.000 -1.29300 2.73600 1.48500 +2013-07-02T09:14:54.000 -1.21700 2.61200 1.66200 +2013-07-02T09:15:10.000 -1.44300 2.56400 1.50500 +2013-07-02T09:15:26.000 -1.27800 2.89200 1.16800 +2013-07-02T09:15:42.000 -1.20200 2.86200 1.24400 +2013-07-02T09:15:58.000 -1.22000 2.85900 1.15000 +2013-07-02T09:16:14.000 -1.25900 2.76400 1.35800 \ No newline at end of file diff --git a/plugins/amda/tests/TestAmdaResultParser.cpp b/plugins/amda/tests/TestAmdaResultParser.cpp index 9b21c44..13241c2 100644 --- a/plugins/amda/tests/TestAmdaResultParser.cpp +++ b/plugins/amda/tests/TestAmdaResultParser.cpp @@ -1,6 +1,7 @@ #include "AmdaResultParser.h" #include +#include #include #include @@ -11,6 +12,11 @@ namespace { const auto TESTS_RESOURCES_PATH = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaResultParser"}.absoluteFilePath(); +QDateTime dateTime(int year, int month, int day, int hours, int minutes, int seconds) +{ + return QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC}; +} + /// Compares two vectors that can potentially contain NaN values bool compareVectors(const QVector &v1, const QVector &v2) { @@ -31,17 +37,50 @@ bool compareVectors(const QVector &v1, const QVector &v2) return result; } +bool compareVectors(const QVector > &v1, const QVector > &v2) +{ + if (v1.size() != v2.size()) { + return false; + } + + auto result = true; + for (auto i = 0; i < v1.size() && result; ++i) { + result &= compareVectors(v1.at(i), v2.at(i)); + } + + return result; +} + +QVector > valuesData(const ArrayData<1> &arrayData) +{ + return QVector >{arrayData.data()}; +} + +QVector > valuesData(const ArrayData<2> &arrayData) +{ + return arrayData.data(); +} + + QString inputFilePath(const QString &inputFileName) { return QFileInfo{TESTS_RESOURCES_PATH, inputFileName}.absoluteFilePath(); } +template struct ExpectedResults { explicit ExpectedResults() = default; - /// Ctor with QVector as x-axis data. Datetimes are converted to doubles explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector &xAxisData, QVector valuesData) + : ExpectedResults(xAxisUnit, valuesUnit, xAxisData, + QVector >{std::move(valuesData)}) + { + } + + /// Ctor with QVector as x-axis data. Datetimes are converted to doubles + explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector &xAxisData, + QVector > valuesData) : m_ParsingOK{true}, m_XAxisUnit{xAxisUnit}, m_ValuesUnit{valuesUnit}, @@ -60,17 +99,17 @@ struct ExpectedResults { void validate(std::shared_ptr results) { if (m_ParsingOK) { - auto scalarSeries = dynamic_cast(results.get()); - QVERIFY(scalarSeries != nullptr); + auto dataSeries = dynamic_cast(results.get()); + QVERIFY(dataSeries != nullptr); // Checks units - QVERIFY(scalarSeries->xAxisUnit() == m_XAxisUnit); - QVERIFY(scalarSeries->valuesUnit() == m_ValuesUnit); + QVERIFY(dataSeries->xAxisUnit() == m_XAxisUnit); + QVERIFY(dataSeries->valuesUnit() == m_ValuesUnit); // Checks values : as the vectors can potentially contain NaN values, we must use a // custom vector comparison method - QVERIFY(compareVectors(scalarSeries->xAxisData()->data(), m_XAxisData)); - QVERIFY(compareVectors(scalarSeries->valuesData()->data(), m_ValuesData)); + QVERIFY(compareVectors(dataSeries->xAxisData()->data(), m_XAxisData)); + QVERIFY(compareVectors(valuesData(*dataSeries->valuesData()), m_ValuesData)); } else { QVERIFY(results == nullptr); @@ -86,47 +125,74 @@ struct ExpectedResults { // Expected x-axis data QVector m_XAxisData{}; // Expected values data - QVector m_ValuesData{}; + QVector > m_ValuesData{}; }; } // namespace -Q_DECLARE_METATYPE(ExpectedResults) +Q_DECLARE_METATYPE(ExpectedResults) +Q_DECLARE_METATYPE(ExpectedResults) class TestAmdaResultParser : public QObject { Q_OBJECT +private: + template + void testReadDataStructure() + { + // ////////////// // + // Test structure // + // ////////////// // + + // Name of TXT file to read + QTest::addColumn("inputFileName"); + // Expected results + QTest::addColumn >("expectedResults"); + } + + template + void testRead(AmdaResultParser::ValueType valueType) + { + QFETCH(QString, inputFileName); + QFETCH(ExpectedResults, expectedResults); + + // Parses file + auto filePath = inputFilePath(inputFileName); + auto results = AmdaResultParser::readTxt(filePath, valueType); + + // ///////////////// // + // Validates results // + // ///////////////// // + expectedResults.validate(results); + } + private slots: /// Input test data - /// @sa testTxtJson() - void testReadTxt_data(); + /// @sa testReadScalarTxt() + void testReadScalarTxt_data(); - /// Tests parsing of a TXT file - void testReadTxt(); + /// Tests parsing scalar series of a TXT file + void testReadScalarTxt(); + + /// Input test data + /// @sa testReadVectorTxt() + void testReadVectorTxt_data(); + + /// Tests parsing vector series of a TXT file + void testReadVectorTxt(); }; -void TestAmdaResultParser::testReadTxt_data() +void TestAmdaResultParser::testReadScalarTxt_data() { - // ////////////// // - // Test structure // - // ////////////// // - - // Name of TXT file to read - QTest::addColumn("inputFileName"); - // Expected results - QTest::addColumn("expectedResults"); + testReadDataStructure(); // ////////// // // Test cases // // ////////// // - auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) { - return QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC}; - }; - // Valid files QTest::newRow("Valid file") << QStringLiteral("ValidScalar1.txt") - << ExpectedResults{ + << ExpectedResults{ Unit{QStringLiteral("nT"), true}, Unit{}, QVector{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30), dateTime(2013, 9, 23, 9, 3, 30), @@ -138,7 +204,7 @@ void TestAmdaResultParser::testReadTxt_data() QTest::newRow("Valid file (value of first line is invalid but it is converted to NaN") << QStringLiteral("WrongValue.txt") - << ExpectedResults{ + << ExpectedResults{ Unit{QStringLiteral("nT"), true}, Unit{}, QVector{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)}, @@ -146,7 +212,7 @@ void TestAmdaResultParser::testReadTxt_data() QTest::newRow("Valid file that contains NaN values") << QStringLiteral("NaNValue.txt") - << ExpectedResults{ + << ExpectedResults{ Unit{QStringLiteral("nT"), true}, Unit{}, QVector{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)}, @@ -154,58 +220,90 @@ void TestAmdaResultParser::testReadTxt_data() // Valid files but with some invalid lines (wrong unit, wrong values, etc.) QTest::newRow("No unit file") << QStringLiteral("NoUnit.txt") - << ExpectedResults{Unit{QStringLiteral(""), true}, Unit{}, - QVector{}, QVector{}}; + << ExpectedResults{Unit{QStringLiteral(""), true}, + Unit{}, QVector{}, + QVector{}}; QTest::newRow("Wrong unit file") << QStringLiteral("WrongUnit.txt") - << ExpectedResults{Unit{QStringLiteral(""), true}, Unit{}, - QVector{dateTime(2013, 9, 23, 9, 0, 30), - dateTime(2013, 9, 23, 9, 1, 30), - dateTime(2013, 9, 23, 9, 2, 30)}, - QVector{-2.83950, -2.71850, -2.52150}}; + << ExpectedResults{Unit{QStringLiteral(""), true}, Unit{}, + QVector{dateTime(2013, 9, 23, 9, 0, 30), + dateTime(2013, 9, 23, 9, 1, 30), + dateTime(2013, 9, 23, 9, 2, 30)}, + QVector{-2.83950, -2.71850, -2.52150}}; QTest::newRow("Wrong results file (date of first line is invalid") << QStringLiteral("WrongDate.txt") - << ExpectedResults{ + << ExpectedResults{ Unit{QStringLiteral("nT"), true}, Unit{}, QVector{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)}, QVector{-2.71850, -2.52150}}; QTest::newRow("Wrong results file (too many values for first line") << QStringLiteral("TooManyValues.txt") - << ExpectedResults{ + << ExpectedResults{ Unit{QStringLiteral("nT"), true}, Unit{}, QVector{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)}, QVector{-2.71850, -2.52150}}; QTest::newRow("Wrong results file (x of first line is NaN") << QStringLiteral("NaNX.txt") - << ExpectedResults{ + << ExpectedResults{ Unit{QStringLiteral("nT"), true}, Unit{}, QVector{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)}, QVector{-2.71850, -2.52150}}; + QTest::newRow("Invalid file type (vector)") + << QStringLiteral("ValidVector1.txt") + << ExpectedResults{Unit{QStringLiteral("nT"), true}, Unit{}, + QVector{}, QVector{}}; + // Invalid files - QTest::newRow("Invalid file (unexisting file)") << QStringLiteral("UnexistingFile.txt") - << ExpectedResults{}; + QTest::newRow("Invalid file (unexisting file)") + << QStringLiteral("UnexistingFile.txt") << ExpectedResults{}; + + QTest::newRow("Invalid file (file not found on server)") + << QStringLiteral("FileNotFound.txt") << ExpectedResults{}; +} - QTest::newRow("Invalid file (file not found on server)") << QStringLiteral("FileNotFound.txt") - << ExpectedResults{}; +void TestAmdaResultParser::testReadScalarTxt() +{ + testRead(AmdaResultParser::ValueType::SCALAR); } -void TestAmdaResultParser::testReadTxt() +void TestAmdaResultParser::testReadVectorTxt_data() { - QFETCH(QString, inputFileName); - QFETCH(ExpectedResults, expectedResults); + testReadDataStructure(); + + // ////////// // + // Test cases // + // ////////// // + + // Valid files + QTest::newRow("Valid file") + << QStringLiteral("ValidVector1.txt") + << ExpectedResults{ + Unit{QStringLiteral("nT"), true}, Unit{}, + QVector{dateTime(2013, 7, 2, 9, 13, 50), dateTime(2013, 7, 2, 9, 14, 6), + dateTime(2013, 7, 2, 9, 14, 22), dateTime(2013, 7, 2, 9, 14, 38), + dateTime(2013, 7, 2, 9, 14, 54), dateTime(2013, 7, 2, 9, 15, 10), + dateTime(2013, 7, 2, 9, 15, 26), dateTime(2013, 7, 2, 9, 15, 42), + dateTime(2013, 7, 2, 9, 15, 58), dateTime(2013, 7, 2, 9, 16, 14)}, + QVector >{ + {-0.332, -1.011, -1.457, -1.293, -1.217, -1.443, -1.278, -1.202, -1.22, -1.259}, + {3.206, 2.999, 2.785, 2.736, 2.612, 2.564, 2.892, 2.862, 2.859, 2.764}, + {0.058, 0.496, 1.018, 1.485, 1.662, 1.505, 1.168, 1.244, 1.15, 1.358}}}; - // Parses file - auto filePath = inputFilePath(inputFileName); - auto results = AmdaResultParser::readTxt(filePath); + // Valid files but with some invalid lines (wrong unit, wrong values, etc.) + QTest::newRow("Invalid file type (scalar)") + << QStringLiteral("ValidScalar1.txt") + << ExpectedResults{Unit{QStringLiteral("nT"), true}, Unit{}, + QVector{}, + QVector >{{}, {}, {}}}; +} - // ///////////////// // - // Validates results // - // ///////////////// // - expectedResults.validate(results); +void TestAmdaResultParser::testReadVectorTxt() +{ + testRead(AmdaResultParser::ValueType::VECTOR); } QTEST_MAIN(TestAmdaResultParser)