File indexing completed on 2024-06-23 11:14:25

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 "perceptualsettings.h"
0007 
0008 #include "setting.h"
0009 #include "settingbase.h"
0010 #include <qcolor.h>
0011 #include <qglobal.h>
0012 #include <qnamespace.h>
0013 #include <qobject.h>
0014 #include <qsignalspy.h>
0015 #include <qstring.h>
0016 #include <qstringliteral.h>
0017 #include <qtest.h>
0018 #include <qtest_gui.h>
0019 #include <qtestcase.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     // cppcheck-suppress constVariableReference // snippet for documentation
0030     //! [PerceptualSettings Instance]
0031     auto &mySettings = PerceptualColor::PerceptualSettings::instance();
0032     //! [PerceptualSettings Instance]
0033     Q_UNUSED(mySettings)
0034 }
0035 
0036 namespace PerceptualColor
0037 {
0038 class TestPerceptualSettings : public QObject
0039 {
0040     Q_OBJECT
0041 
0042 public:
0043     explicit TestPerceptualSettings(QObject *parent = nullptr)
0044         : QObject(parent)
0045     {
0046     }
0047 
0048 private Q_SLOTS:
0049     void initTestCase()
0050     {
0051         // Called before the first test function is executed
0052     }
0053 
0054     void cleanupTestCase()
0055     {
0056         // Called after the last test function was executed
0057     }
0058 
0059     void init()
0060     {
0061         // Called before each test function is executed
0062     }
0063 
0064     void cleanup()
0065     {
0066         // Called after every test function
0067     }
0068 
0069     void testSnippet01()
0070     {
0071         snippet01();
0072     }
0073 
0074     void testColorListConstructor()
0075     {
0076         PerceptualSettings::ColorList myList;
0077         Q_UNUSED(myList);
0078     }
0079 
0080     void testConstructorDestructor()
0081     {
0082         // There should be no crash:
0083         const auto &mySettings = PerceptualSettings::instance();
0084         Q_UNUSED(mySettings)
0085     }
0086 
0087 #ifndef MSVC_DLL
0088     // The automatic export of otherwise private symbols on MSVC
0089     // shared libraries via CMake's WINDOWS_EXPORT_ALL_SYMBOLS property
0090     // does not work well for Qt meta objects, resulting in non-functional
0091     // signals. Since the following unit tests require signals, it cannot be
0092     // built for MSVC shared libraries.
0093 
0094     void testCustomColors()
0095     {
0096         auto &mySettings = PerceptualSettings::instance();
0097 
0098         const PerceptualColor::PerceptualSettings::ColorList newColors1 = {QColor(Qt::red), QColor(Qt::green), QColor(Qt::blue)};
0099         mySettings.customColors.setValue(newColors1);
0100         QCOMPARE(mySettings.customColors.value(), newColors1);
0101 
0102         QSignalSpy spy(&mySettings.customColors, &PerceptualColor::SettingBase::valueChanged);
0103 
0104         const PerceptualColor::PerceptualSettings::ColorList newColors2 = {QColor(Qt::cyan), QColor(Qt::magenta), QColor(Qt::yellow)};
0105         mySettings.customColors.setValue(newColors2);
0106         mySettings.customColors.setValue(newColors2); // Intentional duplicate
0107         QCOMPARE(mySettings.customColors.value(), newColors2);
0108         QVERIFY(spy.isValid());
0109         // The second call to the setter with an identical value
0110         // should not trigger a signal.
0111         QCOMPARE(spy.count(), 1);
0112     }
0113 
0114     void testTab()
0115     {
0116         auto &mySettings = PerceptualSettings::instance();
0117 
0118         const QString newTab1 = QStringLiteral("testTab");
0119         mySettings.tab.setValue(newTab1);
0120         QCOMPARE(mySettings.tab.value(), newTab1);
0121 
0122         QSignalSpy spy(&mySettings.tab, &PerceptualColor::SettingBase::valueChanged);
0123 
0124         const QString newTab2 = QStringLiteral("differentTestTab");
0125         mySettings.tab.setValue(newTab2);
0126         mySettings.tab.setValue(newTab2); // Intentional duplicate
0127         QCOMPARE(mySettings.tab.value(), newTab2);
0128         QVERIFY(spy.isValid());
0129         // The second call to the setter with an identical value
0130         // should not trigger a signal.
0131         QCOMPARE(spy.count(), 1);
0132     }
0133 
0134     void testInstancesAreIdenticalForTab()
0135     {
0136         // As this is implemented as singleton, calling the singleton function
0137         // various times should still produce interchangeable results.
0138 
0139         auto &mySettings1 = PerceptualSettings::instance();
0140         auto &mySettings2 = PerceptualSettings::instance();
0141 
0142         const QString newTab1 = QStringLiteral("testTabInstance");
0143         mySettings1.tab.setValue(newTab1);
0144         QCOMPARE(mySettings1.tab.value(), newTab1);
0145         QCOMPARE(mySettings2.tab.value(), newTab1);
0146 
0147         QSignalSpy spy1(&mySettings1.tab, &PerceptualColor::SettingBase::valueChanged);
0148         QSignalSpy spy2(&mySettings1.tab, &PerceptualColor::SettingBase::valueChanged);
0149 
0150         const QString newTab2 = QStringLiteral("differentTestTabInstance");
0151         mySettings2.tab.setValue(newTab2);
0152         mySettings2.tab.setValue(newTab2); // Intentional duplicate
0153         QCOMPARE(mySettings1.tab.value(), newTab2);
0154         QCOMPARE(mySettings2.tab.value(), newTab2);
0155         QVERIFY(spy1.isValid());
0156         // The second call to the setter with an identical value
0157         // should not trigger a signal.
0158         QCOMPARE(spy1.count(), 1);
0159         QVERIFY(spy2.isValid());
0160         // The second call to the setter with an identical value
0161         // should not trigger a signal.
0162         QCOMPARE(spy2.count(), 1);
0163     }
0164 
0165     void testTabExpanded()
0166     {
0167         auto &mySettings = PerceptualSettings::instance();
0168 
0169         const QString newTab1 = QStringLiteral("testTabExpanded");
0170         mySettings.tabExpanded.setValue(newTab1);
0171         QCOMPARE(mySettings.tabExpanded.value(), newTab1);
0172 
0173         QSignalSpy spy(&mySettings.tabExpanded, &PerceptualColor::SettingBase::valueChanged);
0174 
0175         const QString newTab2 = QStringLiteral("differentTestTab");
0176         mySettings.tabExpanded.setValue(newTab2);
0177         mySettings.tabExpanded.setValue(newTab2); // Intentional duplicate
0178         QCOMPARE(mySettings.tabExpanded.value(), newTab2);
0179         QVERIFY(spy.isValid());
0180         // The second call to the setter with an identical value
0181         // should not trigger a signal.
0182         QCOMPARE(spy.count(), 1);
0183     }
0184 
0185     void testInstancesAreIdenticalForTabExpanded()
0186     {
0187         auto &mySettings1 = PerceptualSettings::instance();
0188         auto &mySettings2 = PerceptualSettings::instance();
0189 
0190         const QString newTabExpanded1 = QStringLiteral("testTabExpandedInstance");
0191         mySettings1.tabExpanded.setValue(newTabExpanded1);
0192         QCOMPARE(mySettings1.tabExpanded.value(), newTabExpanded1);
0193         QCOMPARE(mySettings2.tabExpanded.value(), newTabExpanded1);
0194 
0195         QSignalSpy spy1(&mySettings1.tabExpanded, &PerceptualColor::SettingBase::valueChanged);
0196         QSignalSpy spy2(&mySettings2.tabExpanded, &PerceptualColor::SettingBase::valueChanged);
0197 
0198         const QString newTabExpanded2 = QStringLiteral("differentTestTabExpandedInstance");
0199         mySettings2.tabExpanded.setValue(newTabExpanded2);
0200         mySettings2.tabExpanded.setValue(newTabExpanded2); // Intentional duplicate
0201         QCOMPARE(mySettings1.tabExpanded.value(), newTabExpanded2);
0202         QCOMPARE(mySettings2.tabExpanded.value(), newTabExpanded2);
0203         QVERIFY(spy1.isValid());
0204         // The second call to the setter with an identical value
0205         // should not trigger a signal.
0206         QCOMPARE(spy1.count(), 1);
0207         QVERIFY(spy2.isValid());
0208         // The second call to the setter with an identical value
0209         // should not trigger a signal.
0210         QCOMPARE(spy2.count(), 1);
0211     }
0212 
0213 #endif
0214 };
0215 
0216 } // namespace PerceptualColor
0217 
0218 QTEST_MAIN(PerceptualColor::TestPerceptualSettings)
0219 
0220 // The following “include” is necessary because we do not use a header file:
0221 #include "testperceptualsettings.moc"