File indexing completed on 2024-06-16 10:43:45

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 "colorpatch.h"
0007 // Second, the private implementation.
0008 #include "colorpatch_p.h" // IWYU pragma: keep
0009 
0010 #include "constpropagatinguniquepointer.h"
0011 #include <qcolor.h>
0012 #include <qglobal.h>
0013 #include <qnamespace.h>
0014 #include <qobject.h>
0015 #include <qsize.h>
0016 #include <qstring.h>
0017 #include <qtest.h>
0018 #include <qtestcase.h>
0019 #include <qtestdata.h>
0020 
0021 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0022 #include <qtmetamacros.h>
0023 #else
0024 #include <qobjectdefs.h>
0025 #endif
0026 
0027 static void snippet01()
0028 {
0029     //! [ColorPatch Create widget]
0030     PerceptualColor::ColorPatch *m_patch = new PerceptualColor::ColorPatch;
0031     m_patch->setColor(Qt::blue);
0032     //! [ColorPatch Create widget]
0033     //! [ColorPatch Bigger minimum size]
0034     m_patch->setMinimumSize(QSize(50, 50));
0035     //! [ColorPatch Bigger minimum size]
0036     QCOMPARE(m_patch->color(), QColor(Qt::blue));
0037     delete m_patch;
0038 }
0039 
0040 namespace PerceptualColor
0041 {
0042 class TestColorPatch : public QObject
0043 {
0044     Q_OBJECT
0045 
0046 public:
0047     explicit TestColorPatch(QObject *parent = nullptr)
0048         : QObject(parent)
0049     {
0050     }
0051 
0052 private:
0053     static void voidMessageHandler(QtMsgType, const QMessageLogContext &, const QString &)
0054     {
0055         // dummy message handler that does not print messages
0056     }
0057 
0058     void helperProvideQColors()
0059     {
0060         // suppress warning for generating invalid QColor
0061         qInstallMessageHandler(voidMessageHandler);
0062 
0063         QTest::addColumn<QColor>("color");
0064         QTest::newRow("RGB 1 2 3") << QColor(1, 2, 3);
0065         QTest::newRow("RGBA 1 2 3 4") << QColor(1, 2, 3, 4);
0066         QTest::newRow("RGB 1 2 300") << QColor(1, 2, 300);
0067         QTest::newRow("RGBA 1 2 300 4") << QColor(1, 2, 300, 4);
0068 
0069         QTest::newRow("RGB 0.1 0.2 0.3") << QColor::fromRgbF(0.1f, 0.2f, 0.3f);
0070         QTest::newRow("RGBA 0.1 0.2 0.3 0.4") << QColor::fromRgbF(0.1f, 0.2f, 0.3f, 0.4f);
0071         QTest::newRow("RGB 0.1 6.2 0.300") << QColor::fromRgbF(0.1f, 6.2f, 0.300f);
0072         QTest::newRow("RGBA 0.1 6.2 0.300 0.4") << QColor::fromRgbF(0.1f, 6.2f, 0.300f, 0.4f);
0073 
0074         QTest::newRow("CMYK 1 2 3 4") << QColor::fromCmyk(1, 2, 3, 4);
0075         QTest::newRow("CMYK 1 2 3 4 5") << QColor::fromCmyk(1, 2, 3, 4, 5);
0076         QTest::newRow("CMYK 1 2 300 4") << QColor::fromCmyk(1, 2, 300, 4);
0077         QTest::newRow("CMYK 1 2 300 4 5") << QColor::fromCmyk(1, 2, 300, 4, 5);
0078         QTest::newRow("CMYK 0.1 0.2 0.300 0.4") << QColor::fromCmykF(0.1f, 0.2f, 0.300f, 0.4f);
0079         QTest::newRow("CMYK 0.1 0.2 0.300 0.4 0.6495217645f") << QColor::fromCmykF(0.1f, 0.2f, 0.300f, 0.4f, 0.6495217645f);
0080         QTest::newRow("CMYK 0.1 6.2 0.300 0.4") << QColor::fromCmykF(0.1f, 6.2f, 0.300f, 0.4f);
0081         QTest::newRow("CMYK 0.1 6.2 0.300 0.4 0.6495217645f") << QColor::fromCmykF(0.1f, 6.2f, 0.300f, 0.4f, 0.6495217645f);
0082 
0083         QTest::newRow("HSL 2 3 4") << QColor::fromHsl(2, 3, 4);
0084         QTest::newRow("HSL 2 3 4 5") << QColor::fromHsl(2, 3, 4, 5);
0085         QTest::newRow("HSL 2 300 4") << QColor::fromHsl(2, 300, 4);
0086         QTest::newRow("HSL 2 300 4 5") << QColor::fromHsl(2, 300, 4, 5);
0087         QTest::newRow("HSL 0.2 0.300 0.4") << QColor::fromHslF(0.2f, 0.300f, 0.4f);
0088         QTest::newRow("HSL 0.2 0.300 0.4 0.6495217645") << QColor::fromHslF(0.2f, 0.300f, 0.4f, 0.6495217645f);
0089         QTest::newRow("HSL 6.2 0.300 0.4") << QColor::fromHslF(6.2f, 0.300f, 0.4f);
0090         QTest::newRow("HSL 6.2 0.300 0.4 0.6495217645") << QColor::fromHslF(6.2f, 0.300f, 0.4f, 0.6495217645f);
0091 
0092         QTest::newRow("HSV 2 3 4") << QColor::fromHsv(2, 3, 4);
0093         QTest::newRow("HSV 2 3 4 5") << QColor::fromHsv(2, 3, 4, 5);
0094         QTest::newRow("HSV 2 300 4") << QColor::fromHsv(2, 300, 4);
0095         QTest::newRow("HSV 2 300 4 5") << QColor::fromHsv(2, 300, 4, 5);
0096         QTest::newRow("HSV 0.2 0.300 0.4") << QColor::fromHsvF(0.2f, 0.300f, 0.4f);
0097         QTest::newRow("HSV 0.2 0.300 0.4 0.6495217645") << QColor::fromHsvF(0.2f, 0.300f, 0.4f, 0.6495217645f);
0098         QTest::newRow("HSV 6.2 0.300 0.4") << QColor::fromHsvF(6.2f, 0.300f, 0.4f);
0099         QTest::newRow("HSV 6.2 0.300 0.4 0.6495217645") << QColor::fromHsvF(6.2f, 0.300f, 0.4f, 0.6495217645f);
0100 
0101         QTest::newRow("invalid") << QColor();
0102 
0103         // do not suppress warning for generating invalid QColor anymore
0104         qInstallMessageHandler(nullptr);
0105     }
0106 
0107     QColor m_color;
0108 
0109 private Q_SLOTS:
0110     void initTestCase()
0111     {
0112         // Called before the first test function is executed
0113     }
0114     void cleanupTestCase()
0115     {
0116         // Called after the last test function was executed
0117     }
0118 
0119     void init()
0120     {
0121         // Called before each test function is executed
0122     }
0123     void cleanup()
0124     {
0125         // Called after every test function
0126     }
0127 
0128     void testInitialazation()
0129     {
0130         PerceptualColor::ColorPatch thePatch;
0131         // Test initial value (an invalid color following the documentation)
0132         QCOMPARE(thePatch.color(), QColor());
0133     }
0134 
0135     void testM_color()
0136     {
0137         PerceptualColor::ColorPatch thePatch;
0138         thePatch.setColor(Qt::red);
0139         QCOMPARE(thePatch.color(), Qt::red);
0140         QCOMPARE(thePatch.d_pointer->m_color, Qt::red);
0141     }
0142 
0143     void testApplyColors()
0144     {
0145         PerceptualColor::ColorPatch thePatch;
0146         // Test initial value (an invalid color following the documentation)
0147         QCOMPARE(thePatch.color(), QColor());
0148     }
0149 
0150     void testColorProperty_data()
0151     {
0152         helperProvideQColors();
0153     }
0154 
0155     void testColorProperty()
0156     {
0157         QFETCH(QColor, color);
0158         PerceptualColor::ColorPatch thePatch;
0159         thePatch.setColor(color);
0160         QCOMPARE(thePatch.color(), color);
0161     }
0162 
0163     void helperReceiveSignals(QColor color)
0164     {
0165         m_color = color;
0166     }
0167 
0168     void testColorChanged()
0169     {
0170         // Initialization
0171         PerceptualColor::ColorPatch thePatch;
0172         connect(&thePatch, &PerceptualColor::ColorPatch::colorChanged, this, &TestColorPatch::helperReceiveSignals);
0173 
0174         m_color = Qt::red;
0175         thePatch.setColor(QColor()); // invalid like initial value
0176         // We expect that no signal was emitted
0177         QCOMPARE(m_color, Qt::red);
0178 
0179         m_color = Qt::red;
0180         thePatch.setColor(Qt::blue); // new value
0181         // We expect that a signal was emitted
0182         QCOMPARE(m_color, Qt::blue);
0183 
0184         m_color = Qt::red;
0185         thePatch.setColor(Qt::blue); // is yet blue, set again to blue…
0186         // We expect that no signal was emitted
0187         QCOMPARE(m_color, Qt::red);
0188 
0189         m_color = Qt::red;
0190         thePatch.setColor(QColor()); // new: invalid color
0191         // We expect that a signal was emitted
0192         QCOMPARE(m_color, QColor());
0193     }
0194 
0195     void testVerySmallWidgetSizes()
0196     {
0197         // Also very small widget sizes should not crash the widget.
0198         // This might happen because of divisions by 0, even when the widget
0199         // is bigger than 0 because of borders or offsets. We test this
0200         // here with various small sizes, always forcing in immediate
0201         // re-paint.
0202         ColorPatch myWidget;
0203         myWidget.show();
0204         myWidget.resize(QSize());
0205         myWidget.repaint();
0206         myWidget.resize(QSize(-1, -1));
0207         myWidget.repaint();
0208         myWidget.resize(QSize(-1, 0));
0209         myWidget.repaint();
0210         myWidget.resize(QSize(0, -1));
0211         myWidget.repaint();
0212         myWidget.resize(QSize(0, 1));
0213         myWidget.repaint();
0214         myWidget.resize(QSize(1, 0));
0215         myWidget.repaint();
0216         myWidget.resize(QSize(1, 1));
0217         myWidget.repaint();
0218         myWidget.resize(QSize(2, 2));
0219         myWidget.repaint();
0220         myWidget.resize(QSize(3, 3));
0221         myWidget.repaint();
0222         myWidget.resize(QSize(4, 4));
0223         myWidget.repaint();
0224         myWidget.resize(QSize(5, 5));
0225         myWidget.repaint();
0226         myWidget.resize(QSize(6, 6));
0227         myWidget.repaint();
0228         myWidget.resize(QSize(7, 7));
0229         myWidget.repaint();
0230         myWidget.resize(QSize(8, 8));
0231         myWidget.repaint();
0232         myWidget.resize(QSize(9, 9));
0233         myWidget.repaint();
0234         myWidget.resize(QSize(10, 10));
0235         myWidget.repaint();
0236         myWidget.resize(QSize(11, 11));
0237         myWidget.repaint();
0238         myWidget.resize(QSize(12, 12));
0239         myWidget.repaint();
0240         myWidget.resize(QSize(13, 13));
0241         myWidget.repaint();
0242         myWidget.resize(QSize(14, 14));
0243         myWidget.repaint();
0244     }
0245 
0246     void testSnippet01()
0247     {
0248         snippet01();
0249     }
0250 };
0251 
0252 } // namespace PerceptualColor
0253 
0254 QTEST_MAIN(PerceptualColor::TestColorPatch)
0255 #include "testcolorpatch.moc" // necessary because we do not use a header file