File indexing completed on 2024-12-01 03:34:52

0001 /*
0002     File                 : CommonTest.h
0003     Project              : LabPlot
0004     Description          : General test class
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2019-2022 Stefan Gerlach <stefan.gerlach@uni.kn>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 #ifndef COMMONTEST_H
0011 #define COMMONTEST_H
0012 
0013 #include "backend/worksheet/plots/cartesian/CartesianCoordinateSystem.h"
0014 #include <QtTest>
0015 
0016 #include <gsl/gsl_math.h>
0017 
0018 ///////////////////////// macros ///////////
0019 
0020 // Comparing two values. First a direct comparsion will be done, because for std::nan nsl_math_aproximately_equal does not work
0021 #define VALUES_EQUAL(v1, ref)                                                                                                                                  \
0022     QVERIFY2(v1 == ref ? true : (std::isnan(ref) ? std::isnan(v1) : nsl_math_approximately_equal(v1, ref) == true),                                            \
0023              qPrintable(QStringLiteral("v1:%1, ref:%2").arg((double)v1, 0, 'g', 15, QLatin1Char(' ')).arg((double)ref, 0, 'g', 15, QLatin1Char(' '))))
0024 
0025 #define RANGE_CORRECT(range, start_, end_)                                                                                                                     \
0026     VALUES_EQUAL(range.start(), start_);                                                                                                                       \
0027     VALUES_EQUAL(range.end(), end_);
0028 
0029 /*!
0030  * Checks the range of dim \p dim from the coordinatesystem with index \p cSystemIndex
0031  */
0032 #define CHECK_RANGE_CSYSTEMINDEX(plot, cSystemIndex, dim, start_, end_)                                                                                        \
0033     RANGE_CORRECT(plot->range(dim, plot->coordinateSystem(cSystemIndex)->index(dim)), start_, end_)
0034 
0035 /*!
0036  * Checks the range of dim \p dim from the coordinatesystem assigned to \p aspect
0037  */
0038 #define CHECK_RANGE(plot, aspect, dim, start_, end_) CHECK_RANGE_CSYSTEMINDEX(plot, aspect->coordinateSystemIndex(), dim, start_, end_)
0039 
0040 #define CHECK_SCALE_PLOT(plot, coordinateSystemIndex, dimension, a_ref, b_ref, c_ref)                                                                          \
0041     do {                                                                                                                                                       \
0042         QVERIFY(plot);                                                                                                                                         \
0043         QVERIFY(plot->coordinateSystemCount() > coordinateSystemIndex);                                                                                        \
0044         const auto scales = plot->coordinateSystem(coordinateSystemIndex)->scales(dimension);                                                                  \
0045         QCOMPARE(scales.length(), 1);                                                                                                                          \
0046         QVERIFY(scales.at(0) != nullptr);                                                                                                                      \
0047         CHECK_SCALE(scales.at(0), a_ref, b_ref, c_ref);                                                                                                        \
0048     } while (false);
0049 
0050 #define CHECK_SCALE(scale, a_ref, b_ref, c_ref)                                                                                                                \
0051     do {                                                                                                                                                       \
0052         double a;                                                                                                                                              \
0053         double b;                                                                                                                                              \
0054         double c;                                                                                                                                              \
0055         Range<double> r;                                                                                                                                       \
0056         scale->getProperties(&r, &a, &b, &c);                                                                                                                  \
0057         QVERIFY2(nsl_math_approximately_equal(a, a_ref), qPrintable(QStringLiteral("a: v1:%1, ref:%2").arg(a).arg(a_ref)));                                    \
0058         QVERIFY2(nsl_math_approximately_equal(b, b_ref), qPrintable(QStringLiteral("b: v1:%1, ref:%2").arg(b).arg(b_ref)));                                    \
0059         QVERIFY2(nsl_math_approximately_equal(c, c_ref), qPrintable(QStringLiteral("c: v1:%1, ref:%2").arg(c).arg(c_ref)));                                    \
0060     } while (false);
0061 
0062 #define DEBUG_RANGE(plot, aspect)                                                                                                                              \
0063     {                                                                                                                                                          \
0064         int cSystem = aspect->coordinateSystemIndex();                                                                                                         \
0065         WARN(Q_FUNC_INFO << ", csystem index = " << cSystem)                                                                                                   \
0066         int xIndex = plot->coordinateSystem(cSystem)->index(Dimension::X);                                                                                     \
0067         int yIndex = plot->coordinateSystem(cSystem)->index(Dimension::Y);                                                                                     \
0068                                                                                                                                                                \
0069         auto xrange = plot->range(Dimension::X, xIndex);                                                                                                       \
0070         auto yrange = plot->range(Dimension::Y, yIndex);                                                                                                       \
0071         WARN(Q_FUNC_INFO << ", x index = " << xIndex << ", range = " << xrange.start() << " .. " << xrange.end())                                              \
0072         WARN(Q_FUNC_INFO << ", y index = " << yIndex << ", range = " << yrange.start() << " .. " << yrange.end())                                              \
0073     }
0074 
0075 #define COMPARE_DOUBLE_VECTORS_AT_LEAST_LENGTH(res, ref)                                                                                                       \
0076     do {                                                                                                                                                       \
0077         QVERIFY(res.length() >= ref.length());                                                                                                                 \
0078         for (int i = 0; i < ref.length(); i++)                                                                                                                 \
0079             QVERIFY2(qFuzzyCompare(res.at(i), ref.at(i)),                                                                                                      \
0080                      qPrintable(QStringLiteral("i=") + QString::number(i) + QStringLiteral(", res=") + QString::number(res.at(i)) + QStringLiteral(", ref=")   \
0081                                 + QString::number(ref.at(i))));                                                                                                \
0082     } while (false)
0083 
0084 #define COMPARE_DOUBLE_VECTORS(res, ref)                                                                                                                       \
0085     do {                                                                                                                                                       \
0086         QCOMPARE(res.length(), ref.length());                                                                                                                  \
0087         COMPARE_DOUBLE_VECTORS_AT_LEAST_LENGTH(res, ref);                                                                                                      \
0088     } while (false)
0089 
0090 #define COMPARE_STRING_VECTORS(res, ref)                                                                                                                       \
0091     QCOMPARE(res.length(), ref.length());                                                                                                                      \
0092     for (int i = 0; i < res.length(); i++)                                                                                                                     \
0093         QVERIFY2(res.at(i).compare(ref.at(i)) == 0,                                                                                                            \
0094                  qPrintable(QStringLiteral("i=") + QString::number(i) + QStringLiteral(", res=") + res.at(i) + QStringLiteral(", ref=") + ref.at(i)));
0095 
0096 /*!
0097  * Stores the labplot project to a temporary file
0098  * The filename is then stored in the savePath variable
0099  */
0100 #define SAVE_PROJECT(project_name)                                                                                                                             \
0101     do {                                                                                                                                                       \
0102         auto* tempFile = new QTemporaryFile(QStringLiteral("XXXXXX_") + QLatin1String(project_name) + QLatin1String(".lml"), this);                            \
0103         QCOMPARE(tempFile->open(), true);                                                                                                                      \
0104         savePath = tempFile->fileName();                                                                                                                       \
0105         QFile file(savePath);                                                                                                                                  \
0106         QCOMPARE(file.open(QIODevice::WriteOnly), true);                                                                                                       \
0107                                                                                                                                                                \
0108         project.setFileName(tempFile->fileName());                                                                                                             \
0109         QXmlStreamWriter writer(&file);                                                                                                                        \
0110         QPixmap thumbnail;                                                                                                                                     \
0111         project.save(thumbnail, &writer);                                                                                                                      \
0112         file.close();                                                                                                                                          \
0113         DEBUG(QStringLiteral("File stored as: ").toStdString() << savePath.toStdString());                                                                     \
0114         QVERIFY(!savePath.isEmpty());                                                                                                                          \
0115     } while (0);
0116 
0117 ///////////////////////////////////////////////////////
0118 
0119 class CommonTest : public QObject {
0120     Q_OBJECT
0121 
0122 private Q_SLOTS:
0123     void initTestCase();
0124 
0125 protected:
0126     // compare floats with given delta
0127     // delta - relative error
0128     static inline void FuzzyCompare(double actual, double expected, double delta = 1.e-12) {
0129         if (std::abs(expected) < delta)
0130             QVERIFY(std::abs(actual) < delta);
0131         else {
0132             DEBUG(std::setprecision(15) << actual - std::abs(actual) * delta << " <= " << expected << " <= " << actual + std::abs(actual) * delta);
0133             QVERIFY(!gsl_fcmp(actual, expected, delta));
0134         }
0135     }
0136 };
0137 #endif