File indexing completed on 2023-09-24 11:42:37

0001 /*
0002     SPDX-FileCopyrightText: 2007 Aaron Seigo <aseigo@kde.org>
0003     SPDX-FileCopyrightText: 2014 Marco Martin <mart@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "packagestructuretest.h"
0009 
0010 #include <KLocalizedString>
0011 #include <QDebug>
0012 
0013 #include "packageloader.h"
0014 #include "packagestructure.h"
0015 #include "private/utils.h"
0016 
0017 class NoPrefixes : public KPackage::Package
0018 {
0019 public:
0020     explicit NoPrefixes()
0021         : KPackage::Package(new KPackage::PackageStructure)
0022     {
0023         setContentsPrefixPaths(QStringList());
0024         addDirectoryDefinition("bin", QStringLiteral("bin"));
0025         addFileDefinition("MultiplePaths", QStringLiteral("first"));
0026         addFileDefinition("MultiplePaths", QStringLiteral("second"));
0027         setPath(QStringLiteral("/"));
0028     }
0029 };
0030 
0031 class Wallpaper : public KPackage::PackageStructure
0032 {
0033     Q_OBJECT
0034 public:
0035     void initPackage(KPackage::Package *package) override
0036     {
0037         package->addDirectoryDefinition("images", QStringLiteral("images/"));
0038 
0039         QStringList mimetypes;
0040         mimetypes << QStringLiteral("image/svg") << QStringLiteral("image/png") << QStringLiteral("image/jpeg") << QStringLiteral("image/jpg");
0041         package->setMimeTypes("images", mimetypes);
0042 
0043         package->setRequired("images", true);
0044         package->addFileDefinition("screenshot", QStringLiteral("screenshot.png"));
0045         package->setAllowExternalPaths(true);
0046     }
0047     void pathChanged(KPackage::Package *package) override
0048     {
0049         static bool guard = false;
0050 
0051         if (guard) {
0052             return;
0053         }
0054 
0055         guard = true;
0056         QString ppath = package->path();
0057         if (ppath.endsWith('/')) {
0058             ppath.chop(1);
0059             if (!QFile::exists(ppath)) {
0060                 ppath = package->path();
0061             }
0062         }
0063 
0064         QFileInfo info(ppath);
0065         const bool isFullPackage = info.isDir();
0066         package->removeDefinition("preferred");
0067         package->setRequired("images", isFullPackage);
0068 
0069         if (isFullPackage) {
0070             package->setContentsPrefixPaths(QStringList() << QStringLiteral("contents/"));
0071         } else {
0072             package->addFileDefinition("screenshot", info.fileName());
0073             package->addFileDefinition("preferred", info.fileName());
0074             package->setContentsPrefixPaths(QStringList());
0075             package->setPath(info.path());
0076         }
0077 
0078         guard = false;
0079     }
0080 };
0081 
0082 class SimpleContent : public KPackage::PackageStructure
0083 {
0084     Q_OBJECT
0085 public:
0086     void initPackage(KPackage::Package *package) override
0087     {
0088         package->addDirectoryDefinition("ui", QStringLiteral("ui/"));
0089     }
0090     void pathChanged(KPackage::Package *package) override
0091     {
0092         if (!package->metadata().isValid()) {
0093             return;
0094         }
0095         if (readKPackageType(package->metadata()) == QStringLiteral("CustomContent")) {
0096             package->addFileDefinition("customcontentfile", QStringLiteral("customcontent/CustomContentFile.qml"));
0097         } else {
0098             package->removeDefinition("customcontentfile");
0099         }
0100     }
0101 };
0102 
0103 void PackageStructureTest::initTestCase()
0104 {
0105     m_packagePath = QFINDTESTDATA("data/testpackage");
0106     ps = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("KPackage/Generic"));
0107     ps.addFileDefinition("mainscript", QStringLiteral("ui/main.qml"));
0108     ps.setPath(m_packagePath);
0109 }
0110 
0111 void PackageStructureTest::validStructures()
0112 {
0113     QVERIFY(ps.hasValidStructure());
0114     QVERIFY(!KPackage::Package().hasValidStructure());
0115     QVERIFY(!KPackage::PackageLoader::self()->loadPackage(QStringLiteral("doesNotExist")).hasValidStructure());
0116 }
0117 
0118 void PackageStructureTest::validPackages()
0119 {
0120     QVERIFY(ps.isValid());
0121     QVERIFY(!KPackage::Package().isValid());
0122     QVERIFY(!KPackage::PackageLoader::self()->loadPackage(QStringLiteral("doesNotExist")).isValid());
0123     QVERIFY(NoPrefixes().isValid());
0124 
0125     KPackage::Package p = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("KPackage/Generic"));
0126     p.addFileDefinition("mainscript", QStringLiteral("ui/main.qml"));
0127     QVERIFY(!p.isValid());
0128     p.setPath(QStringLiteral("/does/not/exist"));
0129     QVERIFY(!p.isValid());
0130     p.setPath(ps.path());
0131     QVERIFY(p.isValid());
0132 }
0133 
0134 void PackageStructureTest::wallpaperPackage()
0135 {
0136     KPackage::Package p(new Wallpaper);
0137     p.setPath(m_packagePath);
0138     QVERIFY(p.isValid());
0139 
0140     KPackage::Package p2(new Wallpaper);
0141     p2.setPath(m_packagePath + "/contents/images/empty.png");
0142     QVERIFY(p2.isValid());
0143 }
0144 
0145 void PackageStructureTest::copyPerformance()
0146 {
0147     // seed the cache first
0148     ps.filePath("mainscript");
0149 
0150     QBENCHMARK {
0151         KPackage::Package foo(ps);
0152         const QString bar = foo.filePath("mainscript");
0153         Q_UNUSED(bar);
0154     }
0155 }
0156 
0157 void PackageStructureTest::mutateAfterCopy()
0158 {
0159     const bool mainscriptRequired = ps.isRequired("mainscript");
0160     const QStringList imageMimeTypes = ps.mimeTypes("images");
0161     const QStringList defaultMimeTypes = ps.mimeTypes("translations");
0162     const QString packageRoot = ps.defaultPackageRoot();
0163     const bool externalPaths = ps.allowExternalPaths();
0164     const QStringList contentsPrefixPaths = ps.contentsPrefixPaths();
0165     const QList<QByteArray> files = ps.files();
0166     const QList<QByteArray> dirs = ps.directories();
0167 
0168     KPackage::Package copy(ps);
0169 
0170     copy.setRequired("mainscript", !mainscriptRequired);
0171     QCOMPARE(ps.isRequired("mainscript"), mainscriptRequired);
0172     QCOMPARE(copy.isRequired("mainscript"), !mainscriptRequired);
0173 
0174     copy = ps;
0175     const QString copyPackageRoot = packageRoot + "more/";
0176     copy.setDefaultPackageRoot(copyPackageRoot);
0177     QCOMPARE(ps.defaultPackageRoot(), packageRoot);
0178     QCOMPARE(copy.defaultPackageRoot(), copyPackageRoot);
0179 
0180     copy = ps;
0181     copy.setAllowExternalPaths(!externalPaths);
0182     QCOMPARE(ps.allowExternalPaths(), externalPaths);
0183     QCOMPARE(copy.allowExternalPaths(), !externalPaths);
0184 
0185     copy = ps;
0186     QStringList copyContentsPrefixPaths = contentsPrefixPaths;
0187     copyContentsPrefixPaths << QStringLiteral("more/");
0188     copy.setContentsPrefixPaths(copyContentsPrefixPaths);
0189     QCOMPARE(ps.contentsPrefixPaths(), contentsPrefixPaths);
0190     QCOMPARE(copy.contentsPrefixPaths(), copyContentsPrefixPaths);
0191 
0192     copy = ps;
0193     copy.addFileDefinition("nonsense", QStringLiteral("foobar"));
0194     QCOMPARE(ps.files(), files);
0195     QVERIFY(ps.files() != copy.files());
0196 
0197     copy = ps;
0198     copy.addDirectoryDefinition("nonsense", QStringLiteral("foobar"));
0199     QCOMPARE(ps.directories(), dirs);
0200     QVERIFY(ps.directories() != copy.directories());
0201 
0202     copy = ps;
0203     copy.removeDefinition("mainscript");
0204     QCOMPARE(ps.files(), files);
0205     QVERIFY(ps.files() != copy.files());
0206 
0207     copy = ps;
0208     QVERIFY(!imageMimeTypes.isEmpty());
0209     QStringList copyMimeTypes;
0210     copyMimeTypes << imageMimeTypes.first();
0211     copy.setMimeTypes("images", copyMimeTypes);
0212     QCOMPARE(ps.mimeTypes("images"), imageMimeTypes);
0213     QCOMPARE(copy.mimeTypes("images"), copyMimeTypes);
0214 
0215     copy = ps;
0216     QStringList copyDefaultMimeTypes = defaultMimeTypes;
0217     copyDefaultMimeTypes << QStringLiteral("rubbish");
0218     copy.setDefaultMimeTypes(copyDefaultMimeTypes);
0219     QCOMPARE(ps.mimeTypes("translations"), defaultMimeTypes);
0220     QCOMPARE(copy.mimeTypes("translations"), copyDefaultMimeTypes);
0221 }
0222 
0223 void PackageStructureTest::emptyContentsPrefix()
0224 {
0225     NoPrefixes package;
0226     QString path(package.filePath("bin", QStringLiteral("ls")));
0227     // qDebug() << path;
0228     if (QFileInfo::exists(QStringLiteral("/bin/ls"))) { // not Windows
0229         QCOMPARE(path, QStringLiteral("/bin/ls"));
0230     }
0231 }
0232 
0233 void PackageStructureTest::directories()
0234 {
0235     QList<QByteArray> dirs;
0236     dirs << "config"
0237          << "data"
0238          << "images"
0239          << "theme"
0240          << "scripts"
0241          << "translations"
0242          << "ui";
0243 
0244     const QList<QByteArray> psDirs = ps.directories();
0245 
0246     QCOMPARE(dirs.count(), psDirs.count());
0247 
0248     for (const char *dir : psDirs) {
0249         bool found = false;
0250         for (const char *check : std::as_const(dirs)) {
0251             if (qstrcmp(dir, check)) {
0252                 found = true;
0253                 break;
0254             }
0255         }
0256         QVERIFY(found);
0257     }
0258 
0259     for (const char *dir : std::as_const(dirs)) {
0260         bool found = false;
0261         for (const char *check : psDirs) {
0262             if (qstrcmp(dir, check)) {
0263                 found = true;
0264                 break;
0265             }
0266         }
0267         QVERIFY(found);
0268     }
0269 }
0270 
0271 void PackageStructureTest::requiredDirectories()
0272 {
0273     QList<QByteArray> dirs;
0274     QCOMPARE(ps.requiredDirectories(), dirs);
0275 }
0276 
0277 void PackageStructureTest::files()
0278 {
0279     QList<QByteArray> files;
0280     files << "mainconfigui"
0281           << "mainconfigxml"
0282           << "mainscript";
0283 
0284     const QList<QByteArray> psFiles = ps.files();
0285 
0286     // for (int i = 0; i < psFiles.count(); ++i) {
0287     //    qDebug() << psFiles[i];
0288     //}
0289     for (const char *file : psFiles) {
0290         bool found = false;
0291         for (const char *check : std::as_const(files)) {
0292             if (qstrcmp(file, check)) {
0293                 found = true;
0294                 break;
0295             }
0296         }
0297         QVERIFY(found);
0298     }
0299 }
0300 
0301 void PackageStructureTest::requiredFiles()
0302 {
0303     QList<QByteArray> files;
0304     files << "mainscript";
0305 
0306     QList<QByteArray> psFiles = ps.requiredFiles();
0307 
0308     QCOMPARE(files.count(), psFiles.count());
0309     for (int i = 0; i < files.count(); ++i) {
0310         QCOMPARE(files[i], psFiles[i]);
0311     }
0312 }
0313 
0314 void PackageStructureTest::path()
0315 {
0316     QCOMPARE(ps.filePath("images"), QDir(m_packagePath + QLatin1String("/contents/images")).canonicalPath());
0317     QCOMPARE(ps.filePath("theme"), QString());
0318     QCOMPARE(ps.filePath("mainscript"), QFileInfo(m_packagePath + QLatin1String("/contents/ui/main.qml")).canonicalFilePath());
0319 }
0320 
0321 void PackageStructureTest::required()
0322 {
0323     QVERIFY(ps.isRequired("mainscript"));
0324 }
0325 
0326 void PackageStructureTest::mimeTypes()
0327 {
0328     QStringList mimeTypes;
0329     mimeTypes << QStringLiteral("image/svg+xml") << QStringLiteral("image/png") << QStringLiteral("image/jpeg");
0330     QCOMPARE(ps.mimeTypes("images"), mimeTypes);
0331     QCOMPARE(ps.mimeTypes("theme"), mimeTypes);
0332 }
0333 
0334 void PackageStructureTest::customContent()
0335 {
0336     KPackage::Package p(new SimpleContent);
0337     p.setPath(QFINDTESTDATA("data/simplecontent"));
0338     QVERIFY(p.isValid());
0339     QCOMPARE(p.filePath("customcontentfile"), QString());
0340 
0341     p.setPath(QFINDTESTDATA("data/customcontent"));
0342     const QString expected = QFINDTESTDATA("data/customcontent") + "/contents/customcontent/CustomContentFile.qml";
0343     QCOMPARE(p.filePath("customcontentfile"), expected);
0344     QVERIFY(p.isValid());
0345 
0346     p.setPath(QFINDTESTDATA("data/simplecontent"));
0347     QVERIFY(p.isValid());
0348     QCOMPARE(p.filePath("customcontentfile"), QString());
0349 }
0350 
0351 QTEST_MAIN(PackageStructureTest)
0352 
0353 #include "moc_packagestructuretest.cpp"
0354 #include "packagestructuretest.moc"