File indexing completed on 2024-05-12 05:13:32

0001 /*
0002   SPDX-FileCopyrightText: 2014-2024 Laurent Montel <montel@kde.org>
0003 
0004   SPDX-License-Identifier: LGPL-2.1-or-later
0005 */
0006 
0007 #include "grantleethemetest.h"
0008 #include "grantleetheme.h"
0009 
0010 #include <QFile>
0011 #include <QPalette>
0012 #include <QProcess>
0013 #include <QRegularExpression>
0014 #include <QStandardPaths>
0015 #include <qtest.h>
0016 
0017 #include <KColorScheme>
0018 #include <KConfigGroup>
0019 #include <KSharedConfig>
0020 
0021 GrantleeThemeTest::GrantleeThemeTest(QObject *parent)
0022     : QObject(parent)
0023 {
0024     QStandardPaths::setTestModeEnabled(true);
0025 
0026     // Point the test to our dummy icon theme
0027     KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("Icons"));
0028     cg.writeEntry("Theme", "dummyTheme");
0029     qputenv("XDG_DATA_DIRS", GRANTLEETHEME_DATA_DIR);
0030 }
0031 
0032 GrantleeThemeTest::~GrantleeThemeTest() = default;
0033 
0034 void GrantleeThemeTest::shouldHaveDefaultValue()
0035 {
0036     GrantleeTheme::Theme theme;
0037     QVERIFY(theme.description().isEmpty());
0038     QVERIFY(theme.themeFilename().isEmpty());
0039     QVERIFY(theme.name().isEmpty());
0040     QVERIFY(theme.displayExtraVariables().isEmpty());
0041     QVERIFY(theme.dirName().isEmpty());
0042     QVERIFY(theme.absolutePath().isEmpty());
0043     QVERIFY(theme.author().isEmpty());
0044     QVERIFY(theme.authorEmail().isEmpty());
0045     QVERIFY(!theme.isValid());
0046 }
0047 
0048 void GrantleeThemeTest::shouldInvalidWhenPathIsNotValid()
0049 {
0050     const QString themePath(QStringLiteral("/foo"));
0051     const QString dirName(QStringLiteral("name"));
0052     const QString defaultDesktopFileName(QStringLiteral("bla"));
0053     GrantleeTheme::Theme theme(themePath, dirName, defaultDesktopFileName);
0054     QVERIFY(theme.description().isEmpty());
0055     QVERIFY(theme.themeFilename().isEmpty());
0056     QVERIFY(theme.name().isEmpty());
0057     QVERIFY(theme.displayExtraVariables().isEmpty());
0058     QVERIFY(!theme.dirName().isEmpty());
0059     QVERIFY(!theme.absolutePath().isEmpty());
0060     QVERIFY(theme.author().isEmpty());
0061     QVERIFY(theme.authorEmail().isEmpty());
0062     QVERIFY(!theme.isValid());
0063 }
0064 
0065 void GrantleeThemeTest::shouldLoadTheme_data()
0066 {
0067     QTest::addColumn<QString>("dirname");
0068     QTest::addColumn<QString>("filename");
0069     QTest::addColumn<bool>("isvalid");
0070     QTest::addColumn<QStringList>("displayExtraVariables");
0071 
0072     QTest::newRow("valid theme") << QStringLiteral("valid") << QStringLiteral("filename.testdesktop") << true << QStringList();
0073     QTest::newRow("not existing theme") << QStringLiteral("notvalid") << QStringLiteral("filename.testdesktop") << false << QStringList();
0074     QStringList extraVariables;
0075     extraVariables << QStringLiteral("foo") << QStringLiteral("bla");
0076     QTest::newRow("valid with extra variable") << QStringLiteral("valid-with-extravariables") << QStringLiteral("filename.testdesktop") << true
0077                                                << extraVariables;
0078 }
0079 
0080 void GrantleeThemeTest::shouldLoadTheme()
0081 {
0082     QFETCH(QString, dirname);
0083     QFETCH(QString, filename);
0084     QFETCH(bool, isvalid);
0085     QFETCH(QStringList, displayExtraVariables);
0086 
0087     GrantleeTheme::Theme theme(QStringLiteral(GRANTLEETHEME_DATA_DIR "/themes/") + dirname, dirname, filename);
0088     QCOMPARE(theme.isValid(), isvalid);
0089     QCOMPARE(theme.displayExtraVariables(), displayExtraVariables);
0090     QCOMPARE(theme.dirName(), dirname);
0091 }
0092 
0093 bool GrantleeThemeTest::validateHtml(const QString &themePath, const QString &name, const QString &html)
0094 {
0095     const QString outFileName = themePath + QStringLiteral("/%1.out").arg(name);
0096     const QString htmlFileName = themePath + QStringLiteral("/%1.out.html").arg(name);
0097     QFile outFile(outFileName);
0098     if (!outFile.open(QIODevice::WriteOnly)) {
0099         qDebug() << "impossible to open " << outFile.fileName();
0100         return false;
0101     }
0102     outFile.write(html.toUtf8());
0103     outFile.close();
0104 
0105     // validate xml and pretty-print for comparison
0106     // TODO add proper cmake check for xmllint and diff
0107     const QStringList args =
0108         {QStringLiteral("--format"), QStringLiteral("--encode"), QStringLiteral("UTF8"), QStringLiteral("--output"), htmlFileName, outFileName};
0109 
0110     const int result = QProcess::execute(QStringLiteral("xmllint"), args);
0111     return result == 0;
0112 }
0113 
0114 bool GrantleeThemeTest::compareHtml(const QString &generatedTheme, const QString &themePath, const QString &name)
0115 {
0116     const QString htmlFileName = generatedTheme + QStringLiteral("/%1.out.html").arg(name);
0117     const QString referenceFileName = themePath + QStringLiteral("/%1_expected.html").arg(name);
0118 
0119     // get rid of system dependent or random paths
0120     {
0121         QFile f(htmlFileName);
0122         if (!f.open(QIODevice::ReadOnly)) {
0123             return false;
0124         }
0125         QString content = QString::fromUtf8(f.readAll());
0126         f.close();
0127         content.replace(QRegularExpression(QLatin1StringView("\"file:[^\"]*[/(?:%2F)]([^\"/(?:%2F)]*)\"")), QStringLiteral("\"file:\\1\""));
0128         if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
0129             return false;
0130         }
0131         f.write(content.toUtf8());
0132         f.close();
0133     }
0134 
0135     // compare to reference file
0136     const QStringList args = {QStringLiteral("-u"), referenceFileName, htmlFileName};
0137 
0138     QProcess proc;
0139     proc.setProcessChannelMode(QProcess::ForwardedChannels);
0140     proc.start(QStringLiteral("diff"), args);
0141     if (!proc.waitForFinished()) {
0142         return false;
0143     }
0144 
0145     return proc.exitCode() == 0;
0146 }
0147 
0148 void GrantleeThemeTest::testRenderTemplate_data()
0149 {
0150     QTest::addColumn<QString>("dirname");
0151     QTest::addColumn<bool>("isValid");
0152     QTest::addColumn<QString>("filename");
0153     QTest::addColumn<QString>("templateBasename");
0154 
0155     QTest::newRow("valid theme") << QStringLiteral("valid") << true << QStringLiteral("filename.testdesktop") << QStringLiteral("header");
0156     QTest::newRow("invalid theme") << QStringLiteral("invalid") << false << QStringLiteral("filename.testdesktop") << QString();
0157     QTest::newRow("color") << QStringLiteral("color") << true << QStringLiteral("color.testdesktop") << QStringLiteral("color");
0158 }
0159 
0160 void GrantleeThemeTest::testRenderTemplate()
0161 {
0162     QFETCH(QString, dirname);
0163     QFETCH(bool, isValid);
0164     QFETCH(QString, filename);
0165     QFETCH(QString, templateBasename);
0166 
0167     const QString themePath = QStringLiteral(GRANTLEETHEME_DATA_DIR "/themes/") + dirname;
0168     const QString themeBinaryPath = QStringLiteral(GRANTLEETHEME_DATA_BUILD_DIR "/themes/") + dirname;
0169     QDir().mkpath(themeBinaryPath);
0170 
0171     QVariantHash data;
0172     data[QStringLiteral("icon")] = QStringLiteral("kde");
0173     data[QStringLiteral("name")] = QStringLiteral("KMail");
0174     data[QStringLiteral("subtitle")] = QStringLiteral("...just rocks!");
0175     data[QStringLiteral("title")] = QStringLiteral("Something's going on");
0176     data[QStringLiteral("subtext")] = QStringLiteral("Please wait, it will be over soon.");
0177 
0178     QPalette pal;
0179     pal.setColor(QPalette::Button, Qt::red);
0180     pal.setColor(QPalette::Active, QPalette::Base, Qt::red);
0181     pal.setColor(QPalette::Inactive, QPalette::Base, Qt::green);
0182     pal.setColor(QPalette::Disabled, QPalette::Base, Qt::blue);
0183     data[QStringLiteral("pal")] = QVariant::fromValue(pal);
0184     data[QStringLiteral("colorScheme")] = QVariant::fromValue(KColorScheme(QPalette::Normal, KColorScheme::View));
0185 
0186     GrantleeTheme::Theme theme(themePath, dirname, filename);
0187     QCOMPARE(theme.isValid(), isValid);
0188 
0189     if (isValid) {
0190         const QString result = theme.render(templateBasename + QStringLiteral(".html"), data);
0191 
0192         QVERIFY(validateHtml(themeBinaryPath, templateBasename, result));
0193         QVERIFY(compareHtml(themeBinaryPath, themePath, templateBasename));
0194 
0195         QFile::remove(themeBinaryPath + QLatin1Char('/') + templateBasename + QStringLiteral(".out"));
0196         QFile::remove(themeBinaryPath + QLatin1Char('/') + templateBasename + QStringLiteral(".out.html"));
0197     }
0198 }
0199 
0200 QTEST_GUILESS_MAIN(GrantleeThemeTest)
0201 
0202 #include "moc_grantleethemetest.cpp"