File indexing completed on 2024-05-19 16:37:10

0001 /*
0002     SPDX-FileCopyrightText: 2016 Marco Martin <mart@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "themetest.h"
0008 #include "../src/plasma/private/svg_p.h"
0009 #include <QApplication>
0010 #include <QSignalSpy>
0011 #include <QStandardPaths>
0012 
0013 #include <KConfigGroup>
0014 #include <KIconLoader>
0015 #include <KIconTheme>
0016 #include <KWindowSystem>
0017 #include <KX11Extras>
0018 
0019 #include <config-plasma.h>
0020 #if HAVE_X11
0021 #include <KSelectionOwner>
0022 #endif
0023 #include <array>
0024 
0025 QString cacheIdHash(const Plasma::SvgPrivate::CacheId &id)
0026 {
0027     static const uint seed = 0x9e3779b9;
0028     std::array<size_t, 10> parts = {
0029         ::qHash(id.width),
0030         ::qHash(id.height),
0031         ::qHash(id.elementName),
0032         ::qHash(id.filePath),
0033         ::qHash(id.status),
0034         ::qHash(id.devicePixelRatio),
0035         ::qHash(id.scaleFactor),
0036         ::qHash(id.colorGroup),
0037         ::qHash(id.extraFlags),
0038         ::qHash(id.lastModified),
0039     };
0040     return QString::number(qHashRange(parts.begin(), parts.end(), seed));
0041 }
0042 
0043 void ThemeTest::initTestCase()
0044 {
0045     // make our theme in search path
0046     qputenv("XDG_DATA_DIRS", QByteArray(qgetenv("XDG_DATA_DIRS") + ":" + QFINDTESTDATA("data").toLocal8Bit()));
0047 
0048     // set default icon theme to test-theme
0049     QStandardPaths::setTestModeEnabled(true);
0050 
0051     m_theme = new Plasma::Theme("testtheme", this);
0052     QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
0053 
0054     if (!QDir(configPath).mkpath(QStringLiteral("."))) {
0055         qFatal("Failed to create test configuration directory.");
0056     }
0057 
0058     QFile::remove(configPath);
0059 
0060     QIcon::setThemeSearchPaths(QStringList() << QFINDTESTDATA("data/icons"));
0061 
0062     KConfigGroup plasmaConfig(KSharedConfig::openConfig("plasmarc"), "Theme");
0063     plasmaConfig.writeEntry("name", "default");
0064     m_svg = new Plasma::Svg();
0065 
0066     KIconTheme::forceThemeForTests("test-theme");
0067     KSharedConfig::openConfig()->reparseConfiguration();
0068     KIconTheme::reconfigure();
0069     KIconLoader::global()->reconfigure(QString());
0070 }
0071 
0072 void ThemeTest::cleanupTestCase()
0073 {
0074     //    m_testIconsDir.removeRecursively();
0075     delete m_svg;
0076 }
0077 
0078 void ThemeTest::loadSvgIcon()
0079 {
0080     const auto *iconTheme = KIconLoader::global()->theme();
0081     QString iconPath;
0082     if (iconTheme) {
0083         iconPath = iconTheme->iconPath(QLatin1String("konversation.svg"), 48, KIconLoader::MatchBest);
0084     }
0085 
0086     QVERIFY(iconTheme);
0087     QVERIFY(iconTheme->isValid());
0088     QVERIFY2(QFile::exists(iconPath), qPrintable(iconPath));
0089     m_svg->setImagePath(iconPath);
0090     QVERIFY(m_svg->isValid());
0091 
0092     m_svg->pixmap(); // trigger the SVG being loaded
0093 
0094     QFileInfo info(iconPath);
0095 
0096     QString cacheId = cacheIdHash(Plasma::SvgPrivate::CacheId{48,
0097                                                               48,
0098                                                               iconPath,
0099                                                               QString(),
0100                                                               m_svg->status(),
0101                                                               m_svg->devicePixelRatio(),
0102                                                               m_svg->scaleFactor(),
0103                                                               m_svg->colorGroup(),
0104                                                               0,
0105                                                               static_cast<uint>(info.lastModified().toSecsSinceEpoch())});
0106 
0107     QPixmap result;
0108     QVERIFY(m_svg->theme()->findInCache(cacheId, result, info.lastModified().toSecsSinceEpoch()));
0109 
0110     QSignalSpy spy(m_svg, SIGNAL(repaintNeeded()));
0111     QVERIFY(spy.isValid());
0112 
0113     KIconTheme::forceThemeForTests("test-theme-two");
0114     // KIconloader needs changesto be emitted manually, ouch.
0115     for (int i = 0; i < KIconLoader::LastGroup; i++) {
0116         KIconLoader::emitChange(KIconLoader::Group(i));
0117     }
0118 
0119     spy.wait();
0120     // Svg emitting repaintNeeded when something changes in KIconLoader means the svg loaded an icon
0121     QVERIFY(spy.count() == 1);
0122 
0123     QVERIFY(!m_svg->theme()->findInCache(cacheId, result));
0124 }
0125 
0126 void ThemeTest::testThemeConfig_data()
0127 {
0128     QTest::addColumn<QString>("themeName");
0129 
0130     QTest::addRow("new metadata style theme") << QStringLiteral("testtheme");
0131 #if PLASMA_BUILD_DEPRECATED_SINCE(5, 86)
0132     QTest::addRow("old metadata format theme") << QStringLiteral("test_old_metadata_format_theme");
0133 #endif
0134 }
0135 
0136 void ThemeTest::testThemeConfig()
0137 {
0138     QFETCH(QString, themeName);
0139     auto theme = std::make_unique<Plasma::Theme>(themeName, this);
0140     QCOMPARE(theme->backgroundContrastEnabled(), true);
0141     QCOMPARE(theme->backgroundContrast(), 0.23);
0142 }
0143 
0144 void ThemeTest::testColors()
0145 {
0146     QCOMPARE(m_theme->color(Plasma::Theme::TextColor, Plasma::Theme::NormalColorGroup), QColor(49, 54, 59));
0147     QCOMPARE(m_theme->color(Plasma::Theme::BackgroundColor, Plasma::Theme::NormalColorGroup), QColor(239, 240, 241));
0148     QCOMPARE(m_theme->color(Plasma::Theme::HighlightColor, Plasma::Theme::NormalColorGroup), QColor(61, 174, 230));
0149     QCOMPARE(m_theme->color(Plasma::Theme::HoverColor, Plasma::Theme::NormalColorGroup), QColor(61, 174, 230));
0150     QCOMPARE(m_theme->color(Plasma::Theme::FocusColor, Plasma::Theme::NormalColorGroup), QColor(30, 146, 255));
0151     QCOMPARE(m_theme->color(Plasma::Theme::LinkColor, Plasma::Theme::NormalColorGroup), QColor(61, 174, 230));
0152     QCOMPARE(m_theme->color(Plasma::Theme::VisitedLinkColor, Plasma::Theme::NormalColorGroup), QColor(61, 174, 230));
0153     QCOMPARE(m_theme->color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::NormalColorGroup), QColor(252, 252, 252));
0154     QCOMPARE(m_theme->color(Plasma::Theme::PositiveTextColor, Plasma::Theme::NormalColorGroup), QColor(17, 209, 22));
0155     QCOMPARE(m_theme->color(Plasma::Theme::NeutralTextColor, Plasma::Theme::NormalColorGroup), QColor(201, 206, 59));
0156     QCOMPARE(m_theme->color(Plasma::Theme::NegativeTextColor, Plasma::Theme::NormalColorGroup), QColor(237, 21, 21));
0157 
0158     QCOMPARE(m_theme->color(Plasma::Theme::TextColor, Plasma::Theme::ButtonColorGroup), QColor(49, 54, 59));
0159     QCOMPARE(m_theme->color(Plasma::Theme::BackgroundColor, Plasma::Theme::ButtonColorGroup), QColor(239, 240, 241));
0160     QCOMPARE(m_theme->color(Plasma::Theme::HighlightColor, Plasma::Theme::ButtonColorGroup), QColor(61, 174, 230));
0161     QCOMPARE(m_theme->color(Plasma::Theme::HoverColor, Plasma::Theme::ButtonColorGroup), QColor(61, 174, 230));
0162     QCOMPARE(m_theme->color(Plasma::Theme::FocusColor, Plasma::Theme::ButtonColorGroup), QColor(30, 146, 255));
0163     QCOMPARE(m_theme->color(Plasma::Theme::LinkColor, Plasma::Theme::ButtonColorGroup), QColor(61, 174, 230));
0164     QCOMPARE(m_theme->color(Plasma::Theme::VisitedLinkColor, Plasma::Theme::ButtonColorGroup), QColor(61, 174, 230));
0165     QCOMPARE(m_theme->color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::ButtonColorGroup), QColor(252, 252, 252));
0166     QCOMPARE(m_theme->color(Plasma::Theme::PositiveTextColor, Plasma::Theme::ButtonColorGroup), QColor(17, 209, 23));
0167     QCOMPARE(m_theme->color(Plasma::Theme::NeutralTextColor, Plasma::Theme::ButtonColorGroup), QColor(201, 206, 60));
0168     QCOMPARE(m_theme->color(Plasma::Theme::NegativeTextColor, Plasma::Theme::ButtonColorGroup), QColor(237, 21, 22));
0169 
0170     QCOMPARE(m_theme->color(Plasma::Theme::TextColor, Plasma::Theme::ViewColorGroup), QColor(49, 54, 59));
0171     QCOMPARE(m_theme->color(Plasma::Theme::BackgroundColor, Plasma::Theme::ViewColorGroup), QColor(252, 252, 252));
0172     QCOMPARE(m_theme->color(Plasma::Theme::HighlightColor, Plasma::Theme::ViewColorGroup), QColor(61, 174, 230));
0173     QCOMPARE(m_theme->color(Plasma::Theme::HoverColor, Plasma::Theme::ViewColorGroup), QColor(61, 174, 230));
0174     QCOMPARE(m_theme->color(Plasma::Theme::FocusColor, Plasma::Theme::ViewColorGroup), QColor(30, 146, 255));
0175     QCOMPARE(m_theme->color(Plasma::Theme::LinkColor, Plasma::Theme::ViewColorGroup), QColor(61, 174, 230));
0176     QCOMPARE(m_theme->color(Plasma::Theme::VisitedLinkColor, Plasma::Theme::ViewColorGroup), QColor(61, 174, 230));
0177     QCOMPARE(m_theme->color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::ViewColorGroup), QColor(252, 252, 252));
0178     QCOMPARE(m_theme->color(Plasma::Theme::PositiveTextColor, Plasma::Theme::ViewColorGroup), QColor(17, 209, 24));
0179     QCOMPARE(m_theme->color(Plasma::Theme::NeutralTextColor, Plasma::Theme::ViewColorGroup), QColor(201, 206, 61));
0180     QCOMPARE(m_theme->color(Plasma::Theme::NegativeTextColor, Plasma::Theme::ViewColorGroup), QColor(237, 21, 23));
0181 
0182     QCOMPARE(m_theme->color(Plasma::Theme::TextColor, Plasma::Theme::ComplementaryColorGroup), QColor(239, 240, 241));
0183     QCOMPARE(m_theme->color(Plasma::Theme::BackgroundColor, Plasma::Theme::ComplementaryColorGroup), QColor(49, 54, 59));
0184     QCOMPARE(m_theme->color(Plasma::Theme::HighlightColor, Plasma::Theme::ComplementaryColorGroup), QColor(61, 174, 230));
0185     QCOMPARE(m_theme->color(Plasma::Theme::HoverColor, Plasma::Theme::ComplementaryColorGroup), QColor(71, 174, 230));
0186     QCOMPARE(m_theme->color(Plasma::Theme::FocusColor, Plasma::Theme::ComplementaryColorGroup), QColor(40, 146, 255));
0187     QCOMPARE(m_theme->color(Plasma::Theme::LinkColor, Plasma::Theme::ComplementaryColorGroup), QColor(71, 174, 230));
0188     QCOMPARE(m_theme->color(Plasma::Theme::VisitedLinkColor, Plasma::Theme::ComplementaryColorGroup), QColor(71, 174, 230));
0189     QCOMPARE(m_theme->color(Plasma::Theme::HighlightedTextColor, Plasma::Theme::ComplementaryColorGroup), QColor(252, 252, 252));
0190     QCOMPARE(m_theme->color(Plasma::Theme::PositiveTextColor, Plasma::Theme::ComplementaryColorGroup), QColor(17, 209, 25));
0191     QCOMPARE(m_theme->color(Plasma::Theme::NeutralTextColor, Plasma::Theme::ComplementaryColorGroup), QColor(201, 206, 62));
0192     QCOMPARE(m_theme->color(Plasma::Theme::NegativeTextColor, Plasma::Theme::ComplementaryColorGroup), QColor(237, 21, 24));
0193 }
0194 
0195 void ThemeTest::testCompositingChange()
0196 {
0197     // this test simulates the compositing change on X11
0198 #if HAVE_X11
0199     if (!KWindowSystem::isPlatformX11()) {
0200         QSKIP("Test is only for X11");
0201     }
0202     QVERIFY(!KX11Extras::compositingActive());
0203 
0204     // image path should give us an opaque variant
0205     QVERIFY(m_theme->imagePath(QStringLiteral("element")).endsWith(QLatin1String("/desktoptheme/testtheme/opaque/element.svg")));
0206 
0207     QSignalSpy themeChangedSpy(m_theme, &Plasma::Theme::themeChanged);
0208     QVERIFY(themeChangedSpy.isValid());
0209 
0210     // fake the compositor
0211     QSignalSpy compositingChangedSpy(KX11Extras::self(), &KX11Extras::compositingChanged);
0212     QVERIFY(compositingChangedSpy.isValid());
0213     std::unique_ptr<KSelectionOwner> compositorSelection(new KSelectionOwner("_NET_WM_CM_S0"));
0214     QSignalSpy claimedSpy(compositorSelection.get(), &KSelectionOwner::claimedOwnership);
0215     QVERIFY(claimedSpy.isValid());
0216     compositorSelection->claim(true);
0217     QVERIFY(claimedSpy.wait());
0218 
0219     QCOMPARE(compositingChangedSpy.count(), 1);
0220     QVERIFY(KX11Extras::compositingActive());
0221     QVERIFY(themeChangedSpy.wait());
0222     QCOMPARE(themeChangedSpy.count(), 1);
0223     QVERIFY(m_theme->imagePath(QStringLiteral("element")).endsWith(QLatin1String("/desktoptheme/testtheme/element.svg")));
0224 
0225     // remove compositor again
0226     compositorSelection.reset();
0227     QVERIFY(compositingChangedSpy.wait());
0228     QCOMPARE(compositingChangedSpy.count(), 2);
0229     QVERIFY(!KX11Extras::compositingActive());
0230     QVERIFY(themeChangedSpy.wait());
0231     QCOMPARE(themeChangedSpy.count(), 2);
0232     QVERIFY(m_theme->imagePath(QStringLiteral("element")).endsWith(QLatin1String("/desktoptheme/testtheme/opaque/element.svg")));
0233 #endif
0234 }
0235 
0236 QTEST_MAIN(ThemeTest)
0237 
0238 #include "moc_themetest.cpp"