File indexing completed on 2024-07-21 04:19:53

0001 // SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com>
0002 // SPDX-License-Identifier: BSD-2-Clause OR MIT
0003 
0004 // First included header is the public header of the class we are testing;
0005 // this forces the header to be self-contained.
0006 #include "polarpointf.h"
0007 
0008 #include <cmath>
0009 #include <qdebug.h>
0010 #include <qglobal.h>
0011 #include <qobject.h>
0012 #include <qpoint.h>
0013 #include <qtest.h>
0014 #include <qtestcase.h>
0015 #include <qvariant.h>
0016 
0017 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0018 #include <qstring.h>
0019 #include <qtmetamacros.h>
0020 #else
0021 #include <qobjectdefs.h>
0022 #include <qstring.h>
0023 #endif
0024 
0025 namespace PerceptualColor
0026 {
0027 class TestPolarPointF : public QObject
0028 {
0029     Q_OBJECT
0030 
0031 public:
0032     explicit TestPolarPointF(QObject *parent = nullptr)
0033         : QObject(parent)
0034     {
0035     }
0036 
0037 private:
0038     static void voidMessageHandler(QtMsgType, const QMessageLogContext &, const QString &)
0039     {
0040         // dummy message handler that does not print messages
0041     }
0042 
0043 private Q_SLOTS:
0044     void initTestCase()
0045     {
0046         // Called before the first test function is executed
0047     }
0048     void cleanupTestCase()
0049     {
0050         // Called after the last test function was executed
0051     }
0052 
0053     void init()
0054     {
0055         // Called before each test function is executed
0056     }
0057     void cleanup()
0058     {
0059         // Called after every test function
0060     }
0061 
0062     void testConstructorRadiusAngle()
0063     {
0064         PerceptualColor::PolarPointF temp01;
0065 
0066         // Default value is 0, 0°
0067         temp01 = PerceptualColor::PolarPointF();
0068         QCOMPARE(temp01.radius(), 0);
0069         QCOMPARE(temp01.angleDegree(), 0);
0070 
0071         // Same for initialization with 0, 0
0072         temp01 = PerceptualColor::PolarPointF(0, 0);
0073         QCOMPARE(temp01.radius(), 0);
0074         QCOMPARE(temp01.angleDegree(), 0);
0075 
0076         // Same for initialization with -0, 0
0077         temp01 = PerceptualColor::PolarPointF(-0, 0);
0078         QCOMPARE(temp01.radius(), 0);
0079         QCOMPARE(temp01.angleDegree(), 0);
0080 
0081         // Yet normalized values are taken as-is
0082         temp01 = PerceptualColor::PolarPointF(2, 3);
0083         QCOMPARE(temp01.radius(), 2);
0084         QCOMPARE(temp01.angleDegree(), 3);
0085 
0086         // Negative radii are normalized (180° shift for angle)
0087         temp01 = PerceptualColor::PolarPointF(-2, 183);
0088         QCOMPARE(temp01.radius(), 2);
0089         QCOMPARE(temp01.angleDegree(), 3);
0090 
0091         // Out-of-range angle is normalized
0092         temp01 = PerceptualColor::PolarPointF(2, 363);
0093         QCOMPARE(temp01.radius(), 2);
0094         QCOMPARE(temp01.angleDegree(), 3);
0095 
0096         temp01 = PerceptualColor::PolarPointF(2, -357);
0097         QCOMPARE(temp01.radius(), 2);
0098         QCOMPARE(temp01.angleDegree(), 3);
0099 
0100         // Also when both radius and angle are
0101         // out-of-range, normalization works
0102         temp01 = PerceptualColor::PolarPointF(-2, -357);
0103         QCOMPARE(temp01.radius(), 2);
0104         QCOMPARE(temp01.angleDegree(), 183);
0105         temp01 = PerceptualColor::PolarPointF(-2, -717);
0106         QCOMPARE(temp01.radius(), 2);
0107         QCOMPARE(temp01.angleDegree(), 183);
0108         temp01 = PerceptualColor::PolarPointF(-2, 363);
0109         QCOMPARE(temp01.radius(), 2);
0110         QCOMPARE(temp01.angleDegree(), 183);
0111         temp01 = PerceptualColor::PolarPointF(-2, 723);
0112         QCOMPARE(temp01.radius(), 2);
0113         QCOMPARE(temp01.angleDegree(), 183);
0114 
0115         // When radius is 0, angle (while meaningless) is
0116         // preserved (but normalized)
0117         temp01 = PerceptualColor::PolarPointF(0, 150);
0118         QCOMPARE(temp01.radius(), 0);
0119         QCOMPARE(temp01.angleDegree(), 150);
0120         temp01 = PerceptualColor::PolarPointF(0, 370);
0121         QCOMPARE(temp01.radius(), 0);
0122         QCOMPARE(temp01.angleDegree(), 10);
0123 
0124         // When radius is -0, angle (while meaningless) is
0125         // preserved (but normalized)
0126         temp01 = PerceptualColor::PolarPointF(-0, 150);
0127         QCOMPARE(temp01.radius(), 0);
0128         QCOMPARE(temp01.angleDegree(), 150);
0129         temp01 = PerceptualColor::PolarPointF(-0, 370);
0130         QCOMPARE(temp01.radius(), 0);
0131         QCOMPARE(temp01.angleDegree(), 10);
0132 
0133         // Edge case: 360°
0134         temp01 = PerceptualColor::PolarPointF(-0, 360);
0135         QCOMPARE(temp01.radius(), 0);
0136         QCOMPARE(temp01.angleDegree(), 0);
0137         temp01 = PerceptualColor::PolarPointF(0, 360);
0138         QCOMPARE(temp01.radius(), 0);
0139         QCOMPARE(temp01.angleDegree(), 0);
0140         temp01 = PerceptualColor::PolarPointF(5, 360);
0141         QCOMPARE(temp01.radius(), 5);
0142         QCOMPARE(temp01.angleDegree(), 0);
0143     }
0144 
0145     void testCopyAndAsignmentConstructor()
0146     {
0147         PerceptualColor::PolarPointF temp01;
0148         PerceptualColor::PolarPointF temp02;
0149         PerceptualColor::PolarPointF temp03;
0150 
0151         temp01 = PerceptualColor::PolarPointF();
0152         temp02 = temp01;
0153         temp03 = PerceptualColor::PolarPointF(temp01);
0154         QCOMPARE(temp01.radius(), 0);
0155         QCOMPARE(temp02.radius(), 0);
0156         QCOMPARE(temp03.radius(), 0);
0157         QCOMPARE(temp01.angleDegree(), 0);
0158         QCOMPARE(temp02.angleDegree(), 0);
0159         QCOMPARE(temp03.angleDegree(), 0);
0160 
0161         temp01 = PerceptualColor::PolarPointF(0, 0);
0162         temp02 = temp01;
0163         temp03 = PerceptualColor::PolarPointF(temp01);
0164         QCOMPARE(temp01.radius(), 0);
0165         QCOMPARE(temp02.radius(), 0);
0166         QCOMPARE(temp03.radius(), 0);
0167         QCOMPARE(temp01.angleDegree(), 0);
0168         QCOMPARE(temp02.angleDegree(), 0);
0169         QCOMPARE(temp03.angleDegree(), 0);
0170 
0171         temp01 = PerceptualColor::PolarPointF(-2, 723);
0172         temp02 = temp01;
0173         temp03 = PerceptualColor::PolarPointF(temp01);
0174         QCOMPARE(temp01.radius(), 2);
0175         QCOMPARE(temp02.radius(), 2);
0176         QCOMPARE(temp03.radius(), 2);
0177         QCOMPARE(temp01.angleDegree(), 183);
0178         QCOMPARE(temp02.angleDegree(), 183);
0179         QCOMPARE(temp03.angleDegree(), 183);
0180     }
0181 
0182     void testConstructorCartesian()
0183     {
0184         PerceptualColor::PolarPointF temp01;
0185         temp01 = PerceptualColor::PolarPointF(QPointF(0, 0));
0186         QCOMPARE(temp01.radius(), 0);
0187         QCOMPARE(temp01.angleDegree(), 0);
0188         temp01 = PerceptualColor::PolarPointF(QPointF(2, 0));
0189         QCOMPARE(temp01.radius(), 2);
0190         QCOMPARE(temp01.angleDegree(), 0);
0191         temp01 = PerceptualColor::PolarPointF(QPointF(2, 2));
0192         QCOMPARE(temp01.radius(), sqrt(8));
0193         QCOMPARE(temp01.angleDegree(), static_cast<qreal>(45));
0194         temp01 = PerceptualColor::PolarPointF(QPointF(0, 2));
0195         QCOMPARE(temp01.radius(), 2);
0196         QCOMPARE(temp01.angleDegree(), 90);
0197         temp01 = PerceptualColor::PolarPointF(QPointF(-2, 2));
0198         QCOMPARE(temp01.radius(), sqrt(8));
0199         QCOMPARE(temp01.angleDegree(), static_cast<qreal>(135));
0200         temp01 = PerceptualColor::PolarPointF(QPointF(-2, 0));
0201         QCOMPARE(temp01.radius(), 2);
0202         QCOMPARE(temp01.angleDegree(), 180);
0203         temp01 = PerceptualColor::PolarPointF(QPointF(-2, -2));
0204         QCOMPARE(temp01.radius(), sqrt(8));
0205         QCOMPARE(temp01.angleDegree(), static_cast<qreal>(225));
0206         temp01 = PerceptualColor::PolarPointF(QPointF(0, -2));
0207         QCOMPARE(temp01.radius(), 2);
0208         QCOMPARE(temp01.angleDegree(), 270);
0209         temp01 = PerceptualColor::PolarPointF(QPointF(2, -2));
0210         QCOMPARE(temp01.radius(), sqrt(8));
0211         QCOMPARE(temp01.angleDegree(), static_cast<qreal>(315));
0212     }
0213 
0214     void testIsSamePoint()
0215     {
0216         QVERIFY(!PerceptualColor::PolarPointF(0, 0).isSamePoint(PerceptualColor::PolarPointF(1, 0)));
0217 
0218         // If radius is 0, different angle still means same point
0219         QVERIFY(PerceptualColor::PolarPointF(0, 0).isSamePoint(PerceptualColor::PolarPointF(0, 500)));
0220 
0221         QVERIFY(PerceptualColor::PolarPointF(0, 0).isSamePoint(PerceptualColor::PolarPointF(0, 300)));
0222 
0223         QVERIFY(PerceptualColor::PolarPointF(0, 0).isSamePoint(PerceptualColor::PolarPointF(0, -500)));
0224 
0225         QVERIFY(PerceptualColor::PolarPointF(0, 0).isSamePoint(PerceptualColor::PolarPointF(-0, 500)));
0226 
0227         QVERIFY(PerceptualColor::PolarPointF(0, 0).isSamePoint(PerceptualColor::PolarPointF(-0, 300)));
0228 
0229         QVERIFY(PerceptualColor::PolarPointF(0, 0).isSamePoint(PerceptualColor::PolarPointF(-0, -500)));
0230 
0231         QVERIFY(!PerceptualColor::PolarPointF(1, 320).isSamePoint(PerceptualColor::PolarPointF(1, 321)));
0232 
0233         QVERIFY(PerceptualColor::PolarPointF(5, 90).isSamePoint(PerceptualColor::PolarPointF(-5, 270)));
0234 
0235         QVERIFY(PerceptualColor::PolarPointF(5, 450).isSamePoint(PerceptualColor::PolarPointF(-5, -90)));
0236     }
0237 
0238     void testToCartesian()
0239     {
0240         QCOMPARE(PerceptualColor::PolarPointF(0, 0).toCartesian(), QPointF(0, 0));
0241         QCOMPARE(PerceptualColor::PolarPointF(-0, 0).toCartesian(), QPointF(0, 0));
0242         QCOMPARE(PerceptualColor::PolarPointF(0, 90).toCartesian(), QPointF(0, 0));
0243         QCOMPARE(PerceptualColor::PolarPointF(-0, 90).toCartesian(), QPointF(0, 0));
0244         QCOMPARE(PerceptualColor::PolarPointF(0, 361).toCartesian(), QPointF(0, 0));
0245         QCOMPARE(PerceptualColor::PolarPointF(-0, 361).toCartesian(), QPointF(0, 0));
0246         QCOMPARE(PerceptualColor::PolarPointF(0, -1).toCartesian(), QPointF(0, 0));
0247         QCOMPARE(PerceptualColor::PolarPointF(-0, -1).toCartesian(), QPointF(0, 0));
0248         QCOMPARE(PerceptualColor::PolarPointF(1, 0).toCartesian(), QPointF(1, 0));
0249         QCOMPARE(PerceptualColor::PolarPointF(1, 90).toCartesian(), QPointF(0, 1));
0250         QCOMPARE(PerceptualColor::PolarPointF(1, 180).toCartesian(), QPointF(-1, 0));
0251         QCOMPARE(PerceptualColor::PolarPointF(1, 270).toCartesian(), QPointF(0, -1));
0252         QCOMPARE(PerceptualColor::PolarPointF(1, 360).toCartesian(), QPointF(1, 0));
0253         QCOMPARE(PerceptualColor::PolarPointF(1, 720).toCartesian(), QPointF(1, 0));
0254         QCOMPARE(PerceptualColor::PolarPointF(1, -360).toCartesian(), QPointF(1, 0));
0255         QCOMPARE(PerceptualColor::PolarPointF(sqrt(8), 45).toCartesian(), QPointF(2, 2));
0256     }
0257 
0258     void testMetaType()
0259     {
0260         PerceptualColor::PolarPointF temp01(17, 18);
0261         QVariant var;
0262         // This following line should throw a compile-time error if meta-type
0263         // is not declared:
0264         var.setValue(temp01);
0265         QVERIFY(var.value<PerceptualColor::PolarPointF>().isSamePoint(temp01));
0266     }
0267 
0268     void testDebug()
0269     {
0270         // suppress warnings
0271         qInstallMessageHandler(voidMessageHandler);
0272         // Test if QDebug support does not make a crash.
0273         qDebug() << PolarPointF();
0274         // do not suppress warning for generating invalid QColor anymore
0275         qInstallMessageHandler(nullptr);
0276     }
0277 
0278     void testMetaTypeDeclaration()
0279     {
0280         QVariant test;
0281         // The next line should produce a compiler error if the
0282         // type is not declared to Qt’s Meta Object System.
0283         test.setValue(PolarPointF());
0284     }
0285 };
0286 
0287 } // namespace PerceptualColor
0288 
0289 QTEST_MAIN(PerceptualColor::TestPolarPointF)
0290 // The following “include” is necessary because we do not use a header file:
0291 #include "testpolarpointf.moc"