File indexing completed on 2024-12-01 10:31:03
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 "colorwheelimage.h" 0007 0008 #include "rgbcolorspacefactory.h" 0009 #include <qcolor.h> 0010 #include <qglobal.h> 0011 #include <qimage.h> 0012 #include <qobject.h> 0013 #include <qsharedpointer.h> 0014 #include <qsize.h> 0015 #include <qtest.h> 0016 #include <qtestcase.h> 0017 #include <qwidget.h> 0018 0019 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0020 #include <qtmetamacros.h> 0021 #else 0022 #include <qobjectdefs.h> 0023 #include <qstring.h> 0024 #endif 0025 0026 class TestColorWheelSnippetClass : public QWidget 0027 { 0028 Q_OBJECT 0029 public: 0030 // A constructor that is clazy-conform 0031 explicit TestColorWheelSnippetClass(QWidget *parent = nullptr) 0032 : QWidget(parent) 0033 { 0034 } 0035 void testSnippet01() 0036 { 0037 //! [ColorWheelImage HiDPI usage] 0038 auto myColorSpace = PerceptualColor::RgbColorSpaceFactory::createSrgb(); 0039 PerceptualColor::ColorWheelImage test{myColorSpace}; 0040 // The function setImageSize() expects an int 0041 // value. static_cast<int> will round down, which 0042 // is the desired behaviour here. (Rounding up 0043 // would mean one more pixel, and on some Qt 0044 // styles this would fail.) 0045 test.setImageSize(static_cast<int>(100 * devicePixelRatioF())); 0046 test.setBorder(5 * devicePixelRatioF()); 0047 test.setWheelThickness(10 * devicePixelRatioF()); 0048 test.setDevicePixelRatioF(devicePixelRatioF()); 0049 QImage myImage = test.getImage(); 0050 //! [ColorWheelImage HiDPI usage] 0051 Q_UNUSED(myImage) 0052 } 0053 }; 0054 0055 namespace PerceptualColor 0056 { 0057 class RgbColorSpace; 0058 0059 class TestColorWheelImage : public QObject 0060 { 0061 Q_OBJECT 0062 0063 public: 0064 explicit TestColorWheelImage(QObject *parent = nullptr) 0065 : QObject(parent) 0066 { 0067 } 0068 0069 private: 0070 QSharedPointer<RgbColorSpace> colorSpace = RgbColorSpaceFactory::createSrgb(); 0071 0072 private Q_SLOTS: 0073 void initTestCase() 0074 { 0075 // Called before the first test function is executed 0076 } 0077 0078 void cleanupTestCase() 0079 { 0080 // Called after the last test function was executed 0081 } 0082 0083 void init() 0084 { 0085 // Called before each test function is executed 0086 } 0087 0088 void cleanup() 0089 { 0090 // Called after every test function 0091 } 0092 0093 void testConstructor() 0094 { 0095 ColorWheelImage test(colorSpace); 0096 } 0097 0098 void testImageSize() 0099 { 0100 ColorWheelImage test(colorSpace); 0101 QCOMPARE(test.getImage().size(), QSize(0, 0)); 0102 test.setImageSize(5); 0103 QCOMPARE(test.getImage().size(), QSize(5, 5)); 0104 test.setImageSize(500); 0105 QCOMPARE(test.getImage().size(), QSize(500, 500)); 0106 } 0107 0108 void testDevicePixelRatioF() 0109 { 0110 ColorWheelImage test(colorSpace); 0111 test.setImageSize(100); 0112 // Image size is as described. 0113 QCOMPARE(test.getImage().size(), QSize(100, 100)); 0114 // Default devicePixelRatioF is 1 0115 QCOMPARE(test.getImage().devicePixelRatio(), 1); 0116 // Testing with a (non-integer) scale factor 0117 test.setDevicePixelRatioF(1.5); 0118 // Image size remains unchanged. 0119 QCOMPARE(test.getImage().size(), QSize(100, 100)); 0120 // Default devicePixelRatioF is 1.5 0121 QCOMPARE(test.getImage().devicePixelRatio(), 1.5); 0122 } 0123 0124 void testBorderOdd() 0125 { 0126 ColorWheelImage test(colorSpace); 0127 test.setImageSize(99); 0128 // Default border is zero: no transparent border. 0129 QVERIFY2(test.getImage().pixelColor(49, 0).alpha() > 0, "Verify that pixel top center is not transparent."); 0130 QVERIFY2(test.getImage().pixelColor(49, 98).alpha() > 0, "Verify that pixel bottom center is not transparent."); 0131 QVERIFY2(test.getImage().pixelColor(0, 49).alpha() > 0, "Verify that pixel left is not transparent."); 0132 QVERIFY2(test.getImage().pixelColor(98, 49).alpha() > 0, "Verify that pixel right is not transparent."); 0133 test.setBorder(1); 0134 // Now, the pixels should become transparent. 0135 QCOMPARE(test.getImage().pixelColor(49, 0).alpha(), 0); 0136 QCOMPARE(test.getImage().pixelColor(49, 98).alpha(), 0); 0137 QCOMPARE(test.getImage().pixelColor(0, 49).alpha(), 0); 0138 QCOMPARE(test.getImage().pixelColor(98, 49).alpha(), 0); 0139 } 0140 0141 void testBorderEven() 0142 { 0143 ColorWheelImage test(colorSpace); 0144 test.setImageSize(100); 0145 // Default border is zero: no transparent border. 0146 QVERIFY2(test.getImage().pixelColor(49, 0).alpha() > 0, "Verify that pixel top center is not transparent."); 0147 QVERIFY2(test.getImage().pixelColor(50, 0).alpha() > 0, "Verify that pixel top center is not transparent."); 0148 QVERIFY2(test.getImage().pixelColor(49, 99).alpha() > 0, "Verify that pixel bottom center is not transparent."); 0149 QVERIFY2(test.getImage().pixelColor(50, 99).alpha() > 0, "Verify that pixel bottom center is not transparent."); 0150 QVERIFY2(test.getImage().pixelColor(0, 49).alpha() > 0, "Verify that pixel left is not transparent."); 0151 QVERIFY2(test.getImage().pixelColor(0, 50).alpha() > 0, "Verify that pixel left is not transparent."); 0152 QVERIFY2(test.getImage().pixelColor(99, 49).alpha() > 0, "Verify that pixel right is not transparent."); 0153 QVERIFY2(test.getImage().pixelColor(99, 50).alpha() > 0, "Verify that pixel right is not transparent."); 0154 test.setBorder(1); 0155 // Now, the pixels should become transparent. 0156 QCOMPARE(test.getImage().pixelColor(49, 0).alpha(), 0); 0157 QCOMPARE(test.getImage().pixelColor(50, 0).alpha(), 0); 0158 QCOMPARE(test.getImage().pixelColor(49, 99).alpha(), 0); 0159 QCOMPARE(test.getImage().pixelColor(50, 99).alpha(), 0); 0160 QCOMPARE(test.getImage().pixelColor(0, 49).alpha(), 0); 0161 QCOMPARE(test.getImage().pixelColor(0, 50).alpha(), 0); 0162 QCOMPARE(test.getImage().pixelColor(99, 49).alpha(), 0); 0163 QCOMPARE(test.getImage().pixelColor(99, 50).alpha(), 0); 0164 } 0165 0166 void testCache() 0167 { 0168 ColorWheelImage test(colorSpace); 0169 test.setImageSize(50); // Set a non-zero image size 0170 QVERIFY2(test.m_image.isNull(), "Verify that instantiation is done with empty cache."); 0171 test.setBorder(5); 0172 QVERIFY2(test.m_image.isNull(), "Verify that setting border does not trigger re-calculation."); 0173 Q_UNUSED(test.getImage()); 0174 QVERIFY2(!test.m_image.isNull(), "Verify that getImage() triggers re-calculation."); 0175 test.setBorder(5); 0176 QVERIFY2(!test.m_image.isNull(), 0177 "Verify that setBorder() does not erase the cache" 0178 " if the value that was set is the same than before."); 0179 } 0180 0181 void testCornerCases() 0182 { 0183 ColorWheelImage test(colorSpace); 0184 test.setImageSize(50); // Set a non-zero image size 0185 QVERIFY2(!test.getImage().isNull(), 0186 "Verify that there is no crash and the returned image is not " 0187 "null."); 0188 test.setBorder(10); 0189 QVERIFY2(!test.getImage().isNull(), 0190 "Verify that there is no crash and the returned image is not " 0191 "null."); 0192 test.setBorder(25); 0193 QVERIFY2(!test.getImage().isNull(), 0194 "Verify that there is no crash and the returned image is not " 0195 "null."); 0196 test.setBorder(100); 0197 QVERIFY2(!test.getImage().isNull(), 0198 "Verify that there is no crash and the returned image is not " 0199 "null."); 0200 test.setBorder(5); 0201 QVERIFY2(!test.getImage().isNull(), 0202 "Verify that there is no crash and the returned image is not " 0203 "null."); 0204 test.setWheelThickness(0); 0205 QVERIFY2(!test.getImage().isNull(), 0206 "Verify that there is no crash and the returned image is not " 0207 "null."); 0208 test.setWheelThickness(10); 0209 QVERIFY2(!test.getImage().isNull(), 0210 "Verify that there is no crash and the returned image is not " 0211 "null."); 0212 test.setWheelThickness(25); 0213 QVERIFY2(!test.getImage().isNull(), 0214 "Verify that there is no crash and the returned image is not " 0215 "null."); 0216 test.setWheelThickness(100); 0217 QVERIFY2(!test.getImage().isNull(), 0218 "Verify that there is no crash and the returned image is not " 0219 "null."); 0220 test.setWheelThickness(10); 0221 QVERIFY2(!test.getImage().isNull(), 0222 "Verify that there is no crash and the returned image is not " 0223 "null."); 0224 } 0225 0226 void testVeryThickWheel() 0227 { 0228 ColorWheelImage test(colorSpace); 0229 test.setImageSize(51); // Set a non-zero image size 0230 test.setWheelThickness(100); 0231 // The wheel is so thick that even in the middle, there should be 0232 // a fully opaque pixel. 0233 QCOMPARE(test.getImage().pixelColor(25, 25).alpha(), 255); 0234 } 0235 0236 void testVeryBigBorder() 0237 { 0238 ColorWheelImage test(colorSpace); 0239 const int myImageSize = 51; 0240 test.setImageSize(myImageSize); // Set a non-zero image size 0241 test.setWheelThickness(5); 0242 // Set a border that is bigger than half of the image size 0243 test.setBorder(myImageSize / 2 + 1); 0244 // The border is so big that the hole image should be transparent. 0245 for (int x = 0; x < myImageSize; ++x) { 0246 for (int y = 0; y < myImageSize; ++y) { 0247 QCOMPARE(test.getImage().pixelColor(x, y).alpha(), 0); 0248 } 0249 } 0250 } 0251 0252 void testDevicePixelRatioFForExtremeCases() 0253 { 0254 ColorWheelImage test(colorSpace); 0255 // Testing with a (non-integer) scale factor 0256 test.setDevicePixelRatioF(1.5); 0257 // Test with fully transparent image (here, the border is too big 0258 // for the given image size) 0259 test.setImageSize(20); 0260 test.setBorder(30); 0261 QCOMPARE(test.getImage().devicePixelRatio(), 1.5); 0262 } 0263 0264 void testSnippet01() 0265 { 0266 TestColorWheelSnippetClass mySnippets; 0267 mySnippets.testSnippet01(); 0268 } 0269 }; 0270 0271 } // namespace PerceptualColor 0272 0273 QTEST_MAIN(PerceptualColor::TestColorWheelImage) 0274 0275 // The following “include” is necessary because we do not use a header file: 0276 #include "testcolorwheelimage.moc"