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