From 9baa491a068d6cc3a0276949b538ae8f415ae1ad Mon Sep 17 00:00:00 2001 From: David Faure Date: Wed, 3 Aug 2016 20:01:58 +0200 Subject: [PATCH 1/8] autotests: fix finding data files when not in CWD These tests now can find their data files even when running from a different directory than the source directory, and they no longer misuse QUrl::fromLocalFile for a relative URL (resolved with QUrl::resolved). Change-Id: If18afd2e29571cca2a4c820eda6b9f6713e08a92 Reviewed-by: Simon Hausmann --- .../tst_qquickframebufferobject.cpp | 4 +- .../qquickopenglinfo/tst_qquickopenglinfo.cpp | 2 +- .../auto/quick/scenegraph/tst_scenegraph.cpp | 46 ++++++++----------- 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp b/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp index ada372cfdd..a3be728f5e 100644 --- a/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp +++ b/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp @@ -185,7 +185,7 @@ void tst_QQuickFramebufferObject::testThatStuffWorks() qmlRegisterType("FBOItem", 1, 0, "FBOItem"); QQuickView view; - view.setSource(QUrl::fromLocalFile("data/testStuff.qml")); + view.setSource(testFileUrl("testStuff.qml")); FBOItem *item = view.rootObject()->findChild("fbo"); @@ -229,7 +229,7 @@ void tst_QQuickFramebufferObject::testInvalidate() qmlRegisterType("FBOItem", 1, 0, "FBOItem"); QQuickView view; - view.setSource(QUrl::fromLocalFile("data/testStuff.qml")); + view.setSource(testFileUrl("testStuff.qml")); FBOItem *item = view.rootObject()->findChild("fbo"); item->setTextureFollowsItemSize(false); diff --git a/tests/auto/quick/qquickopenglinfo/tst_qquickopenglinfo.cpp b/tests/auto/quick/qquickopenglinfo/tst_qquickopenglinfo.cpp index 29bcce802f..7446eaec0f 100644 --- a/tests/auto/quick/qquickopenglinfo/tst_qquickopenglinfo.cpp +++ b/tests/auto/quick/qquickopenglinfo/tst_qquickopenglinfo.cpp @@ -53,7 +53,7 @@ private slots: void tst_QQuickOpenGLInfo::testProperties() { QQuickView view; - view.setSource(QUrl::fromLocalFile("data/basic.qml")); + view.setSource(testFileUrl("basic.qml")); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); diff --git a/tests/auto/quick/scenegraph/tst_scenegraph.cpp b/tests/auto/quick/scenegraph/tst_scenegraph.cpp index 80672e234e..b2093076e8 100644 --- a/tests/auto/quick/scenegraph/tst_scenegraph.cpp +++ b/tests/auto/quick/scenegraph/tst_scenegraph.cpp @@ -44,6 +44,7 @@ #include #include +#include "../../shared/util.h" class PerPixelRect : public QQuickItem { @@ -89,7 +90,7 @@ private: QColor m_color; }; -class tst_SceneGraph : public QObject +class tst_SceneGraph : public QQmlDataTest { Q_OBJECT @@ -109,6 +110,7 @@ private slots: private: bool m_brokenMipmapSupport; + QQuickView *createView(const QString &file, QWindow *parent = 0, int x = -1, int y = -1, int w = -1, int h = -1); }; template class ScopedList : public QList { @@ -120,6 +122,8 @@ void tst_SceneGraph::initTestCase() { qmlRegisterType("SceneGraphTest", 1, 0, "PerPixelRect"); + QQmlDataTest::initTestCase(); + QSGRenderLoop *loop = QSGRenderLoop::instance(); qDebug() << "RenderLoop: " << loop; @@ -157,26 +161,16 @@ void tst_SceneGraph::initTestCase() context.doneCurrent(); } -QQuickView *createView(const QString &file, QWindow *parent = 0, int x = -1, int y = -1, int w = -1, int h = -1) +QQuickView *tst_SceneGraph::createView(const QString &file, QWindow *parent, int x, int y, int w, int h) { QQuickView *view = new QQuickView(parent); - view->setSource(QUrl::fromLocalFile("data/" + file)); + view->setSource(testFileUrl(file)); if (x >= 0 && y >= 0) view->setPosition(x, y); if (w >= 0 && h >= 0) view->resize(w, h); view->show(); return view; } -QImage showAndGrab(const QString &file, int w, int h) -{ - QQuickView view; - view.setSource(QUrl::fromLocalFile(QStringLiteral("data/") + file)); - if (w >= 0 && h >= 0) - view.resize(w, h); - view.create(); - return view.grabWindow(); -} - // Assumes the images are opaque white... bool containsSomethingOtherThanWhite(const QImage &image) { @@ -410,17 +404,17 @@ void tst_SceneGraph::render_data() QTest::addColumn >("finalStage"); QList files; - files << "data/render_DrawSets.qml" - << "data/render_Overlap.qml" - << "data/render_MovingOverlap.qml" - << "data/render_BreakOpacityBatch.qml" - << "data/render_OutOfFloatRange.qml" - << "data/render_StackingOrder.qml" - << "data/render_ImageFiltering.qml" - << "data/render_bug37422.qml" - << "data/render_OpacityThroughBatchRoot.qml"; + files << "render_DrawSets.qml" + << "render_Overlap.qml" + << "render_MovingOverlap.qml" + << "render_BreakOpacityBatch.qml" + << "render_OutOfFloatRange.qml" + << "render_StackingOrder.qml" + << "render_ImageFiltering.qml" + << "render_bug37422.qml" + << "render_OpacityThroughBatchRoot.qml"; if (!m_brokenMipmapSupport) - files << "data/render_Mipmap.qml"; + files << "render_Mipmap.qml"; QRegExp sampleCount("#samples: *(\\d+)"); // X:int Y:int R:float G:float B:float Error:float @@ -428,7 +422,7 @@ void tst_SceneGraph::render_data() QRegExp finalSamples("#final: *(\\d+) *(\\d+) *(\\d\\.\\d+) *(\\d\\.\\d+) *(\\d\\.\\d+) *(\\d\\.\\d+)"); foreach (QString fileName, files) { - QFile file(fileName); + QFile file(testFile(fileName)); if (!file.open(QFile::ReadOnly)) { qFatal("render_data: QFile::open failed! file=%s, error=%s", qPrintable(fileName), qPrintable(file.errorString())); @@ -471,7 +465,7 @@ void tst_SceneGraph::render() QQuickView view; view.rootContext()->setContextProperty("suite", &suite); - view.setSource(QUrl::fromLocalFile(file)); + view.setSource(testFileUrl(file)); view.setResizeMode(QQuickView::SizeViewToRootObject); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); @@ -519,7 +513,7 @@ void tst_SceneGraph::hideWithOtherContext() { QQuickView view; - view.setSource(QUrl::fromLocalFile("data/simple.qml")); + view.setSource(testFileUrl("simple.qml")); view.setResizeMode(QQuickView::SizeViewToRootObject); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); From 580f86b8a0e43656805180bc36defb7cf1f76826 Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 1 Aug 2016 23:44:34 +0200 Subject: [PATCH 2/8] QQmlComponent: fix handling of relative paths Calling QUrl::fromLocalFile() on a relative path leads to a non-relative URL, as per the definition of QUrl::isRelative(). Change-Id: Ibaa9ecac56c6a14f6e41c5cf5250d7bbafed9837 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlcomponent.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 9d56ea50de..9ea38fe528 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -55,6 +55,7 @@ #include #include +#include #include #include #include @@ -543,7 +544,8 @@ QQmlComponent::QQmlComponent(QQmlEngine *engine, const QString &fileName, { Q_D(QQmlComponent); d->engine = engine; - d->loadUrl(d->engine->baseUrl().resolved(QUrl::fromLocalFile(fileName))); + const QUrl url = QDir::isAbsolutePath(fileName) ? QUrl::fromLocalFile(fileName) : d->engine->baseUrl().resolved(QUrl(fileName)); + d->loadUrl(url); } /*! @@ -559,7 +561,8 @@ QQmlComponent::QQmlComponent(QQmlEngine *engine, const QString &fileName, { Q_D(QQmlComponent); d->engine = engine; - d->loadUrl(d->engine->baseUrl().resolved(QUrl::fromLocalFile(fileName)), mode); + const QUrl url = QDir::isAbsolutePath(fileName) ? QUrl::fromLocalFile(fileName) : d->engine->baseUrl().resolved(QUrl(fileName)); + d->loadUrl(url, mode); } /*! From 97b2fc9d643538b55e9738322ea4239a3c9f7851 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 2 Aug 2016 17:00:47 +0200 Subject: [PATCH 3/8] Relax negativeYear EcmaScript test EcmaScript doesn't in fact require the date to be represented in english. Thus, only test for the year number to be contained in the date string. Change-Id: I5b89c14a833b317f259f4cd2855b3f24310a7d72 Reviewed-by: Simon Hausmann --- tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index aaa72d48cd..b3b31e1a73 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -7427,8 +7427,11 @@ void tst_qqmlecmascript::negativeYear() QVariant q; QMetaObject::invokeMethod(object, "check_negative_tostring", Q_RETURN_ARG(QVariant, q)); - // Strip the timezone. It should be irrelevant as the date was created with the same one. - QCOMPARE(q.toString().left(32), QStringLiteral("result: Sat Jan 1 00:00:00 -2001")); + + // Only check for the year. We hope that every language writes the year in arabic numerals and + // in relation to a specific dude's date of birth. We also hope that no language adds a "-2001" + // junk string somewhere in the middle. + QVERIFY(q.toString().indexOf(QStringLiteral("-2001")) != -1); QMetaObject::invokeMethod(object, "check_negative_toisostring", Q_RETURN_ARG(QVariant, q)); QCOMPARE(q.toString().left(16), QStringLiteral("result: -002000-")); From 6bcea421991de4c89f4c9bc02b01b370788719c7 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 2 Aug 2016 09:20:21 +0200 Subject: [PATCH 4/8] Fix grammar in JavaScript Host Environment doc Change-Id: Ib7bc3f62fc27e982f59f1c8b2c2e0cf26306c3b9 Reviewed-by: Mitch Curtis Reviewed-by: Friedemann Kleint --- src/qml/doc/src/javascript/hostenvironment.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qml/doc/src/javascript/hostenvironment.qdoc b/src/qml/doc/src/javascript/hostenvironment.qdoc index e613c4fcfb..de8b967d72 100644 --- a/src/qml/doc/src/javascript/hostenvironment.qdoc +++ b/src/qml/doc/src/javascript/hostenvironment.qdoc @@ -110,7 +110,7 @@ console.log("Result: " + a); \endcode Any attempt to modify the global object - either implicitly or explicitly - will -cause an exception. If uncaught, this will result in an warning being printed, +cause an exception. If uncaught, this will result in a warning being printed, that includes the file and line number of the offending code. \li Global code is run in a reduced scope. @@ -120,7 +120,7 @@ code, it is executed in a scope that contains only the external file itself and the global object. That is, it will not have access to the QML objects and properties it \l {Scope and Naming Resolution}{normally would}. -Global code that only accesses script local variable is permitted. This is an +Global code that only accesses script local variables is permitted. This is an example of valid global code. \code From f18e81a20d843b8f5b03a6d38a6e985227a42739 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 3 Aug 2016 12:44:18 +0200 Subject: [PATCH 5/8] photoviewer depends on xmlpatterns Change-Id: Ifc047a7492d0452c86777f1e6a5671421b7065d3 Reviewed-by: Simon Hausmann --- examples/quick/demos/demos.pro | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/quick/demos/demos.pro b/examples/quick/demos/demos.pro index e6937683ab..0644b81a22 100644 --- a/examples/quick/demos/demos.pro +++ b/examples/quick/demos/demos.pro @@ -5,8 +5,7 @@ SUBDIRS = samegame \ tweetsearch \ maroon \ photosurface \ - photoviewer \ stocqt -qtHaveModule(xmlpatterns): SUBDIRS += rssnews +qtHaveModule(xmlpatterns): SUBDIRS += rssnews photoviewer From 0a4cebe6d35abe1019c0d86cf933af972dc8bc6c Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 25 Jul 2016 09:25:11 +0200 Subject: [PATCH 6/8] Fix recursion during aggressive GC With aggressive GC enabled we may end up calling the GC recursively, which does not work at all, so disable that. Change-Id: I9ce0abbdb7b2bfa8499b33fd0be0d6e4a5212a15 Reviewed-by: Erik Verbruggen --- src/qml/memory/qv4mm.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index 885784d7d3..7ab6d15041 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -42,6 +42,7 @@ #include #include +#include #include #include @@ -542,6 +543,8 @@ void MemoryManager::runGC() return; } + QScopedValueRollback gcBlocker(m_d->gcBlocked, true); + if (!m_d->gcStats) { mark(); sweep(); From 5e60d281f1c84c76b80d001ddb3ac00c213de15f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 25 Jul 2016 12:26:54 +0200 Subject: [PATCH 7/8] Test that we don't crash when items are sorted and filtered at the same time This is a test for commit 49c892328223dfa2502b462d8e5e8e181f4f6cd5 in qtbase Change-Id: Id7be42ddd9136b73af08093117316fe2e86a000a Reviewed-by: Robin Burchell --- .../qquicklistview/tst_qquicklistview.cpp | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 08c0887fcf..a3b3a1d309 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -254,6 +254,7 @@ private slots: void QTBUG_50105(); void QTBUG_50097_stickyHeader_positionViewAtIndex(); + void itemFiltered(); private: template void items(const QUrl &source); @@ -8281,6 +8282,37 @@ void tst_QQuickListView::QTBUG_50097_stickyHeader_positionViewAtIndex() QTRY_COMPARE(listview->contentY(), -100.0); // back to the same position: header visible, items not under the header. } +void tst_QQuickListView::itemFiltered() +{ + QStringListModel model(QStringList() << "one" << "two" << "three" << "four" << "five" << "six"); + QSortFilterProxyModel proxy1; + proxy1.setSourceModel(&model); + proxy1.setSortRole(Qt::DisplayRole); + proxy1.setDynamicSortFilter(true); + proxy1.sort(0); + + QSortFilterProxyModel proxy2; + proxy2.setSourceModel(&proxy1); + proxy2.setFilterRole(Qt::DisplayRole); + proxy2.setFilterRegExp("^[^ ]*$"); + proxy2.setDynamicSortFilter(true); + + QScopedPointer window(createView()); + window->engine()->rootContext()->setContextProperty("_model", &proxy2); + QQmlComponent component(window->engine()); + component.setData("import QtQuick 2.4; ListView { " + "anchors.fill: parent; model: _model; delegate: Text { width: parent.width;" + "text: model.display; } }", + QUrl()); + window->setContent(QUrl(), &component, component.create()); + + window->show(); + QTest::qWaitForWindowExposed(window.data()); + + // this should not crash + model.setData(model.index(2), QStringLiteral("modified three"), Qt::DisplayRole); +} + QTEST_MAIN(tst_QQuickListView) #include "tst_qquicklistview.moc" From ffe113ab628adf6c22e96a22cf0bcda8e80c290d Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 4 Aug 2016 10:04:57 +0200 Subject: [PATCH 8/8] V4 Debugger: use engineAdded() instead of engineAboutToBeAdded() It does not make a difference in functionality, but after engineAdded() the server won't wait on a mutex anymore. Before this change, if you managed to send a message to the V4 debugger after the server had called aboutToBeAdded(), but before it had stopped waiting, you could produce a deadlock by scheduling an event for the GUI thread that was never delivered. This is a cherry-pick of 18c4295e25503ae637a715858de5c94a3d105a92 from 5.7 as apparently the problem also occurs in 5.6. Change-Id: Ie2343e6da4bd0b8956d41ff8ebd4d7594616ebd1 Reviewed-by: Simon Hausmann --- src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp | 4 ++-- src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp index e9bcd772e5..7a9d4a66a4 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp @@ -611,7 +611,7 @@ QV4DebugServiceImpl::~QV4DebugServiceImpl() qDeleteAll(handlers); } -void QV4DebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine) +void QV4DebugServiceImpl::engineAdded(QQmlEngine *engine) { QMutexLocker lock(&m_configMutex); if (engine) { @@ -628,7 +628,7 @@ void QV4DebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine) } } } - QQmlConfigurableDebugService::engineAboutToBeAdded(engine); + QQmlConfigurableDebugService::engineAdded(engine); } void QV4DebugServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine) diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h index 658b1b3998..fafe7d90bf 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h @@ -70,7 +70,7 @@ public: explicit QV4DebugServiceImpl(QObject *parent = 0); ~QV4DebugServiceImpl(); - void engineAboutToBeAdded(QQmlEngine *engine); + void engineAdded(QQmlEngine *engine); void engineAboutToBeRemoved(QQmlEngine *engine); void stateAboutToBeChanged(State state);