File indexing completed on 2024-04-28 15:22:15

0001 /*
0002     This file is part of the KDE KFileMetaData project
0003     SPDX-FileCopyrightText: 2014 Vishesh Handa <me@vhanda.in>
0004     SPDX-FileCopyrightText: 2017 Igor Poboiko <igor.poboiko@gmail.com>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-or-later
0007 */
0008 
0009 #include <QObject>
0010 #include <QTest>
0011 #include <QDebug>
0012 
0013 #include "extractorcollection.h"
0014 
0015 namespace KFileMetaData {
0016 
0017 class ExtractorCollectionTest : public QObject
0018 {
0019     Q_OBJECT
0020 private Q_SLOTS:
0021     void testFetchExtractors()
0022     {
0023         QCoreApplication::setLibraryPaths({QCoreApplication::applicationDirPath()});
0024         ExtractorCollection collection;
0025         QVERIFY(collection.fetchExtractors("unknown/mimetype").isEmpty());
0026         QVERIFY(!collection.fetchExtractors("text/plain").isEmpty());
0027     }
0028 
0029     void testMultipleExtractorCollections()
0030     {
0031         QCoreApplication::setLibraryPaths({QCoreApplication::applicationDirPath()});
0032         ExtractorCollection collection;
0033         QVERIFY(collection.fetchExtractors("unknown/mimetype").isEmpty());
0034         QVERIFY(!collection.fetchExtractors("text/plain").isEmpty());
0035         ExtractorCollection collection2;
0036         QVERIFY(collection.fetchExtractors("unknown/mimetype").isEmpty());
0037         QVERIFY(!collection.fetchExtractors("text/plain").isEmpty());
0038         QVERIFY(collection2.fetchExtractors("unknown/mimetype").isEmpty());
0039         QVERIFY(!collection2.fetchExtractors("text/plain").isEmpty());
0040     }
0041 
0042     void testMimeInheritance()
0043     {
0044         QCoreApplication::setLibraryPaths({QCoreApplication::applicationDirPath()});
0045         ExtractorCollection collection;
0046 
0047         auto textExtractors = collection.fetchExtractors("text/plain");
0048         QVERIFY(!textExtractors.isEmpty());
0049 
0050         auto xmlExtractors = collection.fetchExtractors("application/xml");
0051         QVERIFY(!xmlExtractors.isEmpty());
0052 
0053         // Verify the generic "text/plain" extractor is not used for "application/xml"
0054         for (auto extractor : textExtractors) {
0055             QVERIFY(!xmlExtractors.contains(extractor));
0056         }
0057     }
0058 
0059     void testBestMatching()
0060     {
0061         QCoreApplication::setLibraryPaths({QCoreApplication::applicationDirPath()});
0062         ExtractorCollection collection;
0063 
0064         auto textExtractors = collection.fetchExtractors("text/plain");
0065         // "application/mathml+xml" is "sub-class-of" "application/xml" (i.e. inherits it),
0066         // according to the shared-mime-info database
0067         auto xmlSubtypeExtractors = collection.fetchExtractors("application/mathml+xml");
0068         QVERIFY(!xmlSubtypeExtractors.isEmpty());
0069 
0070         // Verify the generic "text/plain" extractor is also not used for
0071         // types inherited from "application/xml"
0072         for (auto extractor : textExtractors) {
0073             QVERIFY(!xmlSubtypeExtractors.contains(extractor));
0074         }
0075     }
0076 
0077     void testExtractorMetadata()
0078     {
0079         QCoreApplication::setLibraryPaths({QCoreApplication::applicationDirPath()});
0080         ExtractorCollection collection;
0081 
0082         auto allExtractors = collection.allExtractors();
0083 
0084         for (auto extractor : allExtractors) {
0085             auto exProperties = extractor->extractorProperties();
0086             if (exProperties.isEmpty()) {
0087                 qWarning() << "Extractor has no property data, please add it! - (Extractor mimetypes:"
0088                            << extractor->mimetypes().join(", ") + ')';
0089                 continue;
0090             }
0091 
0092             // Verify properties for every supported mimetype
0093             auto propMimetypesJson = exProperties["MimeTypes"];
0094             const QStringList propMimeList = propMimetypesJson.toMap().keys();
0095             QSet<QString> propMimetypes(propMimeList.begin(), propMimeList.end());
0096 
0097             const QStringList extractedMimes = extractor->mimetypes();
0098             QSet<QString> supportedMimetypes(extractedMimes.begin(), extractedMimes.end());
0099             QVERIFY2(!exProperties["Name"].toString().isEmpty(), "Missing \"Name\" property");
0100             QVERIFY2(!exProperties["Id"].toString().isEmpty(),   "Missing \"Id\" property");
0101 
0102             if (propMimetypes == supportedMimetypes) {
0103                 continue;
0104             }
0105 
0106             auto diff = propMimetypes - supportedMimetypes;
0107             if (!diff.isEmpty()) {
0108                 for (auto mimetype : diff.values()) {
0109                     auto mimetypeProp = propMimetypesJson.toMap()[mimetype];
0110                     auto runtimedep = mimetypeProp.toMap()["HasRuntimeDependency"];
0111                     if (runtimedep.isValid() && runtimedep.toInt()) {
0112                         diff.remove(mimetype);
0113                     }
0114                 }
0115 
0116                 if (!diff.isEmpty()) {
0117                     qWarning() << exProperties["Name"].toString()
0118                                << exProperties["Id"].toString()
0119                                << "has extraneous properties for these mimetypes:" << diff.values().join(", ");
0120                 }
0121             }
0122 
0123             diff = supportedMimetypes - propMimetypes;
0124             if (!diff.isEmpty()) {
0125                 qWarning() << exProperties["Name"].toString()
0126                            << exProperties["Id"].toString()
0127                            << "has no properties for these mimetypes:" + diff.values().join(", ");
0128             }
0129         }
0130     }
0131 };
0132 
0133 }
0134 
0135 QTEST_GUILESS_MAIN(KFileMetaData::ExtractorCollectionTest)
0136 
0137 #include "extractorcollectiontest.moc"