File indexing completed on 2024-09-15 12:01:54
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"