diff options
Diffstat (limited to 'tests/auto/qml')
-rw-r--r-- | tests/auto/qml/qqmltypeloader/data/Intercept.qml | 41 | ||||
-rw-r--r-- | tests/auto/qml/qqmltypeloader/data/test_intercept.qml | 53 | ||||
-rw-r--r-- | tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp | 168 |
3 files changed, 262 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmltypeloader/data/Intercept.qml b/tests/auto/qml/qqmltypeloader/data/Intercept.qml new file mode 100644 index 0000000000..b557b4b941 --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/data/Intercept.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Fast 1.0 + +Item { + Rectangle { + color: "red" + width: 100 + height: 100 + } + Fast { + + } +} diff --git a/tests/auto/qml/qqmltypeloader/data/test_intercept.qml b/tests/auto/qml/qqmltypeloader/data/test_intercept.qml new file mode 100644 index 0000000000..091fbe7f49 --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/data/test_intercept.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +ListView { + width: 400 + height: 500 + model: 2 + + id: test + property int created: 0 + property int loaded: 0 + + delegate: Loader { + width: ListView.view.width + height: 100 + asynchronous: true + source: "Intercept.qml" + + onLoaded: { + test.loaded++ + } + Component.onCompleted: { + test.created++ + } + } +} diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp index 68b450ab26..12aeff7591 100644 --- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp +++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp @@ -28,6 +28,7 @@ #include <QtTest/QtTest> #include <QtQml/qqmlengine.h> +#include <QtQml/qqmlnetworkaccessmanagerfactory.h> #include <QtQuick/qquickview.h> #include <QtQuick/qquickitem.h> #include <QtQml/private/qqmlengine_p.h> @@ -45,6 +46,7 @@ private slots: void trimCache2(); void keepSingleton(); void keepRegistrations(); + void intercept(); }; void tst_QQMLTypeLoader::testLoadComplete() @@ -192,6 +194,172 @@ void tst_QQMLTypeLoader::keepRegistrations() verifyTypes(true, false); // qmlRegisterType creates an undeletable type. } +class NetworkReply : public QNetworkReply +{ +public: + NetworkReply() + { + open(QIODevice::ReadOnly); + } + + void setData(const QByteArray &data) + { + if (isFinished()) + return; + m_buffer = data; + emit readyRead(); + setFinished(true); + emit finished(); + } + + void fail() + { + if (isFinished()) + return; + m_buffer.clear(); + setError(ContentNotFoundError, "content not found"); + emit error(ContentNotFoundError); + setFinished(true); + emit finished(); + } + + qint64 bytesAvailable() const override + { + return m_buffer.size(); + } + + qint64 readData(char *data, qint64 maxlen) override + { + if (m_buffer.length() < maxlen) + maxlen = m_buffer.length(); + std::memcpy(data, m_buffer.data(), maxlen); + m_buffer.remove(0, maxlen); + return maxlen; + } + + void abort() override + { + if (isFinished()) + return; + m_buffer.clear(); + setFinished(true); + emit finished(); + } + +private: + QByteArray m_buffer; +}; + +class NetworkAccessManager : public QNetworkAccessManager +{ + Q_OBJECT +public: + + NetworkAccessManager(QObject *parent) : QNetworkAccessManager(parent) + { + } + + QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, + QIODevice *outgoingData) override + { + QUrl url = request.url(); + QString scheme = url.scheme(); + if (op != GetOperation || !scheme.endsWith("+debug")) + return QNetworkAccessManager::createRequest(op, request, outgoingData); + + scheme.chop(sizeof("+debug") - 1); + url.setScheme(scheme); + + NetworkReply *reply = new NetworkReply; + QString filename = QQmlFile::urlToLocalFileOrQrc(url); + QTimer::singleShot(10, reply, [this, reply, filename]() { + if (filename.isEmpty()) { + reply->fail(); + } else { + QFile file(filename); + if (file.open(QIODevice::ReadOnly)) { + emit loaded(filename); + reply->setData(file.readAll()); + } else + reply->fail(); + } + }); + return reply; + } + +signals: + void loaded(const QString &filename); +}; + +class NetworkAccessManagerFactory : public QQmlNetworkAccessManagerFactory +{ +public: + QStringList loadedFiles; + + QNetworkAccessManager *create(QObject *parent) override + { + NetworkAccessManager *manager = new NetworkAccessManager(parent); + QObject::connect(manager, &NetworkAccessManager::loaded, [this](const QString &filename) { + loadedFiles.append(filename); + }); + return manager; + } +}; + +class UrlInterceptor : public QQmlAbstractUrlInterceptor +{ +public: + QUrl intercept(const QUrl &path, DataType type) override + { + Q_UNUSED(type); + if (!QQmlFile::isLocalFile(path)) + return path; + + // Don't rewrite internal Qt paths. We'd hit C++ plugins there. + QString filename = QQmlFile::urlToLocalFileOrQrc(path); + if (filename.startsWith(":/qt-project.org/") + || filename.startsWith(QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath))) { + return path; + } + + QUrl result = path; + QString scheme = result.scheme(); + if (!scheme.endsWith("+debug")) + result.setScheme(scheme + "+debug"); + return result; + } +}; + +void tst_QQMLTypeLoader::intercept() +{ + QQmlEngine engine; + engine.addImportPath(dataDirectory()); + + UrlInterceptor interceptor; + NetworkAccessManagerFactory factory; + + engine.setUrlInterceptor(&interceptor); + engine.setNetworkAccessManagerFactory(&factory); + + QQmlComponent component(&engine, testFileUrl("test_intercept.qml")); + + QVERIFY(component.status() != QQmlComponent::Ready); + QTRY_VERIFY2(component.status() == QQmlComponent::Ready, + component.errorString().toUtf8().constData()); + + QScopedPointer<QObject> o(component.create()); + QVERIFY(o.data()); + + QTRY_COMPARE(o->property("created").toInt(), 2); + QTRY_COMPARE(o->property("loaded").toInt(), 2); + + QCOMPARE(factory.loadedFiles.length(), 4); + QVERIFY(factory.loadedFiles.contains(dataDirectory() + "/test_intercept.qml")); + QVERIFY(factory.loadedFiles.contains(dataDirectory() + "/Intercept.qml")); + QVERIFY(factory.loadedFiles.contains(dataDirectory() + "/Fast/qmldir")); + QVERIFY(factory.loadedFiles.contains(dataDirectory() + "/Fast/Fast.qml")); +} + QTEST_MAIN(tst_QQMLTypeLoader) #include "tst_qqmltypeloader.moc" |