summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDavid Faure <faure@kde.org>2012-02-18 16:00:09 +0100
committerQt by Nokia <qt-info@nokia.com>2012-02-18 22:19:43 +0100
commitb164911b7f0efd81ec33325405b88bff8b2334d0 (patch)
treeea4c2eb39f3ae8edb90b8255ffe3ee1b14806ab7 /tests
parent87fcbd82fc679715853e5261f8f0194a80c10b76 (diff)
Import QMimeType / QMimeDatabase into QtCore.
History of the development before the import: ssh://codereview.qt-project.org/playground/mimetypes.git Mimetype definitions come from shared-mime-info where available (UNIX systems), loaded using a mmap'ed binary cache generated by update-mime-database. As a fallback if no cache is found, we parse the raw XML files otherwise. This makes the MIME type support fast and with very low memory usage on UNIX, and it makes it easy to use on Windows (no dependency on shared-mime-info, Qt even includes a freedesktop.xml file to use if none are found on the system). Change-Id: I27b05008216ff936dc463bd80d3893422bfb940e Reviewed-by: Richard J. Moore <rich@kde.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/corelib.pro1
-rw-r--r--tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp7
-rw-r--r--tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp1
-rw-r--r--tests/auto/corelib/mimetypes/mimetypes.pro8
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro12
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp56
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro14
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp51
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro3
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp829
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h99
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/yast2-metapackage-handler-mimetypes.xml15
-rw-r--r--tests/auto/corelib/mimetypes/qmimetype/qmimetype.pro7
-rw-r--r--tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp257
14 files changed, 1358 insertions, 2 deletions
diff --git a/tests/auto/corelib/corelib.pro b/tests/auto/corelib/corelib.pro
index 4f284ac21e..a85a385f80 100644
--- a/tests/auto/corelib/corelib.pro
+++ b/tests/auto/corelib/corelib.pro
@@ -7,6 +7,7 @@ SUBDIRS=\
itemmodels \
json \
kernel \
+ mimetypes \
plugin \
statemachine \
thread \
diff --git a/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp b/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp
index ad61db51d6..d5d490dc29 100644
--- a/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp
+++ b/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp
@@ -403,8 +403,11 @@ void tst_QDirIterator::iterateResource()
QDirIterator it(dirName, nameFilters, filters, flags);
QStringList list;
- while (it.hasNext())
- list << it.next();
+ while (it.hasNext()) {
+ const QString dir = it.next();
+ if (!dir.startsWith(":/qt-project.org"))
+ list << dir;
+ }
list.sort();
QStringList sortedEntries = entries;
diff --git a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp
index fa72083dcc..796282d6d8 100644
--- a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp
+++ b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp
@@ -92,6 +92,7 @@ void tst_QResourceEngine::checkStructure_data()
<< QString()
<< (QStringList() << "search_file.txt")
<< (QStringList() << QLatin1String("aliasdir") << QLatin1String("otherdir")
+ << QLatin1String("qt-project.org")
<< QLatin1String("runtime_resource")
<< QLatin1String("searchpath1") << QLatin1String("searchpath2")
<< QLatin1String("secondary_root")
diff --git a/tests/auto/corelib/mimetypes/mimetypes.pro b/tests/auto/corelib/mimetypes/mimetypes.pro
new file mode 100644
index 0000000000..9063d677e7
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/mimetypes.pro
@@ -0,0 +1,8 @@
+TEMPLATE=subdirs
+
+SUBDIRS = \
+ qmimetype \
+ qmimedatabase
+
+!contains(QT_CONFIG, private_tests): SUBDIRS -= \
+ qmimetype
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro
new file mode 100644
index 0000000000..815401ce1e
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro
@@ -0,0 +1,12 @@
+CONFIG += testcase parallel_test
+
+TARGET = tst_qmimedatabase-cache
+
+QT = core testlib concurrent
+
+SOURCES = tst_qmimedatabase-cache.cpp
+HEADERS = ../tst_qmimedatabase.h
+
+DEFINES += SRCDIR='"\\"$$PWD/../\\""'
+
+*-g++*:QMAKE_CXXFLAGS += -W -Wall -Wextra -Werror -Wshadow -Wno-long-long -Wnon-virtual-dtor
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp
new file mode 100644
index 0000000000..205331d4dd
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../tst_qmimedatabase.h"
+#include <QDir>
+#include <QFile>
+#include <QtTest/QtTest>
+#include <qstandardpaths.h>
+
+#include "../tst_qmimedatabase.cpp"
+
+tst_QMimeDatabase::tst_QMimeDatabase()
+{
+ QDir here = QDir::currentPath();
+ const QString tempMime = here.absolutePath() + QString::fromLatin1("/mime");
+ runUpdateMimeDatabase(tempMime);
+ QVERIFY(QFile::exists(tempMime + QString::fromLatin1("/mime.cache")));
+}
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro
new file mode 100644
index 0000000000..ac7515f781
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro
@@ -0,0 +1,14 @@
+CONFIG += testcase parallel_test
+
+TARGET = tst_qmimedatabase-xml
+
+QT = core testlib concurrent
+
+CONFIG += depend_includepath
+
+SOURCES += tst_qmimedatabase-xml.cpp
+HEADERS += ../tst_qmimedatabase.h
+
+DEFINES += SRCDIR='"\\"$$PWD/../\\""'
+
+*-g++*:QMAKE_CXXFLAGS += -W -Wall -Wextra -Werror -Wshadow -Wno-long-long -Wnon-virtual-dtor
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp
new file mode 100644
index 0000000000..13ca372290
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../tst_qmimedatabase.h"
+#include <QDebug>
+#include <QDir>
+
+tst_QMimeDatabase::tst_QMimeDatabase()
+{
+ qputenv("QT_NO_MIME_CACHE", "1");
+}
+
+#include "../tst_qmimedatabase.cpp"
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro
new file mode 100644
index 0000000000..876b4377dd
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+SUBDIRS = qmimedatabase-xml
+unix: SUBDIRS += qmimedatabase-cache
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
new file mode 100644
index 0000000000..12d6587dfb
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
@@ -0,0 +1,829 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qmimedatabase.h>
+
+#include "qstandardpaths.h"
+
+#include <QtCore/QFile>
+#include <QtConcurrent/QtConcurrentRun>
+#include <QtConcurrent/QFuture>
+
+#include <QtTest/QtTest>
+
+void initializeLang()
+{
+ qputenv("LANG", "en_US");
+}
+
+// Set LANG before QCoreApplication is created
+Q_CONSTRUCTOR_FUNCTION(initializeLang)
+
+void tst_QMimeDatabase::initTestCase()
+{
+ // Create a "global" and a "local" XDG data dir, right here.
+ // The local dir will be empty initially, while the global dir will contain a copy of freedesktop.org.xml
+
+ QDir here = QDir::currentPath();
+
+ qputenv("XDG_DATA_DIRS", QFile::encodeName(here.absolutePath()));
+ QDir(here.absolutePath() + "/mime").removeRecursively();
+ here.mkpath(QString::fromLatin1("mime/packages"));
+
+ QFile xml(QFile::decodeName(SRCDIR "../../../src/mimetypes/mime/packages/freedesktop.org.xml"));
+ const QString mimeDir = here.absolutePath() + QLatin1String("/mime");
+ xml.copy(mimeDir + QLatin1String("/packages/freedesktop.org.xml"));
+
+ m_dataHome = here.absolutePath() + QLatin1String("/../datahome");
+ qputenv("XDG_DATA_HOME", QFile::encodeName(m_dataHome));
+ //qDebug() << "XDG_DATA_HOME=" << m_dataHome;
+
+ // Make sure we start clean
+ cleanupTestCase();
+}
+
+void tst_QMimeDatabase::cleanupTestCase()
+{
+ QDir here = QDir::currentPath();
+ here.remove(QString::fromLatin1("mime/packages/yast2-metapackage-handler-mimetypes.xml"));
+
+ QDir(m_dataHome).removeRecursively();
+}
+
+void tst_QMimeDatabase::mimeTypeForName()
+{
+ QMimeDatabase db;
+ QMimeType s0 = db.mimeTypeForName(QString::fromLatin1("application/x-zerosize"));
+ QVERIFY(s0.isValid());
+ QCOMPARE(s0.name(), QString::fromLatin1("application/x-zerosize"));
+ QCOMPARE(s0.comment(), QString::fromLatin1("empty document"));
+
+ QMimeType s0Again = db.mimeTypeForName(QString::fromLatin1("application/x-zerosize"));
+ QCOMPARE(s0Again.name(), s0.name());
+
+ QMimeType s1 = db.mimeTypeForName(QString::fromLatin1("text/plain"));
+ QVERIFY(s1.isValid());
+ QCOMPARE(s1.name(), QString::fromLatin1("text/plain"));
+ //qDebug("Comment is %s", qPrintable(s1.comment()));
+
+ QMimeType krita = db.mimeTypeForName(QString::fromLatin1("application/x-krita"));
+ QVERIFY(krita.isValid());
+
+ // Test <comment> parsing with application/rdf+xml which has the english comment after the other ones
+ QMimeType rdf = db.mimeTypeForName(QString::fromLatin1("application/rdf+xml"));
+ QVERIFY(rdf.isValid());
+ QCOMPARE(rdf.comment(), QString::fromLatin1("RDF file"));
+
+ QMimeType bzip2 = db.mimeTypeForName(QString::fromLatin1("application/x-bzip2"));
+ QVERIFY(bzip2.isValid());
+ QCOMPARE(bzip2.comment(), QString::fromLatin1("Bzip archive"));
+
+ QMimeType defaultMime = db.mimeTypeForName(QString::fromLatin1("application/octet-stream"));
+ QVERIFY(defaultMime.isValid());
+ QVERIFY(defaultMime.isDefault());
+
+ QMimeType doesNotExist = db.mimeTypeForName(QString::fromLatin1("foobar/x-doesnot-exist"));
+ QVERIFY(!doesNotExist.isValid());
+
+ // TODO move to findByFile
+#ifdef Q_OS_LINUX
+ QString exePath = QStandardPaths::findExecutable(QLatin1String("ls"));
+ if (exePath.isEmpty())
+ qWarning() << "ls not found";
+ else {
+ const QString executableType = QString::fromLatin1("application/x-executable");
+ //QTest::newRow("executable") << exePath << executableType;
+ QCOMPARE(db.mimeTypeForFile(exePath).name(), executableType);
+ }
+#endif
+
+}
+
+void tst_QMimeDatabase::mimeTypeForFileName_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QString>("expectedMimeType");
+
+ QTest::newRow("text") << "textfile.txt" << "text/plain";
+ QTest::newRow("case-insensitive search") << "textfile.TxT" << "text/plain";
+
+ // Needs shared-mime-info > 0.91. Earlier versions wrote .Z to the mime.cache file...
+ //QTest::newRow("case-insensitive match on a non-lowercase glob") << "foo.z" << "application/x-compress";
+
+ QTest::newRow("case-sensitive uppercase match") << "textfile.C" << "text/x-c++src";
+ QTest::newRow("case-sensitive lowercase match") << "textfile.c" << "text/x-csrc";
+ QTest::newRow("case-sensitive long-extension match") << "foo.PS.gz" << "application/x-gzpostscript";
+ QTest::newRow("case-sensitive-only match") << "core" << "application/x-core";
+ QTest::newRow("case-sensitive-only match") << "Core" << "application/octet-stream"; // #198477
+
+ QTest::newRow("desktop file") << "foo.desktop" << "application/x-desktop";
+ QTest::newRow("old kdelnk file is x-desktop too") << "foo.kdelnk" << "application/x-desktop";
+ QTest::newRow("double-extension file") << "foo.tar.bz2" << "application/x-bzip-compressed-tar";
+ QTest::newRow("single-extension file") << "foo.bz2" << "application/x-bzip";
+ QTest::newRow(".doc should assume msword") << "somefile.doc" << "application/msword"; // #204139
+ QTest::newRow("glob that uses [] syntax, 1") << "Makefile" << "text/x-makefile";
+ QTest::newRow("glob that uses [] syntax, 2") << "makefile" << "text/x-makefile";
+ QTest::newRow("glob that ends with *, no extension") << "README" << "text/x-readme";
+ QTest::newRow("glob that ends with *, extension") << "README.foo" << "text/x-readme";
+ QTest::newRow("glob that ends with *, also matches *.txt. Higher weight wins.") << "README.txt" << "text/plain";
+ QTest::newRow("glob that ends with *, also matches *.nfo. Higher weight wins.") << "README.nfo" << "text/x-nfo";
+ // fdo bug 15436, needs shared-mime-info >= 0.40 (and this tests the globs2-parsing code).
+ QTest::newRow("glob that ends with *, also matches *.pdf. *.pdf has higher weight") << "README.pdf" << "application/pdf";
+ QTest::newRow("directory") << "/" << "inode/directory";
+ QTest::newRow("doesn't exist, no extension") << "IDontExist" << "application/octet-stream";
+ QTest::newRow("doesn't exist but has known extension") << "IDontExist.txt" << "text/plain";
+}
+
+void tst_QMimeDatabase::mimeTypeForFileName()
+{
+ QFETCH(QString, fileName);
+ QFETCH(QString, expectedMimeType);
+ QMimeDatabase db;
+ QMimeType mime = db.mimeTypeForFile(fileName, QMimeDatabase::MatchExtension);
+ QVERIFY(mime.isValid());
+ QCOMPARE(mime.name(), expectedMimeType);
+
+ QList<QMimeType> mimes = db.mimeTypesForFileName(fileName);
+ if (expectedMimeType == "application/octet-stream") {
+ QVERIFY(mimes.isEmpty());
+ } else {
+ QVERIFY(!mimes.isEmpty());
+ QCOMPARE(mimes.count(), 1);
+ QCOMPARE(mimes.first().name(), expectedMimeType);
+ }
+}
+
+void tst_QMimeDatabase::mimeTypesForFileName_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QStringList>("expectedMimeTypes");
+
+ QTest::newRow("txt, 1 hit") << "foo.txt" << (QStringList() << "text/plain");
+ QTest::newRow("txtfoobar, 0 hit") << "foo.foobar" << QStringList();
+ QTest::newRow("m, 2 hits") << "foo.m" << (QStringList() << "text/x-matlab" << "text/x-objcsrc");
+ QTest::newRow("sub, 3 hits") << "foo.sub" << (QStringList() << "text/x-microdvd" << "text/x-mpsub" << "text/x-subviewer");
+}
+
+void tst_QMimeDatabase::mimeTypesForFileName()
+{
+ QFETCH(QString, fileName);
+ QFETCH(QStringList, expectedMimeTypes);
+ QMimeDatabase db;
+ QList<QMimeType> mimes = db.mimeTypesForFileName(fileName);
+ QStringList mimeNames;
+ foreach (const QMimeType &mime, mimes)
+ mimeNames.append(mime.name());
+ QCOMPARE(mimeNames, expectedMimeTypes);
+}
+
+void tst_QMimeDatabase::inheritance()
+{
+ QMimeDatabase db;
+
+ // All file-like mimetypes inherit from octet-stream
+ const QMimeType wordperfect = db.mimeTypeForName(QString::fromLatin1("application/vnd.wordperfect"));
+ QVERIFY(wordperfect.isValid());
+ QCOMPARE(wordperfect.parentMimeTypes().join(QString::fromLatin1(",")), QString::fromLatin1("application/octet-stream"));
+ QVERIFY(wordperfect.inherits(QLatin1String("application/octet-stream")));
+
+ QVERIFY(db.mimeTypeForName(QString::fromLatin1("image/svg+xml-compressed")).inherits(QLatin1String("application/x-gzip")));
+
+ // Check that msword derives from ole-storage
+ const QMimeType msword = db.mimeTypeForName(QString::fromLatin1("application/msword"));
+ QVERIFY(msword.isValid());
+ const QMimeType olestorage = db.mimeTypeForName(QString::fromLatin1("application/x-ole-storage"));
+ QVERIFY(olestorage.isValid());
+ QVERIFY(msword.inherits(olestorage.name()));
+ QVERIFY(msword.inherits(QLatin1String("application/octet-stream")));
+
+ const QMimeType directory = db.mimeTypeForName(QString::fromLatin1("inode/directory"));
+ QVERIFY(directory.isValid());
+ QCOMPARE(directory.parentMimeTypes().count(), 0);
+ QVERIFY(!directory.inherits(QLatin1String("application/octet-stream")));
+
+ // Check that text/x-patch knows that it inherits from text/plain (it says so explicitly)
+ const QMimeType plain = db.mimeTypeForName(QString::fromLatin1("text/plain"));
+ const QMimeType derived = db.mimeTypeForName(QString::fromLatin1("text/x-patch"));
+ QVERIFY(derived.isValid());
+ QCOMPARE(derived.parentMimeTypes().join(QString::fromLatin1(",")), plain.name());
+ QVERIFY(derived.inherits(QLatin1String("text/plain")));
+ QVERIFY(derived.inherits(QLatin1String("application/octet-stream")));
+
+ // Check that application/x-shellscript inherits from application/x-executable
+ // (Otherwise KRun cannot start shellscripts...)
+ // This is a test for multiple inheritance...
+ const QMimeType shellscript = db.mimeTypeForName(QString::fromLatin1("application/x-shellscript"));
+ QVERIFY(shellscript.isValid());
+ QVERIFY(shellscript.inherits(QLatin1String("text/plain")));
+ QVERIFY(shellscript.inherits(QLatin1String("application/x-executable")));
+ const QStringList shellParents = shellscript.parentMimeTypes();
+ QVERIFY(shellParents.contains(QLatin1String("text/plain")));
+ QVERIFY(shellParents.contains(QLatin1String("application/x-executable")));
+ QCOMPARE(shellParents.count(), 2); // only the above two
+ const QStringList allShellAncestors = shellscript.allAncestors();
+ QVERIFY(allShellAncestors.contains(QLatin1String("text/plain")));
+ QVERIFY(allShellAncestors.contains(QLatin1String("application/x-executable")));
+ QVERIFY(allShellAncestors.contains(QLatin1String("application/octet-stream")));
+ // Must be least-specific last, i.e. breadth first.
+ QCOMPARE(allShellAncestors.last(), QString::fromLatin1("application/octet-stream"));
+
+ const QStringList allSvgAncestors = db.mimeTypeForName(QString::fromLatin1("image/svg+xml")).allAncestors();
+ QCOMPARE(allSvgAncestors, QStringList() << QLatin1String("application/xml") << QLatin1String("text/plain") << QLatin1String("application/octet-stream"));
+
+ // Check that text/x-mrml knows that it inherits from text/plain (implicitly)
+ const QMimeType mrml = db.mimeTypeForName(QString::fromLatin1("text/x-mrml"));
+ QVERIFY(mrml.isValid());
+ QVERIFY(mrml.inherits(QLatin1String("text/plain")));
+ QVERIFY(mrml.inherits(QLatin1String("application/octet-stream")));
+
+ // Check that msword-template inherits msword
+ const QMimeType mswordTemplate = db.mimeTypeForName(QString::fromLatin1("application/msword-template"));
+ QVERIFY(mswordTemplate.isValid());
+ QVERIFY(mswordTemplate.inherits(QLatin1String("application/msword")));
+}
+
+void tst_QMimeDatabase::aliases()
+{
+ QMimeDatabase db;
+
+ const QMimeType canonical = db.mimeTypeForName(QString::fromLatin1("application/xml"));
+ QVERIFY(canonical.isValid());
+
+ QMimeType resolvedAlias = db.mimeTypeForName(QString::fromLatin1("text/xml"));
+ QVERIFY(resolvedAlias.isValid());
+ QCOMPARE(resolvedAlias.name(), QString::fromLatin1("application/xml"));
+
+ QVERIFY(resolvedAlias.inherits(QLatin1String("application/xml")));
+ QVERIFY(canonical.inherits(QLatin1String("text/xml")));
+
+ // Test for kde bug 197346: does nspluginscan see that audio/mp3 already exists?
+ bool mustWriteMimeType = !db.mimeTypeForName(QString::fromLatin1("audio/mp3")).isValid();
+ QVERIFY(!mustWriteMimeType);
+}
+
+void tst_QMimeDatabase::icons()
+{
+ QMimeDatabase db;
+ QMimeType directory = db.mimeTypeForFile(QString::fromLatin1("/"));
+ QCOMPARE(directory.name(), QString::fromLatin1("inode/directory"));
+ QCOMPARE(directory.iconName(), QString::fromLatin1("inode-directory"));
+ QCOMPARE(directory.genericIconName(), QString::fromLatin1("inode-x-generic"));
+
+ QMimeType pub = db.mimeTypeForFile(QString::fromLatin1("foo.epub"), QMimeDatabase::MatchExtension);
+ QCOMPARE(pub.name(), QString::fromLatin1("application/epub+zip"));
+ QCOMPARE(pub.iconName(), QString::fromLatin1("application-epub+zip"));
+ QCOMPARE(pub.genericIconName(), QString::fromLatin1("x-office-document"));
+}
+
+// In here we do the tests that need some content in a temporary file.
+// This could also be added to shared-mime-info's testsuite...
+void tst_QMimeDatabase::mimeTypeForFileWithContent()
+{
+ QMimeDatabase db;
+ QMimeType mime;
+
+ // Test a real PDF file.
+ // If we find x-matlab because it starts with '%' then we are not ordering by priority.
+ QTemporaryFile tempFile;
+ QVERIFY(tempFile.open());
+ QString tempFileName = tempFile.fileName();
+ tempFile.write("%PDF-");
+ tempFile.close();
+ mime = db.mimeTypeForFile(tempFileName);
+ QCOMPARE(mime.name(), QString::fromLatin1("application/pdf"));
+ QFile file(tempFileName);
+ mime = db.mimeTypeForData(&file); // QIODevice ctor
+ QCOMPARE(mime.name(), QString::fromLatin1("application/pdf"));
+ // by name only, we cannot find the mimetype
+ mime = db.mimeTypeForFile(tempFileName, QMimeDatabase::MatchExtension);
+ QVERIFY(mime.isValid());
+ QVERIFY(mime.isDefault());
+
+ // Test the case where the extension doesn't match the contents: extension wins
+ {
+ QTemporaryFile txtTempFile(QDir::tempPath() + QLatin1String("/tst_QMimeDatabase_XXXXXX.txt"));
+ QVERIFY(txtTempFile.open());
+ txtTempFile.write("%PDF-");
+ QString txtTempFileName = txtTempFile.fileName();
+ txtTempFile.close();
+ mime = db.mimeTypeForFile(txtTempFileName);
+ QCOMPARE(mime.name(), QString::fromLatin1("text/plain"));
+ // fast mode finds the same
+ mime = db.mimeTypeForFile(txtTempFileName, QMimeDatabase::MatchExtension);
+ QCOMPARE(mime.name(), QString::fromLatin1("text/plain"));
+ }
+
+ // Now the case where extension differs from contents, but contents has >80 magic rule
+ // XDG spec says: contents wins. But we can't sniff all files...
+ {
+ QTemporaryFile txtTempFile(QDir::tempPath() + QLatin1String("/tst_QMimeDatabase_XXXXXX.txt"));
+ QVERIFY(txtTempFile.open());
+ txtTempFile.write("<smil");
+ QString txtTempFileName = txtTempFile.fileName();
+ txtTempFile.close();
+ mime = db.mimeTypeForFile(txtTempFileName);
+ QCOMPARE(mime.name(), QString::fromLatin1("text/plain"));
+ }
+
+ // Test what happens with an incorrect path
+ mime = db.mimeTypeForFile(QString::fromLatin1("file:///etc/passwd" /* incorrect code, use a path instead */));
+ QVERIFY(mime.isDefault());
+
+ // findByData when the device cannot be opened (e.g. a directory)
+ QFile dir("/");
+ mime = db.mimeTypeForData(&dir);
+ QVERIFY(mime.isDefault());
+}
+
+void tst_QMimeDatabase::mimeTypeForUrl()
+{
+ QMimeDatabase db;
+ QVERIFY(db.mimeTypeForUrl(QUrl::fromEncoded("http://foo/bar.png")).isDefault()); // HTTP can't know before downloading
+ QCOMPARE(db.mimeTypeForUrl(QUrl::fromEncoded("ftp://foo/bar.png")).name(), QString::fromLatin1("image/png"));
+ QCOMPARE(db.mimeTypeForUrl(QUrl::fromEncoded("ftp://foo/bar")).name(), QString::fromLatin1("application/octet-stream")); // unknown extension
+}
+
+void tst_QMimeDatabase::mimeTypeForData_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QString>("expectedMimeTypeName");
+
+ QTest::newRow("tnef data, needs smi >= 0.20") << QByteArray("\x78\x9f\x3e\x22") << "application/vnd.ms-tnef";
+ QTest::newRow("PDF magic") << QByteArray("%PDF-") << "application/pdf";
+ QTest::newRow("PHP, High-priority rule") << QByteArray("<?php") << "application/x-php";
+ QTest::newRow("unknown") << QByteArray("\001abc?}") << "application/octet-stream";
+}
+
+void tst_QMimeDatabase::mimeTypeForData()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expectedMimeTypeName);
+
+ QMimeDatabase db;
+ QCOMPARE(db.mimeTypeForData(data).name(), expectedMimeTypeName);
+ QBuffer buffer(&data);
+ QCOMPARE(db.mimeTypeForData(&buffer).name(), expectedMimeTypeName);
+ QVERIFY(!buffer.isOpen()); // initial state was restored
+
+ QVERIFY(buffer.open(QIODevice::ReadOnly));
+ QCOMPARE(db.mimeTypeForData(&buffer).name(), expectedMimeTypeName);
+ QVERIFY(buffer.isOpen());
+ QCOMPARE(buffer.pos(), qint64(0));
+}
+
+void tst_QMimeDatabase::mimeTypeForFileAndContent_data()
+{
+ QTest::addColumn<QString>("name");
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QString>("expectedMimeTypeName");
+
+ QTest::newRow("plain text, no extension") << QString::fromLatin1("textfile") << QByteArray("Hello world") << "text/plain";
+ QTest::newRow("plain text, unknown extension") << QString::fromLatin1("textfile.foo") << QByteArray("Hello world") << "text/plain";
+ // Needs kde/mimetypes.xml
+ //QTest::newRow("plain text, doc extension") << QString::fromLatin1("textfile.doc") << QByteArray("Hello world") << "text/plain";
+
+ // If you get powerpoint instead, then you're hit by https://bugs.freedesktop.org/show_bug.cgi?id=435,
+ // upgrade to shared-mime-info >= 0.22
+ const QByteArray oleData("\320\317\021\340\241\261\032\341"); // same as \xD0\xCF\x11\xE0 \xA1\xB1\x1A\xE1
+ QTest::newRow("msword file, unknown extension") << QString::fromLatin1("mswordfile") << oleData << "application/x-ole-storage";
+ QTest::newRow("excel file, found by extension") << QString::fromLatin1("excelfile.xls") << oleData << "application/vnd.ms-excel";
+ QTest::newRow("text.xls, found by extension, user is in control") << QString::fromLatin1("text.xls") << oleData << "application/vnd.ms-excel";
+}
+
+void tst_QMimeDatabase::mimeTypeForFileAndContent()
+{
+ QFETCH(QString, name);
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expectedMimeTypeName);
+
+ QMimeDatabase db;
+ QCOMPARE(db.mimeTypeForNameAndData(name, data).name(), expectedMimeTypeName);
+
+ QBuffer buffer(&data);
+ QCOMPARE(db.mimeTypeForNameAndData(name, &buffer).name(), expectedMimeTypeName);
+ QVERIFY(!buffer.isOpen()); // initial state was restored
+
+ QVERIFY(buffer.open(QIODevice::ReadOnly));
+ QCOMPARE(db.mimeTypeForNameAndData(name, &buffer).name(), expectedMimeTypeName);
+ QVERIFY(buffer.isOpen());
+ QCOMPARE(buffer.pos(), qint64(0));
+}
+
+void tst_QMimeDatabase::allMimeTypes()
+{
+ QMimeDatabase db;
+ const QList<QMimeType> lst = db.allMimeTypes(); // does NOT include aliases
+ QVERIFY(!lst.isEmpty());
+
+ // Hardcoding this is the only way to check both providers find the same number of mimetypes.
+ QCOMPARE(lst.count(), 661);
+
+ foreach (const QMimeType &mime, lst) {
+ const QString name = mime.name();
+ QVERIFY(!name.isEmpty());
+ QCOMPARE(name.count(QLatin1Char('/')), 1);
+ const QMimeType lookedupMime = db.mimeTypeForName(name);
+ QVERIFY(lookedupMime.isValid());
+ QCOMPARE(lookedupMime.name(), name); // if this fails, you have an alias defined as a real mimetype too!
+ }
+}
+
+void tst_QMimeDatabase::inheritsPerformance()
+{
+ // Check performance of inherits().
+ // This benchmark (which started in 2009 in kmimetypetest.cpp) uses 40 mimetypes.
+ QStringList mimeTypes; mimeTypes << QLatin1String("image/jpeg") << QLatin1String("image/png") << QLatin1String("image/tiff") << QLatin1String("text/plain") << QLatin1String("text/html");
+ mimeTypes += mimeTypes;
+ mimeTypes += mimeTypes;
+ mimeTypes += mimeTypes;
+ QCOMPARE(mimeTypes.count(), 40);
+ QMimeDatabase db;
+ QMimeType mime = db.mimeTypeForName(QString::fromLatin1("text/x-chdr"));
+ QVERIFY(mime.isValid());
+ QBENCHMARK {
+ QString match;
+ foreach (const QString &mt, mimeTypes) {
+ if (mime.inherits(mt)) {
+ match = mt;
+ // of course there would normally be a "break" here, but we're testing worse-case
+ // performance here
+ }
+ }
+ QCOMPARE(match, QString::fromLatin1("text/plain"));
+ }
+ // Numbers from 2011, in release mode:
+ // KDE 4.7 numbers: 0.21 msec / 494,000 ticks / 568,345 instr. loads per iteration
+ // QMimeBinaryProvider (with Qt 5): 0.16 msec / NA / 416,049 instr. reads per iteration
+ // QMimeXmlProvider (with Qt 5): 0.062 msec / NA / 172,889 instr. reads per iteration
+ // (but the startup time is way higher)
+ // And memory usage is flat at 200K with QMimeBinaryProvider, while it peaks at 6 MB when
+ // parsing XML, and then keeps being around 4.5 MB for all the in-memory hashes.
+}
+
+void tst_QMimeDatabase::suffixes_data()
+{
+ QTest::addColumn<QString>("mimeType");
+ QTest::addColumn<QString>("patterns");
+ QTest::addColumn<QString>("preferredSuffix");
+
+ QTest::newRow("mimetype with a single pattern") << "application/pdf" << "*.pdf" << "pdf";
+ QTest::newRow("mimetype with multiple patterns") << "application/x-kpresenter" << "*.kpr;*.kpt" << "kpr";
+ //if (KMimeType::sharedMimeInfoVersion() > KDE_MAKE_VERSION(0, 60, 0)) {
+ QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
+ //}
+ QTest::newRow("oasis text mimetype") << "application/vnd.oasis.opendocument.text" << "*.odt" << "odt";
+ QTest::newRow("oasis presentation mimetype") << "application/vnd.oasis.opendocument.presentation" << "*.odp" << "odp";
+ QTest::newRow("mimetype with multiple patterns") << "text/plain" << "*.asc;*.txt;*,v" << "txt";
+ QTest::newRow("mimetype with uncommon pattern") << "text/x-readme" << "README*" << QString();
+ QTest::newRow("mimetype with no patterns") << "application/x-ole-storage" << QString() << QString();
+}
+
+void tst_QMimeDatabase::suffixes()
+{
+ QFETCH(QString, mimeType);
+ QFETCH(QString, patterns);
+ QFETCH(QString, preferredSuffix);
+ QMimeDatabase db;
+ QMimeType mime = db.mimeTypeForName(mimeType);
+ QVERIFY(mime.isValid());
+ // Sort both lists; order is unreliable since shared-mime-info uses hashes internally.
+ QStringList expectedPatterns = patterns.split(QLatin1Char(';'));
+ expectedPatterns.sort();
+ QStringList mimePatterns = mime.globPatterns();
+ mimePatterns.sort();
+ QCOMPARE(mimePatterns.join(QLatin1String(";")), expectedPatterns.join(QLatin1String(";")));
+ QCOMPARE(mime.preferredSuffix(), preferredSuffix);
+}
+
+void tst_QMimeDatabase::knownSuffix()
+{
+ QMimeDatabase db;
+ QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.tar")), QString::fromLatin1("tar"));
+ QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.bz2")), QString::fromLatin1("bz2"));
+ QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.bar.bz2")), QString::fromLatin1("bz2"));
+ QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.tar.bz2")), QString::fromLatin1("tar.bz2"));
+}
+
+void tst_QMimeDatabase::findByFileName_data()
+{
+ QTest::addColumn<QString>("filePath");
+ QTest::addColumn<QString>("mimeTypeName");
+ QTest::addColumn<QString>("xFail");
+
+ QString prefix = QLatin1String(SRCDIR "testfiles/");
+
+ QFile f(prefix + QLatin1String("list"));
+ if (!f.open(QIODevice::ReadOnly)) {
+ const QString warning = QString::fromLatin1(
+ "Please download the shared-mime-info test suite:\n"
+ "cd tests/auto/corelib/mimetypes/qmimedatabase\n"
+ "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-0.zip\n"
+ "unzip Release-1-0.zip\n"
+ "ln -s Release-1-0/tests testfiles\n"
+ );
+ qWarning() << warning;
+ QSKIP("shared-mime-info test suite not available.");
+ }
+
+ QByteArray line(1024, Qt::Uninitialized);
+
+ while (!f.atEnd()) {
+ int len = f.readLine(line.data(), 1023);
+
+ if (len <= 2 || line.at(0) == '#')
+ continue;
+
+ QString string = QString::fromLatin1(line.constData(), len - 1).trimmed();
+ QStringList list = string.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ QVERIFY(list.size() >= 2);
+
+ QString filePath = list.at(0);
+ QString mimeTypeType = list.at(1);
+ QString xFail;
+ if (list.size() >= 3)
+ xFail = list.at(2);
+
+ QTest::newRow(filePath.toLatin1().constData()) << QString(prefix + filePath) << mimeTypeType << xFail;
+ }
+}
+
+void tst_QMimeDatabase::findByFileName()
+{
+ QFETCH(QString, filePath);
+ QFETCH(QString, mimeTypeName);
+ QFETCH(QString, xFail);
+
+ QMimeDatabase database;
+
+ //qDebug() << Q_FUNC_INFO << filePath;
+
+ const QMimeType resultMimeType(database.mimeTypeForFile(filePath, QMimeDatabase::MatchExtension));
+ if (resultMimeType.isValid()) {
+ //qDebug() << Q_FUNC_INFO << "MIME type" << resultMimeType.name() << "has generic icon name" << resultMimeType.genericIconName() << "and icon name" << resultMimeType.iconName();
+
+// Loading icons depend on the icon theme, we can't enable this test
+#if 0
+ QCOMPARE(resultMimeType.genericIconName(), QIcon::fromTheme(resultMimeType.genericIconName()).name());
+ QVERIFY2(!QIcon::fromTheme(resultMimeType.genericIconName()).isNull(), qPrintable(resultMimeType.genericIconName()));
+ QVERIFY2(QIcon::hasThemeIcon(resultMimeType.genericIconName()), qPrintable(resultMimeType.genericIconName()));
+
+ QCOMPARE(resultMimeType.iconName(), QIcon::fromTheme(resultMimeType.iconName()).name());
+ QVERIFY2(!QIcon::fromTheme(resultMimeType.iconName()).isNull(), qPrintable(resultMimeType.iconName()));
+ QVERIFY2(QIcon::hasThemeIcon(resultMimeType.iconName()), qPrintable(resultMimeType.iconName()));
+#endif
+ }
+ const QString resultMimeTypeName = resultMimeType.name();
+ //qDebug() << Q_FUNC_INFO << "mimeTypeForFile() returned" << resultMimeTypeName;
+
+ const bool failed = resultMimeTypeName != mimeTypeName;
+ const bool shouldFail = (xFail.length() >= 1 && xFail.at(0) == QLatin1Char('x'));
+ if (shouldFail != failed) {
+ // Results are ambiguous when multiple MIME types have the same glob
+ // -> accept the current result if the found MIME type actually
+ // matches the file's extension.
+ // TODO: a better file format in testfiles/list!
+ const QMimeType foundMimeType = database.mimeTypeForName(resultMimeTypeName);
+ QVERIFY2(resultMimeType == foundMimeType, qPrintable(resultMimeType.name() + QString::fromLatin1(" vs. ") + foundMimeType.name()));
+ if (foundMimeType.isValid()) {
+ const QString extension = QFileInfo(filePath).suffix();
+ //qDebug() << Q_FUNC_INFO << "globPatterns:" << foundMimeType.globPatterns() << "- extension:" << QString() + "*." + extension;
+ if (foundMimeType.globPatterns().contains(QString::fromLatin1("*.") + extension))
+ return;
+ }
+ }
+ if (shouldFail) {
+ // Expected to fail
+ QVERIFY2(resultMimeTypeName != mimeTypeName, qPrintable(resultMimeTypeName));
+ } else {
+ QCOMPARE(resultMimeTypeName, mimeTypeName);
+ }
+
+ // Test QFileInfo overload
+ const QMimeType mimeForFileInfo = database.mimeTypeForFile(QFileInfo(filePath), QMimeDatabase::MatchExtension);
+ QCOMPARE(mimeForFileInfo.name(), resultMimeTypeName);
+}
+
+void tst_QMimeDatabase::findByData_data()
+{
+ findByFileName_data();
+}
+
+void tst_QMimeDatabase::findByData()
+{
+ QFETCH(QString, filePath);
+ QFETCH(QString, mimeTypeName);
+ QFETCH(QString, xFail);
+
+ QMimeDatabase database;
+ QFile f(filePath);
+ QVERIFY(f.open(QIODevice::ReadOnly));
+ QByteArray data = f.read(16384);
+
+ const QString resultMimeTypeName = database.mimeTypeForData(data).name();
+ if (xFail.length() >= 2 && xFail.at(1) == QLatin1Char('x')) {
+ // Expected to fail
+ QVERIFY2(resultMimeTypeName != mimeTypeName, qPrintable(resultMimeTypeName));
+ } else {
+ QCOMPARE(resultMimeTypeName, mimeTypeName);
+ }
+
+ QFileInfo info(filePath);
+ QString mimeForInfo = database.mimeTypeForFile(info, QMimeDatabase::MatchContent).name();
+ QCOMPARE(mimeForInfo, resultMimeTypeName);
+}
+
+void tst_QMimeDatabase::findByFile_data()
+{
+ findByFileName_data();
+}
+
+void tst_QMimeDatabase::findByFile()
+{
+ QFETCH(QString, filePath);
+ QFETCH(QString, mimeTypeName);
+ QFETCH(QString, xFail);
+
+ QMimeDatabase database;
+ const QString resultMimeTypeName = database.mimeTypeForFile(filePath).name();
+ //qDebug() << Q_FUNC_INFO << filePath << "->" << resultMimeTypeName;
+ if (xFail.length() >= 3 && xFail.at(2) == QLatin1Char('x')) {
+ // Expected to fail
+ QVERIFY2(resultMimeTypeName != mimeTypeName, qPrintable(resultMimeTypeName));
+ } else {
+ QCOMPARE(resultMimeTypeName, mimeTypeName);
+ }
+
+ // Test QFileInfo overload
+ const QMimeType mimeForFileInfo = database.mimeTypeForFile(QFileInfo(filePath));
+ QCOMPARE(mimeForFileInfo.name(), resultMimeTypeName);
+}
+
+
+void tst_QMimeDatabase::fromThreads()
+{
+ QThreadPool::globalInstance()->setMaxThreadCount(20);
+ // Note that data-based tests cannot be used here (QTest::fetchData asserts).
+ QList<QFuture<void> > futures;
+ futures << QtConcurrent::run(this, &tst_QMimeDatabase::mimeTypeForName);
+ futures << QtConcurrent::run(this, &tst_QMimeDatabase::aliases);
+ futures << QtConcurrent::run(this, &tst_QMimeDatabase::allMimeTypes);
+ futures << QtConcurrent::run(this, &tst_QMimeDatabase::icons);
+ futures << QtConcurrent::run(this, &tst_QMimeDatabase::inheritance);
+ futures << QtConcurrent::run(this, &tst_QMimeDatabase::knownSuffix);
+ futures << QtConcurrent::run(this, &tst_QMimeDatabase::mimeTypeForFileWithContent);
+ futures << QtConcurrent::run(this, &tst_QMimeDatabase::allMimeTypes); // a second time
+ Q_FOREACH (QFuture<void> f, futures)
+ f.waitForFinished();
+}
+
+static void runUpdateMimeDatabase(const QString &path) // TODO make it a QMimeDatabase method?
+{
+ const QString umd = QStandardPaths::findExecutable(QString::fromLatin1("update-mime-database"));
+ if (umd.isEmpty())
+ QSKIP("shared-mime-info not found, skipping mime.cache test");
+
+ QProcess proc;
+ proc.setProcessChannelMode(QProcess::MergedChannels); // silence output
+ proc.start(umd, QStringList() << path);
+ proc.waitForFinished();
+ //qDebug() << "runUpdateMimeDatabase" << path;
+}
+
+static void waitAndRunUpdateMimeDatabase(const QString &path)
+{
+ QFileInfo mimeCacheInfo(path + QString::fromLatin1("/mime.cache"));
+ if (mimeCacheInfo.exists()) {
+ // Wait until the begining of the next second
+ while (mimeCacheInfo.lastModified().secsTo(QDateTime::currentDateTime()) == 0) {
+ QTest::qSleep(200);
+ }
+ }
+ runUpdateMimeDatabase(path);
+}
+
+static void checkHasMimeType(const QString &mimeType)
+{
+ QMimeDatabase db;
+ QVERIFY(db.mimeTypeForName(mimeType).isValid());
+
+ bool found = false;
+ foreach (const QMimeType &mt, db.allMimeTypes()) {
+ if (mt.name() == mimeType) {
+ found = true;
+ break;
+ }
+ }
+ QVERIFY(found);
+}
+
+QT_BEGIN_NAMESPACE
+extern Q_CORE_EXPORT int qmime_secondsBetweenChecks; // see qmimeprovider.cpp
+QT_END_NAMESPACE
+
+void tst_QMimeDatabase::installNewGlobalMimeType()
+{
+ qmime_secondsBetweenChecks = 0;
+
+ QMimeDatabase db;
+ QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid());
+
+ const QString fileName = QLatin1String("yast2-metapackage-handler-mimetypes.xml");
+ const QString srcFile = QFile::decodeName(SRCDIR) + fileName;
+
+ QDir here = QDir::currentPath();
+ const QString mimeDir = here.absolutePath() + QLatin1String("/mime");
+ const QString destDir = mimeDir + QLatin1String("/packages/");
+ const QString destFile = destDir + fileName;
+ QFile::remove(destFile);
+ //qDebug() << destFile;
+ QVERIFY(QFile::copy(srcFile, destFile));
+ waitAndRunUpdateMimeDatabase(mimeDir);
+
+ QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(),
+ QString::fromLatin1("text/x-suse-ymu"));
+ QVERIFY(db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid());
+ checkHasMimeType("text/x-suse-ymp");
+
+ // Now test removing it again
+ QFile::remove(destFile);
+ waitAndRunUpdateMimeDatabase(mimeDir);
+ QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(),
+ QString::fromLatin1("application/octet-stream"));
+ QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid());
+}
+
+void tst_QMimeDatabase::installNewLocalMimeType()
+{
+ qmime_secondsBetweenChecks = 0;
+
+ QMimeDatabase db;
+ QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid());
+
+ const QString fileName = QLatin1String("yast2-metapackage-handler-mimetypes.xml");
+ const QString srcFile = QFile::decodeName(SRCDIR) + fileName;
+ const QString mimeDir = m_dataHome + QLatin1String("/mime");
+ const QString destDir = mimeDir + QLatin1String("/packages/");
+ QDir().mkpath(destDir);
+ const QString destFile = destDir + fileName;
+ QFile::remove(destFile);
+ QVERIFY(QFile::copy(srcFile, destFile));
+ runUpdateMimeDatabase(mimeDir);
+
+ QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(),
+ QString::fromLatin1("text/x-suse-ymu"));
+ QVERIFY(db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid());
+ checkHasMimeType("text/x-suse-ymp");
+
+ // Now test removing it again (note, this leaves a mostly-empty mime.cache file)
+ QFile::remove(destFile);
+ waitAndRunUpdateMimeDatabase(mimeDir);
+ QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(),
+ QString::fromLatin1("application/octet-stream"));
+ QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid());
+
+ // And now the user goes wild and uses rm -rf
+ QFile::remove(mimeDir + QString::fromLatin1("/mime.cache"));
+ QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(),
+ QString::fromLatin1("application/octet-stream"));
+ QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid());
+}
+
+QTEST_GUILESS_MAIN(tst_QMimeDatabase)
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h
new file mode 100644
index 0000000000..869990401c
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TST_QMIMEDATABASE_H
+#define TST_QMIMEDATABASE_H
+
+#include <QtCore/QObject>
+
+class tst_QMimeDatabase : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QMimeDatabase();
+
+private slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+ void mimeTypeForName();
+ void mimeTypeForFileName_data();
+ void mimeTypeForFileName();
+ void mimeTypesForFileName_data();
+ void mimeTypesForFileName();
+ void inheritance();
+ void aliases();
+ void icons();
+ void mimeTypeForFileWithContent();
+ void mimeTypeForUrl();
+ void mimeTypeForData_data();
+ void mimeTypeForData();
+ void mimeTypeForFileAndContent_data();
+ void mimeTypeForFileAndContent();
+ void allMimeTypes();
+ void inheritsPerformance();
+ void suffixes_data();
+ void suffixes();
+ void knownSuffix();
+ void fromThreads();
+
+ // shared-mime-info test suite
+
+ void findByFileName_data();
+ void findByFileName();
+
+ void findByData_data();
+ void findByData();
+
+ void findByFile_data();
+ void findByFile();
+
+ //
+
+ void installNewGlobalMimeType();
+ void installNewLocalMimeType();
+
+private:
+ QString m_dataHome;
+};
+
+#endif // TST_QMIMEDATABASE_H
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/yast2-metapackage-handler-mimetypes.xml b/tests/auto/corelib/mimetypes/qmimedatabase/yast2-metapackage-handler-mimetypes.xml
new file mode 100644
index 0000000000..ef3035ef4a
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/yast2-metapackage-handler-mimetypes.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!-- http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec -->
+<!-- to to ${PREFIX-~/.local}/share/mime/packages -->
+<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
+ <mime-type type="text/x-suse-ymp">
+ <comment>YaST Meta Package</comment>
+ <glob pattern="*.ymp"/>
+ </mime-type>
+
+ <mime-type type="text/x-suse-ymu">
+ <comment>URL of a YaST Meta Package</comment>
+ <glob pattern="*.ymu"/>
+ </mime-type>
+</mime-info>
+
diff --git a/tests/auto/corelib/mimetypes/qmimetype/qmimetype.pro b/tests/auto/corelib/mimetypes/qmimetype/qmimetype.pro
new file mode 100644
index 0000000000..125d0d280f
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimetype/qmimetype.pro
@@ -0,0 +1,7 @@
+CONFIG += testcase parallel_test
+TARGET = tst_qmimetype
+QT = core-private testlib
+
+*-g++*:QMAKE_CXXFLAGS += -W -Wall -Wextra -Werror -Wshadow -Wno-long-long -Wnon-virtual-dtor
+
+SOURCES = tst_qmimetype.cpp
diff --git a/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp b/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp
new file mode 100644
index 0000000000..6f24bfe6f1
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp
@@ -0,0 +1,257 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qmimetype_p.h>
+
+#include <qmimetype.h>
+#include <qmimedatabase.h>
+
+#include <QtTest/QtTest>
+
+
+class tst_qmimetype : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+
+ void isValid();
+ void name();
+ void genericIconName();
+ void iconName();
+ void suffixes();
+};
+
+// ------------------------------------------------------------------------------------------------
+
+void tst_qmimetype::initTestCase()
+{
+ qputenv("XDG_DATA_DIRS", "doesnotexist");
+}
+
+// ------------------------------------------------------------------------------------------------
+
+static QString qMimeTypeName()
+{
+ static const QString result ("No name of the MIME type");
+ return result;
+}
+
+static QString qMimeTypeGenericIconName()
+{
+ static const QString result ("No file name of an icon image that represents the MIME type");
+ return result;
+}
+
+static QString qMimeTypeIconName()
+{
+ static const QString result ("No file name of an icon image that represents the MIME type");
+ return result;
+}
+
+static QStringList buildQMimeTypeFilenameExtensions()
+{
+ QStringList result;
+ result << QString::fromLatin1("*.png");
+ return result;
+}
+
+static QStringList qMimeTypeGlobPatterns()
+{
+ static const QStringList result (buildQMimeTypeFilenameExtensions());
+ return result;
+}
+
+// ------------------------------------------------------------------------------------------------
+
+#ifndef Q_COMPILER_RVALUE_REFS
+QMIMETYPE_BUILDER
+#else
+QMIMETYPE_BUILDER_FROM_RVALUE_REFS
+#endif
+
+// ------------------------------------------------------------------------------------------------
+
+void tst_qmimetype::isValid()
+{
+ QMimeType instantiatedQMimeType (
+ buildQMimeType (
+ qMimeTypeName(),
+ qMimeTypeGenericIconName(),
+ qMimeTypeIconName(),
+ qMimeTypeGlobPatterns()
+ )
+ );
+
+ QVERIFY(instantiatedQMimeType.isValid());
+
+ QMimeType otherQMimeType (instantiatedQMimeType);
+
+ QVERIFY(otherQMimeType.isValid());
+ QCOMPARE(instantiatedQMimeType, otherQMimeType);
+
+ QMimeType defaultQMimeType;
+
+ QVERIFY(!defaultQMimeType.isValid());
+}
+
+// ------------------------------------------------------------------------------------------------
+
+void tst_qmimetype::name()
+{
+ QMimeType instantiatedQMimeType (
+ buildQMimeType (
+ qMimeTypeName(),
+ qMimeTypeGenericIconName(),
+ qMimeTypeIconName(),
+ qMimeTypeGlobPatterns()
+ )
+ );
+
+ QMimeType otherQMimeType (
+ buildQMimeType (
+ QString(),
+ qMimeTypeGenericIconName(),
+ qMimeTypeIconName(),
+ qMimeTypeGlobPatterns()
+ )
+ );
+
+ // Verify that the Name is part of the equality test:
+ QCOMPARE(instantiatedQMimeType.name(), qMimeTypeName());
+
+ QVERIFY(instantiatedQMimeType != otherQMimeType);
+ QVERIFY(!(instantiatedQMimeType == otherQMimeType));
+}
+
+// ------------------------------------------------------------------------------------------------
+
+void tst_qmimetype::genericIconName()
+{
+ QMimeType instantiatedQMimeType (
+ buildQMimeType (
+ qMimeTypeName(),
+ qMimeTypeGenericIconName(),
+ qMimeTypeIconName(),
+ qMimeTypeGlobPatterns()
+ )
+ );
+
+ QMimeType otherQMimeType (
+ buildQMimeType (
+ qMimeTypeName(),
+ QString(),
+ qMimeTypeGenericIconName(),
+ qMimeTypeGlobPatterns()
+ )
+ );
+
+ // Verify that the GenericIconName is part of the equality test:
+ QCOMPARE(instantiatedQMimeType.genericIconName(), qMimeTypeGenericIconName());
+
+ QVERIFY(instantiatedQMimeType != otherQMimeType);
+ QVERIFY(!(instantiatedQMimeType == otherQMimeType));
+}
+
+// ------------------------------------------------------------------------------------------------
+
+void tst_qmimetype::iconName()
+{
+ QMimeType instantiatedQMimeType (
+ buildQMimeType (
+ qMimeTypeName(),
+ qMimeTypeGenericIconName(),
+ qMimeTypeIconName(),
+ qMimeTypeGlobPatterns()
+ )
+ );
+
+ QMimeType otherQMimeType (
+ buildQMimeType (
+ qMimeTypeName(),
+ qMimeTypeGenericIconName(),
+ QString(),
+ qMimeTypeGlobPatterns()
+ )
+ );
+
+ // Verify that the IconName is part of the equality test:
+ QCOMPARE(instantiatedQMimeType.iconName(), qMimeTypeIconName());
+
+ QVERIFY(instantiatedQMimeType != otherQMimeType);
+ QVERIFY(!(instantiatedQMimeType == otherQMimeType));
+}
+
+// ------------------------------------------------------------------------------------------------
+
+void tst_qmimetype::suffixes()
+{
+ QMimeType instantiatedQMimeType (
+ buildQMimeType (
+ qMimeTypeName(),
+ qMimeTypeGenericIconName(),
+ qMimeTypeIconName(),
+ qMimeTypeGlobPatterns()
+ )
+ );
+
+ QMimeType otherQMimeType (
+ buildQMimeType (
+ qMimeTypeName(),
+ qMimeTypeGenericIconName(),
+ qMimeTypeIconName(),
+ QStringList()
+ )
+ );
+
+ // Verify that the Suffixes are part of the equality test:
+ QCOMPARE(instantiatedQMimeType.globPatterns(), qMimeTypeGlobPatterns());
+ QCOMPARE(instantiatedQMimeType.suffixes(), QStringList() << QString::fromLatin1("png"));
+
+ QVERIFY(instantiatedQMimeType != otherQMimeType);
+ QVERIFY(!(instantiatedQMimeType == otherQMimeType));
+}
+
+// ------------------------------------------------------------------------------------------------
+
+QTEST_GUILESS_MAIN(tst_qmimetype)
+#include "tst_qmimetype.moc"