File indexing completed on 2024-04-14 14:26:48

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"), QStringLiteral("bin"));
0025         addFileDefinition("MultiplePaths", QStringLiteral("first"), QStringLiteral("Description proper"));
0026         addFileDefinition("MultiplePaths", QStringLiteral("second"), QStringLiteral("Description proper"));
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/"), i18n("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"), i18n("Screenshot"));
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(), i18n("Preview"));
0073             package->addFileDefinition("preferred", info.fileName(), QString());
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/"), i18n("User interface"));
0089     }
0090     void pathChanged(KPackage::Package *package) override
0091     {
0092         if (!package->metadata().isValid()) {
0093             return;
0094         }
0095         if (readKPackageTypes(package->metadata()).contains(QStringLiteral("CustomContent"))) {
0096             package->addFileDefinition("customcontentfile",
0097                                        QStringLiteral("customcontent/CustomContentFile.qml"),
0098                                        i18n("Custom file only for packages that contain CustomContent in their servicetypes"));
0099         } else {
0100             package->removeDefinition("customcontentfile");
0101         }
0102     }
0103 };
0104 
0105 void PackageStructureTest::initTestCase()
0106 {
0107     m_packagePath = QFINDTESTDATA("data/testpackage");
0108     ps = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("KPackage/Generic"));
0109     ps.addFileDefinition("mainscript", QStringLiteral("ui/main.qml"), i18n("Main Script File"));
0110     ps.setPath(m_packagePath);
0111 }
0112 
0113 void PackageStructureTest::validStructures()
0114 {
0115     QVERIFY(ps.hasValidStructure());
0116     QVERIFY(!KPackage::Package().hasValidStructure());
0117     QVERIFY(!KPackage::PackageLoader::self()->loadPackage(QStringLiteral("doesNotExist")).hasValidStructure());
0118 }
0119 
0120 void PackageStructureTest::validPackages()
0121 {
0122     QVERIFY(ps.isValid());
0123     QVERIFY(!KPackage::Package().isValid());
0124     QVERIFY(!KPackage::PackageLoader::self()->loadPackage(QStringLiteral("doesNotExist")).isValid());
0125     QVERIFY(NoPrefixes().isValid());
0126 
0127     KPackage::Package p = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("KPackage/Generic"));
0128     p.addFileDefinition("mainscript", QStringLiteral("ui/main.qml"), i18n("Main Script File"));
0129     QVERIFY(!p.isValid());
0130     p.setPath(QStringLiteral("/does/not/exist"));
0131     QVERIFY(!p.isValid());
0132     p.setPath(ps.path());
0133     QVERIFY(p.isValid());
0134 }
0135 
0136 void PackageStructureTest::wallpaperPackage()
0137 {
0138     KPackage::Package p(new Wallpaper);
0139     p.setPath(m_packagePath);
0140     QVERIFY(p.isValid());
0141 
0142     KPackage::Package p2(new Wallpaper);
0143     p2.setPath(m_packagePath + "/contents/images/empty.png");
0144     QVERIFY(p2.isValid());
0145 }
0146 
0147 void PackageStructureTest::copyPerformance()
0148 {
0149     // seed the cache first
0150     ps.filePath("mainscript");
0151 
0152     QBENCHMARK {
0153         KPackage::Package foo(ps);
0154         const QString bar = foo.filePath("mainscript");
0155         Q_UNUSED(bar);
0156     }
0157 }
0158 
0159 void PackageStructureTest::mutateAfterCopy()
0160 {
0161     const bool mainscriptRequired = ps.isRequired("mainscript");
0162     const QStringList imageMimeTypes = ps.mimeTypes("images");
0163     const QStringList defaultMimeTypes = ps.mimeTypes("translations");
0164     const QString packageRoot = ps.defaultPackageRoot();
0165     const bool externalPaths = ps.allowExternalPaths();
0166     const QStringList contentsPrefixPaths = ps.contentsPrefixPaths();
0167     const QList<QByteArray> files = ps.files();
0168     const QList<QByteArray> dirs = ps.directories();
0169 
0170     KPackage::Package copy(ps);
0171 
0172     copy.setRequired("mainscript", !mainscriptRequired);
0173     QCOMPARE(ps.isRequired("mainscript"), mainscriptRequired);
0174     QCOMPARE(copy.isRequired("mainscript"), !mainscriptRequired);
0175 
0176     copy = ps;
0177     const QString copyPackageRoot = packageRoot + "more/";
0178     copy.setDefaultPackageRoot(copyPackageRoot);
0179     QCOMPARE(ps.defaultPackageRoot(), packageRoot);
0180     QCOMPARE(copy.defaultPackageRoot(), copyPackageRoot);
0181 
0182     copy = ps;
0183     copy.setAllowExternalPaths(!externalPaths);
0184     QCOMPARE(ps.allowExternalPaths(), externalPaths);
0185     QCOMPARE(copy.allowExternalPaths(), !externalPaths);
0186 
0187     copy = ps;
0188     QStringList copyContentsPrefixPaths = contentsPrefixPaths;
0189     copyContentsPrefixPaths << QStringLiteral("more/");
0190     copy.setContentsPrefixPaths(copyContentsPrefixPaths);
0191     QCOMPARE(ps.contentsPrefixPaths(), contentsPrefixPaths);
0192     QCOMPARE(copy.contentsPrefixPaths(), copyContentsPrefixPaths);
0193 
0194     copy = ps;
0195     copy.addFileDefinition("nonsense", QStringLiteral("foobar"), QString());
0196     QCOMPARE(ps.files(), files);
0197     QVERIFY(ps.files() != copy.files());
0198 
0199     copy = ps;
0200     copy.addDirectoryDefinition("nonsense", QStringLiteral("foobar"), QString());
0201     QCOMPARE(ps.directories(), dirs);
0202     QVERIFY(ps.directories() != copy.directories());
0203 
0204     copy = ps;
0205     copy.removeDefinition("mainscript");
0206     QCOMPARE(ps.files(), files);
0207     QVERIFY(ps.files() != copy.files());
0208 
0209     copy = ps;
0210     QVERIFY(!imageMimeTypes.isEmpty());
0211     QStringList copyMimeTypes;
0212     copyMimeTypes << imageMimeTypes.first();
0213     copy.setMimeTypes("images", copyMimeTypes);
0214     QCOMPARE(ps.mimeTypes("images"), imageMimeTypes);
0215     QCOMPARE(copy.mimeTypes("images"), copyMimeTypes);
0216 
0217     copy = ps;
0218     QStringList copyDefaultMimeTypes = defaultMimeTypes;
0219     copyDefaultMimeTypes << QStringLiteral("rubbish");
0220     copy.setDefaultMimeTypes(copyDefaultMimeTypes);
0221     QCOMPARE(ps.mimeTypes("translations"), defaultMimeTypes);
0222     QCOMPARE(copy.mimeTypes("translations"), copyDefaultMimeTypes);
0223 }
0224 
0225 void PackageStructureTest::emptyContentsPrefix()
0226 {
0227     NoPrefixes package;
0228     QString path(package.filePath("bin", QStringLiteral("ls")));
0229     // qDebug() << path;
0230     if (QFileInfo::exists(QStringLiteral("/bin/ls"))) { // not Windows
0231         QCOMPARE(path, QStringLiteral("/bin/ls"));
0232     }
0233 }
0234 
0235 void PackageStructureTest::multiplePaths()
0236 {
0237     NoPrefixes package;
0238     QCOMPARE(package.name("MultiplePaths"), QStringLiteral("Description proper"));
0239 }
0240 
0241 void PackageStructureTest::directories()
0242 {
0243     QList<QByteArray> dirs;
0244     dirs << "config"
0245          << "data"
0246          << "images"
0247          << "theme"
0248          << "scripts"
0249          << "translations"
0250          << "ui";
0251 
0252     const QList<QByteArray> psDirs = ps.directories();
0253 
0254     QCOMPARE(dirs.count(), psDirs.count());
0255 
0256     for (const char *dir : psDirs) {
0257         bool found = false;
0258         for (const char *check : std::as_const(dirs)) {
0259             if (qstrcmp(dir, check)) {
0260                 found = true;
0261                 break;
0262             }
0263         }
0264         QVERIFY(found);
0265     }
0266 
0267     for (const char *dir : std::as_const(dirs)) {
0268         bool found = false;
0269         for (const char *check : psDirs) {
0270             if (qstrcmp(dir, check)) {
0271                 found = true;
0272                 break;
0273             }
0274         }
0275         QVERIFY(found);
0276     }
0277 }
0278 
0279 void PackageStructureTest::requiredDirectories()
0280 {
0281     QList<QByteArray> dirs;
0282     QCOMPARE(ps.requiredDirectories(), dirs);
0283 }
0284 
0285 void PackageStructureTest::files()
0286 {
0287     QList<QByteArray> files;
0288     files << "mainconfigui"
0289           << "mainconfigxml"
0290           << "mainscript";
0291 
0292     const QList<QByteArray> psFiles = ps.files();
0293 
0294     // for (int i = 0; i < psFiles.count(); ++i) {
0295     //    qDebug() << psFiles[i];
0296     //}
0297     for (const char *file : psFiles) {
0298         bool found = false;
0299         for (const char *check : std::as_const(files)) {
0300             if (qstrcmp(file, check)) {
0301                 found = true;
0302                 break;
0303             }
0304         }
0305         QVERIFY(found);
0306     }
0307 }
0308 
0309 void PackageStructureTest::requiredFiles()
0310 {
0311     QList<QByteArray> files;
0312     files << "mainscript";
0313 
0314     QList<QByteArray> psFiles = ps.requiredFiles();
0315 
0316     QCOMPARE(files.count(), psFiles.count());
0317     for (int i = 0; i < files.count(); ++i) {
0318         QCOMPARE(files[i], psFiles[i]);
0319     }
0320 }
0321 
0322 void PackageStructureTest::path()
0323 {
0324     QCOMPARE(ps.filePath("images"), QDir(m_packagePath + QLatin1String("/contents/images")).canonicalPath());
0325     QCOMPARE(ps.filePath("theme"), QString());
0326     QCOMPARE(ps.filePath("mainscript"), QFileInfo(m_packagePath + QLatin1String("/contents/ui/main.qml")).canonicalFilePath());
0327 }
0328 
0329 void PackageStructureTest::name()
0330 {
0331     QCOMPARE(ps.name("config"), i18n("Configuration Definitions"));
0332     QCOMPARE(ps.name("mainscript"), i18n("Main Script File"));
0333 }
0334 
0335 void PackageStructureTest::required()
0336 {
0337     QVERIFY(ps.isRequired("mainscript"));
0338 }
0339 
0340 void PackageStructureTest::mimeTypes()
0341 {
0342     QStringList mimeTypes;
0343     mimeTypes << QStringLiteral("image/svg+xml") << QStringLiteral("image/png") << QStringLiteral("image/jpeg");
0344     QCOMPARE(ps.mimeTypes("images"), mimeTypes);
0345     QCOMPARE(ps.mimeTypes("theme"), mimeTypes);
0346 }
0347 
0348 void PackageStructureTest::customContent()
0349 {
0350     KPackage::Package p(new SimpleContent);
0351     p.setPath(QFINDTESTDATA("data/simplecontent"));
0352     QVERIFY(p.isValid());
0353     QCOMPARE(p.filePath("customcontentfile"), QString());
0354 
0355     p.setPath(QFINDTESTDATA("data/customcontent"));
0356     const QString expected = QFINDTESTDATA("data/customcontent") + "/contents/customcontent/CustomContentFile.qml";
0357     QCOMPARE(p.filePath("customcontentfile"), expected);
0358     QVERIFY(p.isValid());
0359 
0360     p.setPath(QFINDTESTDATA("data/simplecontent"));
0361     QVERIFY(p.isValid());
0362     QCOMPARE(p.filePath("customcontentfile"), QString());
0363 }
0364 
0365 QTEST_MAIN(PackageStructureTest)
0366 
0367 #include "moc_packagestructuretest.cpp"
0368 #include "packagestructuretest.moc"