aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Vogt <matthew.vogt@nokia.com>2012-07-25 16:59:17 +1000
committerQt by Nokia <qt-info@nokia.com>2012-07-31 00:22:36 +0200
commitc9b7582a2e7ad9fcd03dd999c3b7a16b72803238 (patch)
treed1ffdb193576fef0c243600f46c69b180d2ad2a8
parent2e6accbbbb9783ff6e5ad171f179d5021b0761af (diff)
Implement strict mode for qmldir modules
Allow a module's qmldir to contain a module directive, which when present specifies 'strict mode' import processing. In strict mode, type registrations are only permitted into the namespace identified in the qmldir file's module directive. In addition, any type registrations to that namespace originating from other modules are treated as error conditions. Task-number: QTBUG-26551 Change-Id: I081bde2d3b83d3f28524440177fb2cd1ccee34ad Reviewed-by: Chris Adams <christopher.adams@nokia.com> Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
-rw-r--r--src/imports/folderlistmodel/qmldir1
-rw-r--r--src/imports/localstorage/qmldir3
-rw-r--r--src/imports/particles/qmldir1
-rw-r--r--src/imports/qtquick2/qmldir1
-rw-r--r--src/imports/testlib/qmldir1
-rw-r--r--src/imports/window/qmldir1
-rw-r--r--src/imports/xmllistmodel/qmldir3
-rw-r--r--src/qml/qml/qqmldirparser.cpp42
-rw-r--r--src/qml/qml/qqmldirparser_p.h6
-rw-r--r--src/qml/qml/qqmlengine.cpp2
-rw-r--r--src/qml/qml/qqmlimport.cpp53
-rw-r--r--src/qml/qml/qqmlimport_p.h2
-rw-r--r--src/qml/qml/qqmlmetatype.cpp74
-rw-r--r--src/qml/qml/qqmlmetatype_p.h10
-rw-r--r--src/qml/qml/qqmltypeloader.cpp5
-rw-r--r--src/qml/qml/qqmltypeloader_p.h2
-rw-r--r--tests/auto/qml/qqmlbundle/data/imports/bundletest/bundledata/qmldir1
-rw-r--r--tests/auto/qml/qqmldirparser/data/empty/qmldir0
-rw-r--r--tests/auto/qml/qqmldirparser/data/excessive-module/qmldir1
-rw-r--r--tests/auto/qml/qqmldirparser/data/excessive-plugin/qmldir1
-rw-r--r--tests/auto/qml/qqmldirparser/data/four-sections/qmldir1
-rw-r--r--tests/auto/qml/qqmldirparser/data/incomplete-module/qmldir1
-rw-r--r--tests/auto/qml/qqmldirparser/data/incomplete-plugin/qmldir1
-rw-r--r--tests/auto/qml/qqmldirparser/data/invalid-versioned-component/qmldir1
-rw-r--r--tests/auto/qml/qqmldirparser/data/multiple/qmldir15
-rw-r--r--tests/auto/qml/qqmldirparser/data/name-path-plugin/qmldir1
-rw-r--r--tests/auto/qml/qqmldirparser/data/name-plugin/qmldir1
-rw-r--r--tests/auto/qml/qqmldirparser/data/no-content/qmldir4
-rw-r--r--tests/auto/qml/qqmldirparser/data/non-first-module/qmldir2
-rw-r--r--tests/auto/qml/qqmldirparser/data/one-section/qmldir1
-rw-r--r--tests/auto/qml/qqmldirparser/data/repeated-module/qmldir2
-rw-r--r--tests/auto/qml/qqmldirparser/data/unversioned-component/qmldir1
-rw-r--r--tests/auto/qml/qqmldirparser/data/versioned-component/qmldir1
-rw-r--r--tests/auto/qml/qqmldirparser/data/versioned-script/qmldir1
-rw-r--r--tests/auto/qml/qqmldirparser/qqmldirparser.pro10
-rw-r--r--tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp288
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/data/implicit2/implicitQmldir.2.errors.txt3
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/invalidNamespaceModule.pro12
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/plugin.cpp69
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/qmldir2
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro12
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/plugin.cpp69
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/qmldir2
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/nonstrictModule/nonstrictModule.pro12
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/nonstrictModule/plugin.cpp71
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/nonstrictModule/qmldir1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/plugin.cpp69
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/preemptedStrictModule.pro12
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/qmldir2
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/preemptiveModule/plugin.cpp72
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/preemptiveModule/preemptiveModule.pro12
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/preemptiveModule/qmldir1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro17
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/strictModule/plugin.cpp69
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/strictModule/qmldir2
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/strictModule/strictModule.pro12
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp86
-rw-r--r--tests/auto/quick/qquickanimations/tst_qquickanimations.cpp8
-rw-r--r--tests/auto/quick/qquickwindow/data/ownershipRootItem.qml1
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp2
60 files changed, 1142 insertions, 17 deletions
diff --git a/src/imports/folderlistmodel/qmldir b/src/imports/folderlistmodel/qmldir
index 6e115bbc7e..bbd91356cf 100644
--- a/src/imports/folderlistmodel/qmldir
+++ b/src/imports/folderlistmodel/qmldir
@@ -1 +1,2 @@
+module Qt.labs.folderlistmodel
plugin qmlfolderlistmodelplugin
diff --git a/src/imports/localstorage/qmldir b/src/imports/localstorage/qmldir
index 33288a1afa..8bb2c3bc68 100644
--- a/src/imports/localstorage/qmldir
+++ b/src/imports/localstorage/qmldir
@@ -1 +1,2 @@
-plugin qmllocalstorageplugin \ No newline at end of file
+module QtQuick.LocalStorage
+plugin qmllocalstorageplugin
diff --git a/src/imports/particles/qmldir b/src/imports/particles/qmldir
index 593915f83f..25d58dec0d 100644
--- a/src/imports/particles/qmldir
+++ b/src/imports/particles/qmldir
@@ -1 +1,2 @@
+module QtQuick.Particles
plugin particlesplugin
diff --git a/src/imports/qtquick2/qmldir b/src/imports/qtquick2/qmldir
index bb4d33a5be..1fcbb13f3a 100644
--- a/src/imports/qtquick2/qmldir
+++ b/src/imports/qtquick2/qmldir
@@ -1 +1,2 @@
+module QtQuick
plugin qtquick2plugin
diff --git a/src/imports/testlib/qmldir b/src/imports/testlib/qmldir
index 9e872f9683..d126464e9a 100644
--- a/src/imports/testlib/qmldir
+++ b/src/imports/testlib/qmldir
@@ -1,3 +1,4 @@
+module QtTest
plugin qmltestplugin
TestCase 1.0 TestCase.qml
SignalSpy 1.0 SignalSpy.qml
diff --git a/src/imports/window/qmldir b/src/imports/window/qmldir
index 32844a6ed6..2dad388ba3 100644
--- a/src/imports/window/qmldir
+++ b/src/imports/window/qmldir
@@ -1 +1,2 @@
+module QtQuick.Window
plugin windowplugin
diff --git a/src/imports/xmllistmodel/qmldir b/src/imports/xmllistmodel/qmldir
index dd39bcd7f8..945d15ac9f 100644
--- a/src/imports/xmllistmodel/qmldir
+++ b/src/imports/xmllistmodel/qmldir
@@ -1 +1,2 @@
-plugin qmlxmllistmodelplugin \ No newline at end of file
+module QtQuick.XmlListModel
+plugin qmlxmllistmodelplugin
diff --git a/src/qml/qml/qqmldirparser.cpp b/src/qml/qml/qqmldirparser.cpp
index 0805a24e6d..705f715a00 100644
--- a/src/qml/qml/qqmldirparser.cpp
+++ b/src/qml/qml/qqmldirparser.cpp
@@ -99,11 +99,13 @@ bool QQmlDirParser::parse(const QString &source)
_scripts.clear();
int lineNumber = 0;
+ bool firstLine = true;
const QChar *ch = source.constData();
while (!ch->isNull()) {
++lineNumber;
+ bool invalidLine = false;
const QChar *lineStart = ch;
scanSpace(ch);
@@ -129,6 +131,7 @@ bool QQmlDirParser::parse(const QString &source)
} else {
reportError(lineNumber, start-lineStart, QLatin1String("unexpected token"));
scanToEnd(ch);
+ invalidLine = true;
break;
}
scanSpace(ch);
@@ -137,9 +140,32 @@ bool QQmlDirParser::parse(const QString &source)
if (!ch->isNull())
++ch;
- if (sectionCount == 0) {
+ if (invalidLine) {
+ reportError(lineNumber, -1,
+ QString::fromUtf8("invalid qmldir directive contains too many tokens"));
+ continue;
+ } else if (sectionCount == 0) {
continue; // no sections, no party.
+ } else if (sections[0] == QLatin1String("module")) {
+ if (sectionCount != 2) {
+ reportError(lineNumber, -1,
+ QString::fromUtf8("module directive requires one argument, but %1 were provided").arg(sectionCount - 1));
+ continue;
+ }
+ if (!_typeNamespace.isEmpty()) {
+ reportError(lineNumber, -1,
+ QString::fromUtf8("only one module directive may be defined in a qmldir file"));
+ continue;
+ }
+ if (!firstLine) {
+ reportError(lineNumber, -1,
+ QString::fromUtf8("module directive must be the first directive in a qmldir file"));
+ continue;
+ }
+
+ _typeNamespace = sections[1];
+
} else if (sections[0] == QLatin1String("plugin")) {
if (sectionCount < 2) {
reportError(lineNumber, -1,
@@ -209,6 +235,8 @@ bool QQmlDirParser::parse(const QString &source)
reportError(lineNumber, -1,
QString::fromUtf8("a component declaration requires two or three arguments, but %1 were provided").arg(sectionCount));
}
+
+ firstLine = false;
}
return hasError();
@@ -239,16 +267,28 @@ void QQmlDirParser::setError(const QQmlError &e)
QList<QQmlError> QQmlDirParser::errors(const QString &uri) const
{
+ QUrl url(uri);
QList<QQmlError> errors = _errors;
for (int i = 0; i < errors.size(); ++i) {
QQmlError &e = errors[i];
QString description = e.description();
description.replace(QLatin1String("$$URI$$"), uri);
e.setDescription(description);
+ e.setUrl(url);
}
return errors;
}
+QString QQmlDirParser::typeNamespace() const
+{
+ return _typeNamespace;
+}
+
+void QQmlDirParser::setTypeNamespace(const QString &s)
+{
+ _typeNamespace = s;
+}
+
QList<QQmlDirParser::Plugin> QQmlDirParser::plugins() const
{
return _plugins;
diff --git a/src/qml/qml/qqmldirparser_p.h b/src/qml/qml/qqmldirparser_p.h
index c38a3e1791..7a9078180e 100644
--- a/src/qml/qml/qqmldirparser_p.h
+++ b/src/qml/qml/qqmldirparser_p.h
@@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE
class QQmlError;
class QQmlEngine;
-class QQmlDirParser
+class Q_AUTOTEST_EXPORT QQmlDirParser
{
Q_DISABLE_COPY(QQmlDirParser)
@@ -76,6 +76,9 @@ public:
void setError(const QQmlError &);
QList<QQmlError> errors(const QString &uri) const;
+ QString typeNamespace() const;
+ void setTypeNamespace(const QString &s);
+
struct Plugin
{
Plugin() {}
@@ -139,6 +142,7 @@ private:
private:
QList<QQmlError> _errors;
+ QString _typeNamespace;
QHash<QHashedStringRef,Component> _components; // multi hash
QList<Script> _scripts;
QList<Plugin> _plugins;
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 72c1c35244..65eeb242bb 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -1729,7 +1729,7 @@ void QQmlEngine::setPluginPathList(const QStringList &paths)
bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors)
{
Q_D(QQmlEngine);
- return d->importDatabase.importPlugin(filePath, uri, errors);
+ return d->importDatabase.importPlugin(filePath, uri, QString(), errors);
}
/*!
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 20da154673..e7133992d9 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -47,6 +47,7 @@
#include <QtCore/qfileinfo.h>
#include <QtCore/qpluginloader.h>
#include <QtCore/qlibraryinfo.h>
+#include <QtCore/qreadwritelock.h>
#include <QtQml/qqmlextensioninterface.h>
#include <private/qqmlglobal_p.h>
#include <private/qqmltypenamecache_p.h>
@@ -734,7 +735,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
QString resolvedFilePath = database->resolvePlugin(typeLoader, qmldirPath,
plugin.path, plugin.name);
if (!resolvedFilePath.isEmpty()) {
- if (!database->importPlugin(resolvedFilePath, uri, errors)) {
+ if (!database->importPlugin(resolvedFilePath, uri, qmldir->typeNamespace(), errors)) {
if (errors) {
// XXX TODO: should we leave the import plugin error alone?
// Here, we pop it off the top and coalesce it into this error's message.
@@ -1590,7 +1591,7 @@ void QQmlImportDatabase::setImportPathList(const QStringList &paths)
/*!
\internal
*/
-bool QQmlImportDatabase::importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors)
+bool QQmlImportDatabase::importPlugin(const QString &filePath, const QString &uri, const QString &typeNamespace, QList<QQmlError> *errors)
{
if (qmlImportTrace())
qDebug().nospace() << "QQmlImportDatabase::importPlugin: " << uri << " from " << filePath;
@@ -1635,9 +1636,53 @@ bool QQmlImportDatabase::importPlugin(const QString &filePath, const QString &ur
const char *moduleId = bytes.constData();
if (!typesRegistered) {
- // XXX thread this code should probably be protected with a mutex.
qmlEnginePluginsWithRegisteredTypes()->insert(absoluteFilePath, uri);
- iface->registerTypes(moduleId);
+
+ QStringList registrationFailures;
+
+ {
+ QWriteLocker lock(QQmlMetaType::typeRegistrationLock());
+
+ if (!typeNamespace.isEmpty()) {
+ // This is a 'strict' module
+ if (typeNamespace != uri) {
+ // The namespace for type registrations must match the URI for locating the module
+ QQmlError error;
+ error.setDescription(tr("Module namespace '%1' does not match import URI '%2'").arg(typeNamespace).arg(uri));
+ errors->prepend(error);
+ return false;
+ }
+
+ if (QQmlMetaType::namespaceContainsRegistrations(typeNamespace)) {
+ // Other modules have already installed to this namespace
+ QQmlError error;
+ error.setDescription(tr("Namespace '%1' has already been used for type registration").arg(typeNamespace));
+ errors->prepend(error);
+ return false;
+ } else {
+ QQmlMetaType::protectNamespace(typeNamespace);
+ }
+ } else {
+ // This is not a stict module - provide a warning
+ qWarning().nospace() << qPrintable(tr("Module '%1' does not contain a module directive - it cannot be protected from external registrations.").arg(uri));
+ }
+
+ QQmlMetaType::setTypeRegistrationNamespace(typeNamespace);
+
+ iface->registerTypes(moduleId);
+
+ registrationFailures = QQmlMetaType::typeRegistrationFailures();
+ QQmlMetaType::setTypeRegistrationNamespace(QString());
+ }
+
+ if (!registrationFailures.isEmpty()) {
+ foreach (const QString &failure, registrationFailures) {
+ QQmlError error;
+ error.setDescription(failure);
+ errors->prepend(error);
+ }
+ return false;
+ }
}
if (!engineInitialized) {
// things on the engine (eg. adding new global objects) have to be done for every
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index dbff6fd219..2a1fe48b6e 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -143,7 +143,7 @@ public:
QQmlImportDatabase(QQmlEngine *);
~QQmlImportDatabase();
- bool importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors);
+ bool importPlugin(const QString &filePath, const QString &uri, const QString &importNamespace, QList<QQmlError> *errors);
QStringList importPathList(PathType type = LocalOrRemote) const;
void setImportPathList(const QStringList &paths);
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index c1147b025b..b3a16b034c 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -108,6 +108,11 @@ struct QQmlMetaTypeData
QBitArray lists;
QList<QQmlPrivate::AutoParentFunction> parentFunctions;
+
+ QSet<QString> protectedNamespaces;
+
+ QString typeRegistrationNamespace;
+ QStringList typeRegistrationFailures;
};
class QQmlTypeModulePrivate
@@ -128,7 +133,7 @@ public:
};
Q_GLOBAL_STATIC(QQmlMetaTypeData, metaTypeData)
-Q_GLOBAL_STATIC(QReadWriteLock, metaTypeDataLock)
+Q_GLOBAL_STATIC_WITH_ARGS(QReadWriteLock, metaTypeDataLock, (QReadWriteLock::Recursive))
static uint qHash(const QQmlMetaTypeData::VersionedUri &v)
{
@@ -193,7 +198,7 @@ public:
// Avoid multiple fromUtf8(), copies and hashing of the module name.
// This is only called when metaTypeDataLock is locked.
-static QHashedString moduletoUtf8(const char *module)
+static QHashedString moduleFromUtf8(const char *module)
{
if (!module)
return QHashedString();
@@ -241,7 +246,7 @@ QQmlType::QQmlType(int index, const QQmlPrivate::RegisterInterface &interface)
QQmlType::QQmlType(int index, const QQmlPrivate::RegisterType &type)
: d(new QQmlTypePrivate)
{
- d->m_module = moduletoUtf8(type.uri);
+ d->m_module = moduleFromUtf8(type.uri);
d->m_elementName = QString::fromUtf8(type.elementName);
d->m_version_maj = type.versionMajor;
@@ -902,6 +907,29 @@ int registerType(const QQmlPrivate::RegisterType &type)
QWriteLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
+
+ if (type.uri && type.elementName) {
+ QString nameSpace = moduleFromUtf8(type.uri);
+
+ if (!data->typeRegistrationNamespace.isEmpty()) {
+ // We can only install types into the registered namespace
+ if (nameSpace != data->typeRegistrationNamespace) {
+ QString failure(QCoreApplication::translate("qmlRegisterType",
+ "Cannot install element '%1' into unregistered namespace '%2'"));
+ data->typeRegistrationFailures.append(failure.arg(QString::fromUtf8(type.elementName)).arg(nameSpace));
+ return -1;
+ }
+ } else if (data->typeRegistrationNamespace != nameSpace) {
+ // Is the target namespace protected against further registrations?
+ if (data->protectedNamespaces.contains(nameSpace)) {
+ QString failure(QCoreApplication::translate("qmlRegisterType",
+ "Cannot install element '%1' into protected namespace '%2'"));
+ data->typeRegistrationFailures.append(failure.arg(QString::fromUtf8(type.elementName)).arg(nameSpace));
+ return -1;
+ }
+ }
+ }
+
int index = data->types.count();
QQmlType *dtype = new QQmlType(index, type);
@@ -985,6 +1013,46 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
return -1;
}
+bool QQmlMetaType::namespaceContainsRegistrations(const QString &uri)
+{
+ QQmlMetaTypeData *data = metaTypeData();
+
+ // Has any type previously been installed to this namespace?
+ QHashedString nameSpace(uri);
+ foreach (const QQmlType *type, data->types)
+ if (type->module() == nameSpace)
+ return true;
+
+ return false;
+}
+
+void QQmlMetaType::protectNamespace(const QString &uri)
+{
+ QQmlMetaTypeData *data = metaTypeData();
+
+ data->protectedNamespaces.insert(uri);
+}
+
+void QQmlMetaType::setTypeRegistrationNamespace(const QString &uri)
+{
+ QQmlMetaTypeData *data = metaTypeData();
+
+ data->typeRegistrationNamespace = uri;
+ data->typeRegistrationFailures.clear();
+}
+
+QStringList QQmlMetaType::typeRegistrationFailures()
+{
+ QQmlMetaTypeData *data = metaTypeData();
+
+ return data->typeRegistrationFailures;
+}
+
+QReadWriteLock *QQmlMetaType::typeRegistrationLock()
+{
+ return metaTypeDataLock();
+}
+
/*
Returns true if a module \a uri of any version is installed.
*/
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index fbba733018..6f76c95544 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -69,6 +69,7 @@ class QQmlTypePrivate;
class QQmlTypeModule;
class QHashedString;
class QHashedStringRef;
+class QReadWriteLock;
class Q_QML_PRIVATE_EXPORT QQmlMetaType
{
@@ -139,6 +140,15 @@ public:
static ModuleApi moduleApi(const QString &, int, int);
static QHash<QString, QList<ModuleApi> > moduleApis();
+ static bool namespaceContainsRegistrations(const QString &);
+
+ static void protectNamespace(const QString &);
+
+ static void setTypeRegistrationNamespace(const QString &);
+ static QStringList typeRegistrationFailures();
+
+ static QReadWriteLock *typeRegistrationLock();
+
private:
static CompareFunction anchorLineCompareFunction;
};
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index c66cd283da..0790b7664e 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -1381,6 +1381,11 @@ QList<QQmlError> QQmlTypeLoader::QmldirContent::errors(const QString &uri) const
return m_parser.errors(uri);
}
+QString QQmlTypeLoader::QmldirContent::typeNamespace() const
+{
+ return m_parser.typeNamespace();
+}
+
void QQmlTypeLoader::QmldirContent::setContent(const QString &location, const QString &content)
{
m_location = location;
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index 6461c1c484..47f7742cf0 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -302,6 +302,8 @@ public:
bool hasError() const;
QList<QQmlError> errors(const QString &uri) const;
+ QString typeNamespace() const;
+
QQmlDirComponents components() const;
QQmlDirScripts scripts() const;
QQmlDirPlugins plugins() const;
diff --git a/tests/auto/qml/qqmlbundle/data/imports/bundletest/bundledata/qmldir b/tests/auto/qml/qqmlbundle/data/imports/bundletest/bundledata/qmldir
index db8aabfefd..febddf6a47 100644
--- a/tests/auto/qml/qqmlbundle/data/imports/bundletest/bundledata/qmldir
+++ b/tests/auto/qml/qqmlbundle/data/imports/bundletest/bundledata/qmldir
@@ -1 +1,2 @@
+module bundletest
plugin plugin1
diff --git a/tests/auto/qml/qqmldirparser/data/empty/qmldir b/tests/auto/qml/qqmldirparser/data/empty/qmldir
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/empty/qmldir
diff --git a/tests/auto/qml/qqmldirparser/data/excessive-module/qmldir b/tests/auto/qml/qqmldirparser/data/excessive-module/qmldir
new file mode 100644
index 0000000000..c4fdbd4e35
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/excessive-module/qmldir
@@ -0,0 +1 @@
+module foo bar
diff --git a/tests/auto/qml/qqmldirparser/data/excessive-plugin/qmldir b/tests/auto/qml/qqmldirparser/data/excessive-plugin/qmldir
new file mode 100644
index 0000000000..4acde714ac
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/excessive-plugin/qmldir
@@ -0,0 +1 @@
+plugin foo bar baz
diff --git a/tests/auto/qml/qqmldirparser/data/four-sections/qmldir b/tests/auto/qml/qqmldirparser/data/four-sections/qmldir
new file mode 100644
index 0000000000..03b37a0d27
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/four-sections/qmldir
@@ -0,0 +1 @@
+foo bar baz qux
diff --git a/tests/auto/qml/qqmldirparser/data/incomplete-module/qmldir b/tests/auto/qml/qqmldirparser/data/incomplete-module/qmldir
new file mode 100644
index 0000000000..0cca093d7a
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/incomplete-module/qmldir
@@ -0,0 +1 @@
+module
diff --git a/tests/auto/qml/qqmldirparser/data/incomplete-plugin/qmldir b/tests/auto/qml/qqmldirparser/data/incomplete-plugin/qmldir
new file mode 100644
index 0000000000..8cb205e9b3
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/incomplete-plugin/qmldir
@@ -0,0 +1 @@
+plugin
diff --git a/tests/auto/qml/qqmldirparser/data/invalid-versioned-component/qmldir b/tests/auto/qml/qqmldirparser/data/invalid-versioned-component/qmldir
new file mode 100644
index 0000000000..c322b0f278
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/invalid-versioned-component/qmldir
@@ -0,0 +1 @@
+foo 100 bar
diff --git a/tests/auto/qml/qqmldirparser/data/multiple/qmldir b/tests/auto/qml/qqmldirparser/data/multiple/qmldir
new file mode 100644
index 0000000000..e74bad5617
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/multiple/qmldir
@@ -0,0 +1,15 @@
+
+#
+# Comment
+
+module ModuleNamespace
+
+plugin PluginA plugina.so # More comment
+
+ComponentA 1.0 componenta-1_0.qml
+ScriptA 1.0 scripta-1_0.js
+
+#
+ComponentA 1.5 componenta-1_5.qml
+ComponentB 1.5 componentb-1_5.qml
+
diff --git a/tests/auto/qml/qqmldirparser/data/name-path-plugin/qmldir b/tests/auto/qml/qqmldirparser/data/name-path-plugin/qmldir
new file mode 100644
index 0000000000..5cf8bd345d
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/name-path-plugin/qmldir
@@ -0,0 +1 @@
+plugin foo bar
diff --git a/tests/auto/qml/qqmldirparser/data/name-plugin/qmldir b/tests/auto/qml/qqmldirparser/data/name-plugin/qmldir
new file mode 100644
index 0000000000..fb12cab37d
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/name-plugin/qmldir
@@ -0,0 +1 @@
+plugin foo
diff --git a/tests/auto/qml/qqmldirparser/data/no-content/qmldir b/tests/auto/qml/qqmldirparser/data/no-content/qmldir
new file mode 100644
index 0000000000..3ce87ada21
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/no-content/qmldir
@@ -0,0 +1,4 @@
+
+# only empty lines
+ # and comments
+
diff --git a/tests/auto/qml/qqmldirparser/data/non-first-module/qmldir b/tests/auto/qml/qqmldirparser/data/non-first-module/qmldir
new file mode 100644
index 0000000000..932e43a94c
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/non-first-module/qmldir
@@ -0,0 +1,2 @@
+plugin foo
+module bar
diff --git a/tests/auto/qml/qqmldirparser/data/one-section/qmldir b/tests/auto/qml/qqmldirparser/data/one-section/qmldir
new file mode 100644
index 0000000000..257cc5642c
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/one-section/qmldir
@@ -0,0 +1 @@
+foo
diff --git a/tests/auto/qml/qqmldirparser/data/repeated-module/qmldir b/tests/auto/qml/qqmldirparser/data/repeated-module/qmldir
new file mode 100644
index 0000000000..80c3e0c750
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/repeated-module/qmldir
@@ -0,0 +1,2 @@
+module foo
+module bar
diff --git a/tests/auto/qml/qqmldirparser/data/unversioned-component/qmldir b/tests/auto/qml/qqmldirparser/data/unversioned-component/qmldir
new file mode 100644
index 0000000000..d675fa44e5
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/unversioned-component/qmldir
@@ -0,0 +1 @@
+foo bar
diff --git a/tests/auto/qml/qqmldirparser/data/versioned-component/qmldir b/tests/auto/qml/qqmldirparser/data/versioned-component/qmldir
new file mode 100644
index 0000000000..a2afd1835e
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/versioned-component/qmldir
@@ -0,0 +1 @@
+foo 33.66 bar
diff --git a/tests/auto/qml/qqmldirparser/data/versioned-script/qmldir b/tests/auto/qml/qqmldirparser/data/versioned-script/qmldir
new file mode 100644
index 0000000000..1345a6855b
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/versioned-script/qmldir
@@ -0,0 +1 @@
+foo 33.66 bar.js
diff --git a/tests/auto/qml/qqmldirparser/qqmldirparser.pro b/tests/auto/qml/qqmldirparser/qqmldirparser.pro
new file mode 100644
index 0000000000..8efb415d43
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/qqmldirparser.pro
@@ -0,0 +1,10 @@
+CONFIG += testcase
+TARGET = tst_qqmldirparser
+QT += qml testlib v8-private
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qqmldirparser.cpp
+
+include (../../shared/util.pri)
+
+CONFIG += parallel_test
diff --git a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp
new file mode 100644
index 0000000000..82616ffa8a
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp
@@ -0,0 +1,288 @@
+/****************************************************************************
+**
+** 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 "../../shared/util.h"
+
+#include <qtest.h>
+#include <QObject>
+#include <QQmlEngine>
+#include <QQmlComponent>
+#include <private/v8.h>
+#include <private/qqmldirparser_p.h>
+#include <QDebug>
+
+// Test the parsing of qmldir files
+
+class tst_qqmldirparser : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_qqmldirparser();
+
+private slots:
+ void parse_data();
+ void parse();
+};
+
+tst_qqmldirparser::tst_qqmldirparser()
+{
+}
+
+namespace {
+
+ QStringList toStringList(const QList<QQmlError> &errors)
+ {
+ QStringList rv;
+
+ foreach (const QQmlError &e, errors)
+ rv.append(e.toString());
+
+ return rv;
+ }
+
+ QString toString(const QQmlDirParser::Plugin &p)
+ {
+ return p.name + "|" + p.path;
+ }
+
+ QStringList toStringList(const QList<QQmlDirParser::Plugin> &plugins)
+ {
+ QStringList rv;
+
+ foreach (const QQmlDirParser::Plugin &p, plugins)
+ rv.append(toString(p));
+
+ return rv;
+ }
+
+ QString toString(const QQmlDirParser::Component &c)
+ {
+ return c.typeName + "|" + c.fileName + "|" + QString::number(c.majorVersion) + "|" + QString::number(c.minorVersion) + "|" + (c.internal ? "true" : "false");
+ }
+
+ QStringList toStringList(const QQmlDirComponents &components)
+ {
+ QStringList rv;
+
+ foreach (const QQmlDirParser::Component &c, components.values())
+ rv.append(toString(c));
+
+ qSort(rv);
+ return rv;
+ }
+
+ QString toString(const QQmlDirParser::Script &s)
+ {
+ return s.nameSpace + "|" + s.fileName + "|" + QString::number(s.majorVersion) + "|" + QString::number(s.minorVersion);
+ }
+
+ QStringList toStringList(const QList<QQmlDirParser::Script> &scripts)
+ {
+ QStringList rv;
+
+ foreach (const QQmlDirParser::Script &s, scripts)
+ rv.append(toString(s));
+
+ return rv;
+ }
+}
+
+void tst_qqmldirparser::parse_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QStringList>("errors");
+ QTest::addColumn<QStringList>("plugins");
+ QTest::addColumn<QStringList>("components");
+ QTest::addColumn<QStringList>("scripts");
+
+ QTest::newRow("empty")
+ << "empty/qmldir"
+ << QStringList()
+ << QStringList()
+ << QStringList()
+ << QStringList();
+
+ QTest::newRow("no-content")
+ << "no-content/qmldir"
+ << QStringList()
+ << QStringList()
+ << QStringList()
+ << QStringList();
+
+ QTest::newRow("one-section")
+ << "one-section/qmldir"
+ << (QStringList() << "qmldir:1: a component declaration requires two or three arguments, but 1 were provided")
+ << QStringList()
+ << QStringList()
+ << QStringList();
+
+ QTest::newRow("four-sections")
+ << "four-sections/qmldir"
+ << (QStringList() << "qmldir:1:12: unexpected token"
+ << "qmldir:1: invalid qmldir directive contains too many tokens")
+ << QStringList()
+ << QStringList()
+ << QStringList();
+
+ QTest::newRow("incomplete-module")
+ << "incomplete-module/qmldir"
+ << (QStringList() << "qmldir:1: module directive requires one argument, but 0 were provided")
+ << QStringList()
+ << QStringList()
+ << QStringList();
+
+ QTest::newRow("excessive-module")
+ << "excessive-module/qmldir"
+ << (QStringList() << "qmldir:1: module directive requires one argument, but 2 were provided")
+ << QStringList()
+ << QStringList()
+ << QStringList();
+
+ QTest::newRow("repeated-module")
+ << "repeated-module/qmldir"
+ << (QStringList() << "qmldir:2: only one module directive may be defined in a qmldir file")
+ << QStringList()
+ << QStringList()
+ << QStringList();
+
+ QTest::newRow("non-first-module")
+ << "non-first-module/qmldir"
+ << (QStringList() << "qmldir:2: module directive must be the first directive in a qmldir file")
+ << (QStringList() << "foo|")
+ << QStringList()
+ << QStringList();
+
+ QTest::newRow("incomplete-plugin")
+ << "incomplete-plugin/qmldir"
+ << (QStringList() << "qmldir:1: plugin directive requires one or two arguments, but 0 were provided")
+ << QStringList()
+ << QStringList()
+ << QStringList();
+
+ QTest::newRow("excessive-plugin")
+ << "excessive-plugin/qmldir"
+ << (QStringList() << "qmldir:1:15: unexpected token"
+ << "qmldir:1: invalid qmldir directive contains too many tokens")
+ << QStringList()
+ << QStringList()
+ << QStringList();
+
+ QTest::newRow("name-plugin")
+ << "name-plugin/qmldir"
+ << QStringList()
+ << (QStringList() << "foo|")
+ << QStringList()
+ << QStringList();
+
+ QTest::newRow("name-path-plugin")
+ << "name-path-plugin/qmldir"
+ << QStringList()
+ << (QStringList() << "foo|bar")
+ << QStringList()
+ << QStringList();
+
+ QTest::newRow("unversioned-component")
+ << "unversioned-component/qmldir"
+ << QStringList()
+ << QStringList()
+ << (QStringList() << "foo|bar|-1|-1|false")
+ << QStringList();
+
+ QTest::newRow("invalid-versioned-component")
+ << "invalid-versioned-component/qmldir"
+ << (QStringList() << "qmldir:1: expected '.'")
+ << QStringList()
+ << QStringList()
+ << QStringList();
+
+ QTest::newRow("versioned-component")
+ << "versioned-component/qmldir"
+ << QStringList()
+ << QStringList()
+ << (QStringList() << "foo|bar|33|66|false")
+ << QStringList();
+
+ QTest::newRow("versioned-script")
+ << "versioned-script/qmldir"
+ << QStringList()
+ << QStringList()
+ << QStringList()
+ << (QStringList() << "foo|bar.js|33|66");
+
+ QTest::newRow("multiple")
+ << "multiple/qmldir"
+ << QStringList()
+ << (QStringList() << "PluginA|plugina.so")
+ << (QStringList() << "ComponentA|componenta-1_0.qml|1|0|false"
+ << "ComponentA|componenta-1_5.qml|1|5|false"
+ << "ComponentB|componentb-1_5.qml|1|5|false")
+ << (QStringList() << "ScriptA|scripta-1_0.js|1|0");
+}
+
+void tst_qqmldirparser::parse()
+{
+ QFETCH(QString, file);
+ QFETCH(QStringList, errors);
+ QFETCH(QStringList, plugins);
+ QFETCH(QStringList, components);
+ QFETCH(QStringList, scripts);
+
+ QFile f(testFile(file));
+ f.open(QIODevice::ReadOnly);
+
+ QQmlDirParser p;
+ p.parse(f.readAll());
+
+ if (errors.isEmpty()) {
+ QCOMPARE(p.hasError(), false);
+ } else {
+ QCOMPARE(p.hasError(), true);
+ QCOMPARE(toStringList(p.errors("qmldir")), errors);
+ }
+
+ QCOMPARE(toStringList(p.plugins()), plugins);
+ QCOMPARE(toStringList(p.components()), components);
+ QCOMPARE(toStringList(p.scripts()), scripts);
+}
+
+QTEST_MAIN(tst_qqmldirparser)
+
+#include "tst_qqmldirparser.moc"
diff --git a/tests/auto/qml/qqmlmoduleplugin/data/implicit2/implicitQmldir.2.errors.txt b/tests/auto/qml/qqmlmoduleplugin/data/implicit2/implicitQmldir.2.errors.txt
index 9cafb78740..08492af787 100644
--- a/tests/auto/qml/qqmlmoduleplugin/data/implicit2/implicitQmldir.2.errors.txt
+++ b/tests/auto/qml/qqmlmoduleplugin/data/implicit2/implicitQmldir.2.errors.txt
@@ -1,3 +1,4 @@
1:12:unexpected token
-1:-1:expected '.'
+1:-1:invalid qmldir directive contains too many tokens
2:17:unexpected token
+2:-1:invalid qmldir directive contains too many tokens
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/invalidNamespaceModule.pro b/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/invalidNamespaceModule.pro
new file mode 100644
index 0000000000..36b054064c
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/invalidNamespaceModule.pro
@@ -0,0 +1,12 @@
+TEMPLATE = lib
+CONFIG += plugin
+SOURCES = plugin.cpp
+QT = core qml
+DESTDIR = ../imports/com/nokia/InvalidNamespaceModule
+
+QT += core-private gui-private qml-private
+
+IMPORT_FILES = \
+ qmldir
+
+include (../../../shared/imports.pri)
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/plugin.cpp
new file mode 100644
index 0000000000..d682510153
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/plugin.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** 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 <QStringList>
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+#include <QDebug>
+
+class MyPluginType : public QObject
+{
+ Q_OBJECT
+public:
+ MyPluginType(QObject *parent=0) : QObject(parent) {}
+};
+
+
+class MyPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+
+public:
+ MyPlugin() {}
+
+ void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == "com.nokia.InvalidStrictModule");
+ qmlRegisterType<MyPluginType>("com.nokia.SomeOtherModule", 1, 0, "MyPluginType");
+ }
+};
+
+#include "plugin.moc"
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/qmldir b/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/qmldir
new file mode 100644
index 0000000000..5f349709f2
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/qmldir
@@ -0,0 +1,2 @@
+module com.nokia.AwesomeModule
+plugin invalidNamespaceModule
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro b/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro
new file mode 100644
index 0000000000..7caa6c4605
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro
@@ -0,0 +1,12 @@
+TEMPLATE = lib
+CONFIG += plugin
+SOURCES = plugin.cpp
+QT = core qml
+DESTDIR = ../imports/com/nokia/InvalidStrictModule
+
+QT += core-private gui-private qml-private
+
+IMPORT_FILES = \
+ qmldir
+
+include (../../../shared/imports.pri)
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/plugin.cpp
new file mode 100644
index 0000000000..d682510153
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/plugin.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** 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 <QStringList>
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+#include <QDebug>
+
+class MyPluginType : public QObject
+{
+ Q_OBJECT
+public:
+ MyPluginType(QObject *parent=0) : QObject(parent) {}
+};
+
+
+class MyPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+
+public:
+ MyPlugin() {}
+
+ void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == "com.nokia.InvalidStrictModule");
+ qmlRegisterType<MyPluginType>("com.nokia.SomeOtherModule", 1, 0, "MyPluginType");
+ }
+};
+
+#include "plugin.moc"
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/qmldir b/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/qmldir
new file mode 100644
index 0000000000..45752a9bca
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/qmldir
@@ -0,0 +1,2 @@
+module com.nokia.InvalidStrictModule
+plugin invalidStrictModule
diff --git a/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/nonstrictModule.pro b/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/nonstrictModule.pro
new file mode 100644
index 0000000000..e29578483b
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/nonstrictModule.pro
@@ -0,0 +1,12 @@
+TEMPLATE = lib
+CONFIG += plugin
+SOURCES = plugin.cpp
+QT = core qml
+DESTDIR = ../imports/com/nokia/NonstrictModule
+
+QT += core-private gui-private qml-private
+
+IMPORT_FILES = \
+ qmldir
+
+include (../../../shared/imports.pri)
diff --git a/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/plugin.cpp
new file mode 100644
index 0000000000..73e1056d6f
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/plugin.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** 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 <QStringList>
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+#include <QDebug>
+
+class MyPluginType : public QObject
+{
+ Q_OBJECT
+public:
+ MyPluginType(QObject *parent=0) : QObject(parent) {}
+};
+
+
+class MyPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+
+public:
+ MyPlugin() {}
+
+ void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == "com.nokia.NonstrictModule");
+
+ // Install into a namespace that should be protected
+ qmlRegisterType<MyPluginType>("com.nokia.StrictModule", 1, 0, "MyPluginType");
+ }
+};
+
+#include "plugin.moc"
diff --git a/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/qmldir b/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/qmldir
new file mode 100644
index 0000000000..7371ee759f
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/qmldir
@@ -0,0 +1 @@
+plugin nonstrictModule
diff --git a/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/plugin.cpp
new file mode 100644
index 0000000000..f7f7c77bb5
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/plugin.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** 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 <QStringList>
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+#include <QDebug>
+
+class MyPluginType : public QObject
+{
+ Q_OBJECT
+public:
+ MyPluginType(QObject *parent=0) : QObject(parent) {}
+};
+
+
+class MyPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+
+public:
+ MyPlugin() {}
+
+ void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == "com.nokia.PreemptedStrictModule");
+ qmlRegisterType<MyPluginType>(uri, 1, 0, "MyPluginType");
+ }
+};
+
+#include "plugin.moc"
diff --git a/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/preemptedStrictModule.pro b/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/preemptedStrictModule.pro
new file mode 100644
index 0000000000..76934e7657
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/preemptedStrictModule.pro
@@ -0,0 +1,12 @@
+TEMPLATE = lib
+CONFIG += plugin
+SOURCES = plugin.cpp
+QT = core qml
+DESTDIR = ../imports/com/nokia/PreemptedStrictModule
+
+QT += core-private gui-private qml-private
+
+IMPORT_FILES = \
+ qmldir
+
+include (../../../shared/imports.pri)
diff --git a/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/qmldir b/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/qmldir
new file mode 100644
index 0000000000..c82acd2fd3
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/qmldir
@@ -0,0 +1,2 @@
+module com.nokia.PreemptedStrictModule
+plugin preemptedStrictModule
diff --git a/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/plugin.cpp
new file mode 100644
index 0000000000..0b3dd78e79
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/plugin.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** 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 <QStringList>
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+#include <QDebug>
+
+class MyPluginType : public QObject
+{
+ Q_OBJECT
+public:
+ MyPluginType(QObject *parent=0) : QObject(parent) {}
+};
+
+
+class MyPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+
+public:
+ MyPlugin() {}
+
+ void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == "com.nokia.PreemptiveModule");
+ qmlRegisterType<MyPluginType>("com.nokia.PreemptiveModule", 1, 0, "MyPluginType");
+
+ // Install into another namespace that should be protected
+ qmlRegisterType<MyPluginType>("com.nokia.PreemptedStrictModule", 1, 0, "MyPluginType");
+ }
+};
+
+#include "plugin.moc"
diff --git a/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/preemptiveModule.pro b/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/preemptiveModule.pro
new file mode 100644
index 0000000000..e50c722543
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/preemptiveModule.pro
@@ -0,0 +1,12 @@
+TEMPLATE = lib
+CONFIG += plugin
+SOURCES = plugin.cpp
+QT = core qml
+DESTDIR = ../imports/com/nokia/PreemptiveModule
+
+QT += core-private gui-private qml-private
+
+IMPORT_FILES = \
+ qmldir
+
+include (../../../shared/imports.pri)
diff --git a/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/qmldir b/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/qmldir
new file mode 100644
index 0000000000..d240cafac9
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/qmldir
@@ -0,0 +1 @@
+plugin preemptiveModule
diff --git a/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro b/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
index 6da88320cd..c020ce955d 100644
--- a/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
@@ -1,6 +1,21 @@
QT = core
TEMPLATE = subdirs
-SUBDIRS = plugin plugin.2 plugin.2.1 pluginWrongCase pluginWithQmlFile pluginMixed pluginVersion nestedPlugin
+SUBDIRS =\
+ plugin\
+ plugin.2\
+ plugin.2.1\
+ pluginWrongCase\
+ pluginWithQmlFile\
+ pluginMixed\
+ pluginVersion\
+ nestedPlugin\
+ strictModule\
+ invalidStrictModule\
+ nonstrictModule\
+ preemptiveModule\
+ preemptedStrictModule\
+ invalidNamespaceModule
+
tst_qqmlmoduleplugin_pro.depends += plugin
SUBDIRS += tst_qqmlmoduleplugin.pro
diff --git a/tests/auto/qml/qqmlmoduleplugin/strictModule/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/strictModule/plugin.cpp
new file mode 100644
index 0000000000..4bc8108901
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/strictModule/plugin.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** 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 <QStringList>
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+#include <QDebug>
+
+class MyPluginType : public QObject
+{
+ Q_OBJECT
+public:
+ MyPluginType(QObject *parent=0) : QObject(parent) {}
+};
+
+
+class MyPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+
+public:
+ MyPlugin() {}
+
+ void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == "com.nokia.StrictModule");
+ qmlRegisterType<MyPluginType>(uri, 1, 0, "MyPluginType");
+ }
+};
+
+#include "plugin.moc"
diff --git a/tests/auto/qml/qqmlmoduleplugin/strictModule/qmldir b/tests/auto/qml/qqmlmoduleplugin/strictModule/qmldir
new file mode 100644
index 0000000000..ff06446fbd
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/strictModule/qmldir
@@ -0,0 +1,2 @@
+module com.nokia.StrictModule
+plugin strictModule
diff --git a/tests/auto/qml/qqmlmoduleplugin/strictModule/strictModule.pro b/tests/auto/qml/qqmlmoduleplugin/strictModule/strictModule.pro
new file mode 100644
index 0000000000..9c6d83f7a3
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/strictModule/strictModule.pro
@@ -0,0 +1,12 @@
+TEMPLATE = lib
+CONFIG += plugin
+SOURCES = plugin.cpp
+QT = core qml
+DESTDIR = ../imports/com/nokia/StrictModule
+
+QT += core-private gui-private qml-private
+
+IMPORT_FILES = \
+ qmldir
+
+include (../../../shared/imports.pri)
diff --git a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
index 67b3d00196..99e2874060 100644
--- a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
+++ b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
@@ -50,6 +50,10 @@
#define SERVER_ADDR "http://127.0.0.1:14456"
#define SERVER_PORT 14456
+// Note: this test does not use module directives in the qmldir files, because
+// it would result in repeated attempts to insert types into the same namespace.
+// This occurs because type registration is process-global, while the test
+// cases should really be run in proper per-process isolation.
class tst_qqmlmoduleplugin : public QQmlDataTest
{
@@ -74,6 +78,8 @@ private slots:
void importsNested_data();
void importLocalModule();
void importLocalModule_data();
+ void importStrictModule();
+ void importStrictModule_data();
private:
QString m_importsDirectory;
@@ -135,6 +141,7 @@ void tst_qqmlmoduleplugin::importsPlugin()
engine.addImportPath(m_importsDirectory);
QTest::ignoreMessage(QtWarningMsg, "plugin created");
QTest::ignoreMessage(QtWarningMsg, "import worked");
+ QTest::ignoreMessage(QtWarningMsg, "Module 'com.nokia.AutoTestQmlPluginType' does not contain a module directive - it cannot be protected from external registrations.");
QQmlComponent component(&engine, testFileUrl(QStringLiteral("works.qml")));
foreach (QQmlError err, component.errors())
qWarning() << err;
@@ -151,6 +158,7 @@ void tst_qqmlmoduleplugin::importsPlugin2()
engine.addImportPath(m_importsDirectory);
QTest::ignoreMessage(QtWarningMsg, "plugin2 created");
QTest::ignoreMessage(QtWarningMsg, "import2 worked");
+ QTest::ignoreMessage(QtWarningMsg, "Module 'com.nokia.AutoTestQmlPluginType' does not contain a module directive - it cannot be protected from external registrations.");
QQmlComponent component(&engine, testFileUrl(QStringLiteral("works2.qml")));
foreach (QQmlError err, component.errors())
qWarning() << err;
@@ -167,6 +175,7 @@ void tst_qqmlmoduleplugin::importsPlugin21()
engine.addImportPath(m_importsDirectory);
QTest::ignoreMessage(QtWarningMsg, "plugin2.1 created");
QTest::ignoreMessage(QtWarningMsg, "import2.1 worked");
+ QTest::ignoreMessage(QtWarningMsg, "Module 'com.nokia.AutoTestQmlPluginType' does not contain a module directive - it cannot be protected from external registrations.");
QQmlComponent component(&engine, testFileUrl(QStringLiteral("works21.qml")));
foreach (QQmlError err, component.errors())
qWarning() << err;
@@ -215,6 +224,8 @@ void tst_qqmlmoduleplugin::importPluginWithQmlFile()
QQmlEngine engine;
engine.addImportPath(path);
+ QTest::ignoreMessage(QtWarningMsg, "Module 'com.nokia.AutoTestPluginWithQmlFile' does not contain a module directive - it cannot be protected from external registrations.");
+
QQmlComponent component(&engine, testFileUrl(QStringLiteral("pluginWithQmlFile.qml")));
foreach (QQmlError err, component.errors())
qWarning() << err;
@@ -275,6 +286,8 @@ void tst_qqmlmoduleplugin::importsMixedQmlCppPlugin()
QQmlEngine engine;
engine.addImportPath(m_importsDirectory);
+ QTest::ignoreMessage(QtWarningMsg, "Module 'com.nokia.AutoTestQmlMixedPluginType' does not contain a module directive - it cannot be protected from external registrations.");
+
{
QQmlComponent component(&engine, testFileUrl(QStringLiteral("importsMixedQmlCppPlugin.qml")));
@@ -314,6 +327,10 @@ void tst_qqmlmoduleplugin::versionNotInstalled()
QQmlEngine engine;
engine.addImportPath(m_importsDirectory);
+ static int count = 0;
+ if (++count == 1)
+ QTest::ignoreMessage(QtWarningMsg, "Module 'com.nokia.AutoTestQmlVersionPluginType' does not contain a module directive - it cannot be protected from external registrations.");
+
QQmlComponent component(&engine, testFileUrl(file));
VERIFY_ERRORS(errorFile.toLatin1().constData());
}
@@ -382,6 +399,10 @@ void tst_qqmlmoduleplugin::importsNested()
QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready");
}
+ static int count = 0;
+ if (++count == 1)
+ QTest::ignoreMessage(QtWarningMsg, "Module 'com.nokia.AutoTestQmlNestedPluginType' does not contain a module directive - it cannot be protected from external registrations.");
+
QQmlComponent component(&engine, testFile(file));
QObject *obj = component.create();
@@ -446,6 +467,71 @@ void tst_qqmlmoduleplugin::importLocalModule_data()
<< 2 << 0;
}
+void tst_qqmlmoduleplugin::importStrictModule()
+{
+ QFETCH(QString, qml);
+ QFETCH(QString, warning);
+ QFETCH(QString, error);
+
+ if (!warning.isEmpty())
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
+
+ QQmlEngine engine;
+ engine.addImportPath(m_importsDirectory);
+
+ QUrl url(testFileUrl("empty.qml"));
+
+ QQmlComponent component(&engine);
+ component.setData(qml.toUtf8(), url);
+
+ if (error.isEmpty()) {
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(object != 0);
+ } else {
+ QVERIFY(!component.isReady());
+ QCOMPARE(component.errors().count(), 1);
+ QCOMPARE(component.errors().first().toString(), url.toString() + error);
+ }
+}
+
+void tst_qqmlmoduleplugin::importStrictModule_data()
+{
+ QTest::addColumn<QString>("qml");
+ QTest::addColumn<QString>("warning");
+ QTest::addColumn<QString>("error");
+
+ QTest::newRow("success")
+ << "import com.nokia.StrictModule 1.0\n"
+ "MyPluginType {}"
+ << QString()
+ << QString();
+
+ QTest::newRow("wrong target")
+ << "import com.nokia.InvalidStrictModule 1.0\n"
+ "MyPluginType {}"
+ << QString()
+ << ":1:1: plugin cannot be loaded for module \"com.nokia.InvalidStrictModule\": Cannot install element 'MyPluginType' into unregistered namespace 'com.nokia.SomeOtherModule'";
+
+ QTest::newRow("non-strict clash")
+ << "import com.nokia.NonstrictModule 1.0\n"
+ "MyPluginType {}"
+ << "Module 'com.nokia.NonstrictModule' does not contain a module directive - it cannot be protected from external registrations."
+ << ":1:1: plugin cannot be loaded for module \"com.nokia.NonstrictModule\": Cannot install element 'MyPluginType' into protected namespace 'com.nokia.StrictModule'";
+
+ QTest::newRow("non-strict preemption")
+ << "import com.nokia.PreemptiveModule 1.0\n"
+ "import com.nokia.PreemptedStrictModule 1.0\n"
+ "MyPluginType {}"
+ << "Module 'com.nokia.PreemptiveModule' does not contain a module directive - it cannot be protected from external registrations."
+ << ":2:1: plugin cannot be loaded for module \"com.nokia.PreemptedStrictModule\": Namespace 'com.nokia.PreemptedStrictModule' has already been used for type registration";
+
+ QTest::newRow("invalid namespace")
+ << "import com.nokia.InvalidNamespaceModule 1.0\n"
+ "MyPluginType {}"
+ << QString()
+ << ":1:1: plugin cannot be loaded for module \"com.nokia.InvalidNamespaceModule\": Module namespace 'com.nokia.AwesomeModule' does not match import URI 'com.nokia.InvalidNamespaceModule'";
+}
+
QTEST_MAIN(tst_qqmlmoduleplugin)
#include "tst_qqmlmoduleplugin.moc"
diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
index b5ab04cccd..56fb1e9c00 100644
--- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
+++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
@@ -642,7 +642,13 @@ void tst_qquickanimations::resume()
QVERIFY(!animation.isPaused());
QCOMPARE(spy.count(), 2);
- qmlRegisterType<QQuickPropertyAnimation>("QtQuick",2,0,"PropertyAnimation"); //make sure QQuickPropertyAnimation has correct qml type name
+ // Load QtQuick to ensure that QQuickPropertyAnimation is registered as PropertyAnimation
+ {
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0\nQtObject {}\n", QUrl());
+ }
+
QByteArray message = "<Unknown File>: QML PropertyAnimation: setPaused() cannot be used when animation isn't running.";
QTest::ignoreMessage(QtWarningMsg, message);
animation.pause();
diff --git a/tests/auto/quick/qquickwindow/data/ownershipRootItem.qml b/tests/auto/quick/qquickwindow/data/ownershipRootItem.qml
index dfc4159f4e..4b892b2b84 100644
--- a/tests/auto/quick/qquickwindow/data/ownershipRootItem.qml
+++ b/tests/auto/quick/qquickwindow/data/ownershipRootItem.qml
@@ -1,5 +1,6 @@
import QtQuick 2.0
import QtQuick.Window 2.0 as Window
+import Test 1.0
Window.Window {
RootItemAccessor {
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index 01d60361b4..f29df6910b 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -1046,7 +1046,7 @@ void tst_qquickwindow::ignoreUnhandledMouseEvents()
void tst_qquickwindow::ownershipRootItem()
{
- qmlRegisterType<RootItemAccessor>("QtQuick", 2, 0, "RootItemAccessor");
+ qmlRegisterType<RootItemAccessor>("Test", 1, 0, "RootItemAccessor");
QQmlEngine engine;
QQmlComponent component(&engine);