diff options
Diffstat (limited to 'tests/auto/quick')
39 files changed, 1358 insertions, 103 deletions
diff --git a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp index 54eb3509bd..7d50e130f2 100644 --- a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp +++ b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp @@ -131,6 +131,8 @@ void tst_QQuickAccessible::initTestCase() QQmlDataTest::initTestCase(); QTestAccessibility::initialize(); QPlatformIntegration *pfIntegration = QGuiApplicationPrivate::platformIntegration(); + if (!pfIntegration->accessibility()) + QSKIP("This platform does not support accessibility"); pfIntegration->accessibility()->setActive(true); } diff --git a/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml b/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml index e299147b36..70682bed0b 100644 --- a/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml +++ b/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml @@ -16,7 +16,6 @@ TestCase { if (type === "2d") return [ { tag:"image threaded", properties:{width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Threaded}}, - { tag:"image canvas invisible", properties:{visible: false, width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Threaded}}, // { tag:"image cooperative", properties:{width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Cooperative}}, { tag:"image immediate", properties:{width:100, height:100, renderTarget:Canvas.Image, renderStrategy:Canvas.Immediate}}, // { tag:"fbo cooperative", properties:{width:100, height:100, renderTarget:Canvas.FramebufferObject, renderStrategy:Canvas.Cooperative}}, diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml index b92f6354a5..d90eb3971e 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml @@ -180,20 +180,28 @@ CanvasTestCase { tryCompare(c, "availableChangedCount", 1); //scene graph could be available immediately //in this case, we force waiting a short while until the init paint finished - if (c.visible) { - tryCompare(c, "paintedCount", 1); - } else { - tryCompare(c, "paintedCount", 0); - } + tryCompare(c, "paintedCount", 1); ctx.fillRect(0, 0, c.width, c.height); c.toDataURL(); - if (c.visible) { - tryCompare(c, "paintCount", 1); - tryCompare(c, "paintedCount", 2); - } else { - tryCompare(c, "paintCount", 0); - tryCompare(c, "paintedCount", 1); - } + tryCompare(c, "paintedCount", 2); + tryCompare(c, "paintCount", 1); + // implicit repaint when visible and resized + testCase.visible = true; + c.width += 1; + c.height += 1; + tryCompare(c, "paintCount", 2); + tryCompare(c, "paintedCount", 2); + // allow explicit repaint even when hidden + testCase.visible = false; + c.requestPaint(); + tryCompare(c, "paintCount", 3); + tryCompare(c, "paintedCount", 2); + // no implicit repaint when resized but hidden + c.width += 1; + c.height += 1; + waitForRendering(c); + compare(c.paintCount, 3); + tryCompare(c, "paintedCount", 2); c.destroy(); } function test_loadImage(row) { diff --git a/tests/auto/quick/qquickgridview/data/boundZValues.qml b/tests/auto/quick/qquickgridview/data/boundZValues.qml new file mode 100644 index 0000000000..7a1ca48a81 --- /dev/null +++ b/tests/auto/quick/qquickgridview/data/boundZValues.qml @@ -0,0 +1,46 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + + GridView { + id: grid + + property real itemZ: 342 + property real headerZ: 341 + property real footerZ: 340 + property real highlightZ: 339 + + anchors.fill: parent + objectName: "grid" + model: ListModel { ListElement { text: "text" } } + currentIndex: 0 + + delegate: Text { + objectName: "wrapper" + font.pointSize: 20 + text: index + z: grid.itemZ + } + + header: Rectangle { + width: 240 + height: 30 + z: grid.headerZ + } + + footer: Rectangle { + width: 240 + height: 30 + z: grid.footerZ + } + + highlight: Rectangle { + width: 240 + height: 30 + z: grid.highlightZ + } + } +} + diff --git a/tests/auto/quick/qquickgridview/data/constantZValues.qml b/tests/auto/quick/qquickgridview/data/constantZValues.qml new file mode 100644 index 0000000000..7cf564a12e --- /dev/null +++ b/tests/auto/quick/qquickgridview/data/constantZValues.qml @@ -0,0 +1,46 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + + GridView { + id: grid + + property real itemZ: 241 + property real headerZ: 242 + property real footerZ: 243 + property real highlightZ: 244 + + anchors.fill: parent + objectName: "grid" + model: ListModel { ListElement { text: "text" } } + currentIndex: 0 + + delegate: Text { + objectName: "wrapper" + font.pointSize: 20 + text: index + z: 241 + } + + header: Rectangle { + width: 240 + height: 30 + z: 242 + } + + footer: Rectangle { + width: 240 + height: 30 + z: 243 + } + + highlight: Rectangle { + width: 240 + height: 30 + z: 244 + } + } +} + diff --git a/tests/auto/quick/qquickgridview/data/initialZValues.qml b/tests/auto/quick/qquickgridview/data/defaultZValues.qml index 9768b2c695..53f11bb2da 100644 --- a/tests/auto/quick/qquickgridview/data/initialZValues.qml +++ b/tests/auto/quick/qquickgridview/data/defaultZValues.qml @@ -7,11 +7,15 @@ Rectangle { GridView { id: grid - property real initialZ: 342 + property real itemZ: 1 + property real headerZ: 1 + property real footerZ: 1 + property real highlightZ: 0 anchors.fill: parent objectName: "grid" - model: ListModel {} + model: ListModel { ListElement { text: "text" } } + currentIndex: 0 delegate: Text { objectName: "wrapper" @@ -22,13 +26,11 @@ Rectangle { header: Rectangle { width: 240 height: 30 - z: grid.initialZ } footer: Rectangle { width: 240 height: 30 - z: grid.initialZ } } } diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp index f4eec18690..890174e2a8 100644 --- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp +++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp @@ -121,6 +121,7 @@ private slots: void footer(); void footer_data(); void initialZValues(); + void initialZValues_data(); void header(); void header_data(); void extents(); @@ -3200,8 +3201,9 @@ void tst_QQuickGridView::footer_data() void tst_QQuickGridView::initialZValues() { + QFETCH(QString, fileName); QQuickView *window = createView(); - window->setSource(testFileUrl("initialZValues.qml")); + window->setSource(testFileUrl(fileName)); qApp->processEvents(); QQuickGridView *gridview = findItem<QQuickGridView>(window->rootObject(), "grid"); @@ -3209,15 +3211,29 @@ void tst_QQuickGridView::initialZValues() QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != 0); + QVERIFY(gridview->currentItem()); + QTRY_COMPARE(gridview->currentItem()->z(), gridview->property("itemZ").toReal()); + QVERIFY(gridview->headerItem()); - QTRY_COMPARE(gridview->headerItem()->z(), gridview->property("initialZ").toReal()); + QTRY_COMPARE(gridview->headerItem()->z(), gridview->property("headerZ").toReal()); QVERIFY(gridview->footerItem()); - QTRY_COMPARE(gridview->footerItem()->z(), gridview->property("initialZ").toReal()); + QTRY_COMPARE(gridview->footerItem()->z(), gridview->property("footerZ").toReal()); + + QVERIFY(gridview->highlightItem()); + QTRY_COMPARE(gridview->highlightItem()->z(), gridview->property("highlightZ").toReal()); delete window; } +void tst_QQuickGridView::initialZValues_data() +{ + QTest::addColumn<QString>("fileName"); + QTest::newRow("defaults") << "defaultZValues.qml"; + QTest::newRow("constants") << "constantZValues.qml"; + QTest::newRow("bindings") << "boundZValues.qml"; +} + void tst_QQuickGridView::header() { QFETCH(QQuickGridView::Flow, flow); diff --git a/tests/auto/quick/qquickimage/data/heart-highdpi@2x.png b/tests/auto/quick/qquickimage/data/heart-highdpi@2x.png Binary files differnew file mode 100644 index 0000000000..abe97fee4b --- /dev/null +++ b/tests/auto/quick/qquickimage/data/heart-highdpi@2x.png diff --git a/tests/auto/quick/qquickimage/tst_qquickimage.cpp b/tests/auto/quick/qquickimage/tst_qquickimage.cpp index b73dcdfcde..7951cb07cf 100644 --- a/tests/auto/quick/qquickimage/tst_qquickimage.cpp +++ b/tests/auto/quick/qquickimage/tst_qquickimage.cpp @@ -105,6 +105,7 @@ private slots: void progressAndStatusChanges(); void sourceSizeChanges(); void correctStatus(); + void highdpi(); private: QQmlEngine engine; @@ -307,6 +308,10 @@ void tst_qquickimage::mirror() qreal height = 250; foreach (QQuickImage::FillMode fillMode, fillModes) { +#if defined(Q_OS_BLACKBERRY) + QWindow dummy; // On BlackBerry first window is always full screen, + dummy.showFullScreen(); // so make test window a second window. +#endif QQuickView *window = new QQuickView; window->setSource(testFileUrl("mirror.qml")); @@ -315,7 +320,7 @@ void tst_qquickimage::mirror() obj->setFillMode(fillMode); obj->setProperty("mirror", true); - window->show(); + window->showNormal(); QVERIFY(QTest::qWaitForWindowExposed(window)); QImage screenshot = window->grabWindow(); @@ -928,6 +933,49 @@ void tst_qquickimage::correctStatus() delete obj; } +void tst_qquickimage::highdpi() +{ + TestHTTPServer server; + QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString())); + server.serveDirectory(dataDirectory()); + + QString componentStr = "import QtQuick 2.0\nImage { source: srcImage ; }"; + QQmlComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQmlContext *ctxt = engine.rootContext(); + + // Testing "@2x" high-dpi image loading: + // The basic case is as follows. Suppose you have foo.png, + // which is a 64x64 png that fits in a QML layout. Now, + // on a high-dpi system that pixmap would not provide + // enough pixels. To fix this the app developer provides + // a 128x128 foo@2x.png, which Qt automatically loads. + // The image continues to be referred to as "foo.png" in + // the QML sources, and reports a size of 64x64. + // + + // Load "heart-highdpi@2x.png", which is a 300x300 png. As a 2x scale image it + // should render and report a geometry of 150x150. + ctxt->setContextProperty("srcImage", testFileUrl("heart-highdpi@2x.png")); + + QQuickImage *obj = qobject_cast<QQuickImage*>(component.create()); + QVERIFY(obj != 0); + + QCOMPARE(obj->width(), 150.0); + QCOMPARE(obj->height(), 150.0); + QCOMPARE(obj->paintedWidth(), 150.0); + QCOMPARE(obj->paintedHeight(), 150.0); + + // Load a normal 1x image. + ctxt->setContextProperty("srcImage", testFileUrl("heart.png")); + QCOMPARE(obj->width(), 300.0); + QCOMPARE(obj->height(), 300.0); + QCOMPARE(obj->paintedWidth(), 300.0); + QCOMPARE(obj->paintedHeight(), 300.0); + + delete obj; +} + QTEST_MAIN(tst_qquickimage) #include "tst_qquickimage.moc" diff --git a/tests/auto/quick/qquickitem/data/visualParentOwnershipWindow.qml b/tests/auto/quick/qquickitem/data/visualParentOwnershipWindow.qml new file mode 100644 index 0000000000..30fc844d7a --- /dev/null +++ b/tests/auto/quick/qquickitem/data/visualParentOwnershipWindow.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 +import QtQuick.Window 2.1 + +Window { + Component { + id: factory + Item {} + } + + property Item keepAliveProperty; + + function createItemWithoutParent() { + return factory.createObject(/*parent*/ null); + } +} diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index 8db515432a..40327b0666 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -170,6 +170,7 @@ private slots: void acceptedMouseButtons(); void visualParentOwnership(); + void visualParentOwnershipWindow(); private: @@ -1189,8 +1190,9 @@ static inline QByteArray msgItem(const QQuickItem *item) void tst_qquickitem::mouseGrab() { -#if defined(Q_OS_WIN) && defined(QT_OPENGL_ES_2) - QSKIP("Fails in the CI for ANGLE builds on Windows, QTBUG-32664"); +#ifdef Q_OS_WIN + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) + QSKIP("Fails in the CI for ANGLE builds on Windows, QTBUG-32664"); #endif QQuickWindow window; window.setFramePosition(QPoint(100, 100)); @@ -1824,6 +1826,63 @@ void tst_qquickitem::visualParentOwnership() } } +void tst_qquickitem::visualParentOwnershipWindow() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("visualParentOwnershipWindow.qml")); + + QQuickWindow *window = qobject_cast<QQuickWindow*>(component.create()); + QVERIFY(window); + QQuickItem *root = window->contentItem(); + + QVariant newObject; + { + QVERIFY(QMetaObject::invokeMethod(window, "createItemWithoutParent", Q_RETURN_ARG(QVariant, newObject))); + QPointer<QQuickItem> newItem = qvariant_cast<QQuickItem*>(newObject); + QVERIFY(!newItem.isNull()); + + QVERIFY(!newItem->parent()); + QVERIFY(!newItem->parentItem()); + + newItem->setParentItem(root); + + gc(engine); + + QVERIFY(!newItem.isNull()); + newItem->setParentItem(0); + + gc(engine); + QVERIFY(newItem.isNull()); + } + { + QVERIFY(QMetaObject::invokeMethod(window, "createItemWithoutParent", Q_RETURN_ARG(QVariant, newObject))); + QPointer<QQuickItem> firstItem = qvariant_cast<QQuickItem*>(newObject); + QVERIFY(!firstItem.isNull()); + + firstItem->setParentItem(root); + + QVERIFY(QMetaObject::invokeMethod(window, "createItemWithoutParent", Q_RETURN_ARG(QVariant, newObject))); + QPointer<QQuickItem> secondItem = qvariant_cast<QQuickItem*>(newObject); + QVERIFY(!firstItem.isNull()); + + secondItem->setParentItem(firstItem); + + gc(engine); + + delete firstItem; + + window->setProperty("keepAliveProperty", newObject); + + gc(engine); + QVERIFY(!secondItem.isNull()); + + window->setProperty("keepAliveProperty", QVariant()); + + gc(engine); + QVERIFY(secondItem.isNull()); + } +} + QTEST_MAIN(tst_qquickitem) #include "tst_qquickitem.moc" diff --git a/tests/auto/quick/qquickitem2/data/activeFocusOnTab9.qml b/tests/auto/quick/qquickitem2/data/activeFocusOnTab9.qml new file mode 100644 index 0000000000..09bb73639a --- /dev/null +++ b/tests/auto/quick/qquickitem2/data/activeFocusOnTab9.qml @@ -0,0 +1,50 @@ +import QtQuick 2.1 + +Item { + id: main + objectName: "main" + width: 300 + height: 300 + TextInput { + id: textinput1 + objectName: "textinput1" + width: 300 + height: 75 + activeFocusOnTab: true + text: "Text Input 1" + anchors.top: parent.top + anchors.left: parent.left + } + TextInput { + id: textinput2 + objectName: "textinput2" + width: 300 + height: 75 + activeFocusOnTab: true + text: "Text Input 2" + readOnly: true + anchors.top: textinput1.bottom + anchors.left: parent.left + } + TextEdit { + id: textedit1 + objectName: "textedit1" + width: 300 + height: 75 + activeFocusOnTab: true + text: "Text Edit 1" + anchors.top: textinput2.bottom + anchors.left: parent.left + } + TextEdit { + id: textedit2 + objectName: "textedit2" + width: 300 + height: 75 + activeFocusOnTab: true + text: "Text Edit 2" + readOnly: true + anchors.top: textedit1.bottom + anchors.left: parent.left + } +} diff --git a/tests/auto/quick/qquickitem2/data/keysforward.qml b/tests/auto/quick/qquickitem2/data/keysforward.qml new file mode 100644 index 0000000000..f0cb4d9508 --- /dev/null +++ b/tests/auto/quick/qquickitem2/data/keysforward.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: root + + property alias source: source + property alias primaryTarget: primaryTarget + property alias secondaryTarget: secondaryTarget + + property var pressedKeys: [] + property var releasedKeys: [] + Keys.onPressed: { var keys = pressedKeys; keys.push(event.key); pressedKeys = keys } + Keys.onReleased: { var keys = releasedKeys; keys.push(event.key); releasedKeys = keys } + + Item { + id: primaryTarget + objectName: "primary" + property var pressedKeys: [] + property var releasedKeys: [] + Keys.forwardTo: secondaryTarget + Keys.onPressed: { event.accepted = event.key === Qt.Key_P; var keys = pressedKeys; keys.push(event.key); pressedKeys = keys } + Keys.onReleased: { event.accepted = event.key === Qt.Key_P; var keys = releasedKeys; keys.push(event.key); releasedKeys = keys } + + Item { + id: source + objectName: "source" + property var pressedKeys: [] + property var releasedKeys: [] + Keys.forwardTo: primaryTarget + Keys.onPressed: { var keys = pressedKeys; keys.push(event.key); pressedKeys = keys } + Keys.onReleased: { var keys = releasedKeys; keys.push(event.key); releasedKeys = keys } + } + } + + Item { + id: secondaryTarget + objectName: "secondary" + property var pressedKeys: [] + property var releasedKeys: [] + Keys.onPressed: { event.accepted = event.key === Qt.Key_S; var keys = pressedKeys; keys.push(event.key); pressedKeys = keys } + Keys.onReleased: { event.accepted = event.key === Qt.Key_S; var keys = releasedKeys; keys.push(event.key); releasedKeys = keys } + } +} diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index 10f4aa2c83..9d2188253a 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -73,6 +73,8 @@ private slots: void activeFocusOnTab6(); void activeFocusOnTab7(); void activeFocusOnTab8(); + void activeFocusOnTab9(); + void activeFocusOnTab10(); void nextItemInFocusChain(); void nextItemInFocusChain2(); @@ -83,6 +85,7 @@ private slots: void standardKeys(); void keysProcessingOrder(); void keysim(); + void keysForward(); void keyNavigation_data(); void keyNavigation(); void keyNavigation_RightToLeft(); @@ -856,6 +859,140 @@ void tst_QQuickItem::activeFocusOnTab8() delete window; } +void tst_QQuickItem::activeFocusOnTab9() +{ + if (qt_tab_all_widgets()) + QSKIP("This function doesn't support iterating all."); + + QQuickView *window = new QQuickView(0); + window->setBaseSize(QSize(300,300)); + + window->setSource(testFileUrl("activeFocusOnTab9.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + + QQuickItem *content = window->contentItem(); + QVERIFY(content); + QVERIFY(content->hasActiveFocus()); + + QQuickItem *textinput1 = findItem<QQuickItem>(window->rootObject(), "textinput1"); + QVERIFY(textinput1); + QQuickItem *textedit1 = findItem<QQuickItem>(window->rootObject(), "textedit1"); + QVERIFY(textedit1); + + QVERIFY(!textinput1->hasActiveFocus()); + textinput1->forceActiveFocus(); + QVERIFY(textinput1->hasActiveFocus()); + + // Tab: textinput1->textedit1 + QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textedit1->hasActiveFocus()); + + // BackTab: textedit1->textinput1 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textinput1->hasActiveFocus()); + + // BackTab: textinput1->textedit1 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textedit1->hasActiveFocus()); + + delete window; +} + +void tst_QQuickItem::activeFocusOnTab10() +{ + if (!qt_tab_all_widgets()) + QSKIP("This function doesn't support NOT iterating all."); + + QQuickView *window = new QQuickView(0); + window->setBaseSize(QSize(300,300)); + + window->setSource(testFileUrl("activeFocusOnTab9.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + + QQuickItem *content = window->contentItem(); + QVERIFY(content); + QVERIFY(content->hasActiveFocus()); + + QQuickItem *textinput1 = findItem<QQuickItem>(window->rootObject(), "textinput1"); + QVERIFY(textinput1); + QQuickItem *textedit1 = findItem<QQuickItem>(window->rootObject(), "textedit1"); + QVERIFY(textedit1); + QQuickItem *textinput2 = findItem<QQuickItem>(window->rootObject(), "textinput2"); + QVERIFY(textinput2); + QQuickItem *textedit2 = findItem<QQuickItem>(window->rootObject(), "textedit2"); + QVERIFY(textedit2); + + QVERIFY(!textinput1->hasActiveFocus()); + textinput1->forceActiveFocus(); + QVERIFY(textinput1->hasActiveFocus()); + + // Tab: textinput1->textinput2 + QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textinput2->hasActiveFocus()); + + // Tab: textinput2->textedit1 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textedit1->hasActiveFocus()); + + // BackTab: textedit1->textinput2 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textinput2->hasActiveFocus()); + + // BackTab: textinput2->textinput1 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textinput1->hasActiveFocus()); + + // BackTab: textinput1->textedit2 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textedit2->hasActiveFocus()); + + // BackTab: textedit2->textedit1 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textedit1->hasActiveFocus()); + + // BackTab: textedit1->textinput2 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + QVERIFY(textinput2->hasActiveFocus()); + + delete window; +} + void tst_QQuickItem::nextItemInFocusChain() { if (!qt_tab_all_widgets()) @@ -1268,6 +1405,78 @@ void tst_QQuickItem::keysim() delete window; } +void tst_QQuickItem::keysForward() +{ + QQuickView window; + window.setBaseSize(QSize(240,320)); + + window.setSource(testFileUrl("keysforward.qml")); + window.show(); + window.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&window)); + QVERIFY(QGuiApplication::focusWindow() == &window); + + QQuickItem *rootItem = qobject_cast<QQuickItem *>(window.rootObject()); + QVERIFY(rootItem); + QQuickItem *sourceItem = rootItem->property("source").value<QQuickItem *>(); + QVERIFY(sourceItem); + QQuickItem *primaryTarget = rootItem->property("primaryTarget").value<QQuickItem *>(); + QVERIFY(primaryTarget); + QQuickItem *secondaryTarget = rootItem->property("secondaryTarget").value<QQuickItem *>(); + QVERIFY(secondaryTarget); + + // primary target accepts/consumes Key_P + QKeyEvent pressKeyP(QEvent::KeyPress, Qt::Key_P, Qt::NoModifier, "P"); + QCoreApplication::sendEvent(sourceItem, &pressKeyP); + QCOMPARE(rootItem->property("pressedKeys").toList(), QVariantList()); + QCOMPARE(sourceItem->property("pressedKeys").toList(), QVariantList()); + QCOMPARE(primaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P); + QCOMPARE(secondaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P); + QVERIFY(pressKeyP.isAccepted()); + + QKeyEvent releaseKeyP(QEvent::KeyRelease, Qt::Key_P, Qt::NoModifier, "P"); + QCoreApplication::sendEvent(sourceItem, &releaseKeyP); + QCOMPARE(rootItem->property("releasedKeys").toList(), QVariantList()); + QCOMPARE(sourceItem->property("releasedKeys").toList(), QVariantList()); + QCOMPARE(primaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P); + QCOMPARE(secondaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P); + QVERIFY(releaseKeyP.isAccepted()); + + // secondary target accepts/consumes Key_S + QKeyEvent pressKeyS(QEvent::KeyPress, Qt::Key_S, Qt::NoModifier, "S"); + QCoreApplication::sendEvent(sourceItem, &pressKeyS); + QCOMPARE(rootItem->property("pressedKeys").toList(), QVariantList()); + QCOMPARE(sourceItem->property("pressedKeys").toList(), QVariantList()); + QCOMPARE(primaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P); + QCOMPARE(secondaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_S); + QVERIFY(pressKeyS.isAccepted()); + + QKeyEvent releaseKeyS(QEvent::KeyRelease, Qt::Key_S, Qt::NoModifier, "S"); + QCoreApplication::sendEvent(sourceItem, &releaseKeyS); + QCOMPARE(rootItem->property("releasedKeys").toList(), QVariantList()); + QCOMPARE(sourceItem->property("releasedKeys").toList(), QVariantList()); + QCOMPARE(primaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P); + QCOMPARE(secondaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_S); + QVERIFY(releaseKeyS.isAccepted()); + + // neither target accepts/consumes Key_Q + QKeyEvent pressKeyQ(QEvent::KeyPress, Qt::Key_Q, Qt::NoModifier, "Q"); + QCoreApplication::sendEvent(sourceItem, &pressKeyQ); + QCOMPARE(rootItem->property("pressedKeys").toList(), QVariantList()); + QCOMPARE(sourceItem->property("pressedKeys").toList(), QVariantList() << Qt::Key_Q); + QCOMPARE(primaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_Q); + QCOMPARE(secondaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_S << Qt::Key_Q); + QVERIFY(!pressKeyQ.isAccepted()); + + QKeyEvent releaseKeyQ(QEvent::KeyRelease, Qt::Key_Q, Qt::NoModifier, "Q"); + QCoreApplication::sendEvent(sourceItem, &releaseKeyQ); + QCOMPARE(rootItem->property("releasedKeys").toList(), QVariantList()); + QCOMPARE(sourceItem->property("releasedKeys").toList(), QVariantList() << Qt::Key_Q); + QCOMPARE(primaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_Q); + QCOMPARE(secondaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_S << Qt::Key_Q); + QVERIFY(!releaseKeyQ.isAccepted()); +} + QQuickItemPrivate *childPrivate(QQuickItem *rootItem, const char * itemString) { QQuickItem *item = findItem<QQuickItem>(rootItem, QString(QLatin1String(itemString))); diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp index 4f103bd1fa..b5980929a6 100644 --- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp +++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp @@ -55,10 +55,14 @@ public: QImage runTest(const QString &fileName) { +#if defined(Q_OS_BLACKBERRY) + QWindow dummy; // On BlackBerry first window is always full screen, + dummy.showFullScreen(); // so make test window a second window. +#endif QQuickView view; view.setSource(testFileUrl(fileName)); - view.show(); + view.showNormal(); QTest::qWaitForWindowExposed(&view); return view.grabWindow(); diff --git a/tests/auto/quick/qquicklistview/data/boundZValues.qml b/tests/auto/quick/qquicklistview/data/boundZValues.qml new file mode 100644 index 0000000000..10810e540d --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/boundZValues.qml @@ -0,0 +1,55 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + + ListView { + id: list + + property real itemZ: 342 + property real headerZ: 341 + property real footerZ: 340 + property real highlightZ: 339 + property real sectionZ: 338 + + anchors.fill: parent + objectName: "list" + model: ListModel { ListElement { text: "text" } } + currentIndex: 0 + + delegate: Text { + objectName: "wrapper" + font.pointSize: 20 + text: index + z: list.itemZ + } + + header: Rectangle { + width: 240 + height: 30 + z: list.headerZ + } + + footer: Rectangle { + width: 240 + height: 30 + z: list.footerZ + } + + highlight: Rectangle { + width: 240 + height: 30 + z: list.highlightZ + } + + section.property: "text" + section.delegate: Text { + objectName: "section" + font.pointSize: 20 + text: section + z: list.sectionZ + } + } +} + diff --git a/tests/auto/quick/qquicklistview/data/constantZValues.qml b/tests/auto/quick/qquicklistview/data/constantZValues.qml new file mode 100644 index 0000000000..48917fed4f --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/constantZValues.qml @@ -0,0 +1,55 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + + ListView { + id: list + + property real itemZ: 241 + property real headerZ: 242 + property real footerZ: 243 + property real highlightZ: 244 + property real sectionZ: 245 + + anchors.fill: parent + objectName: "list" + model: ListModel { ListElement { text: "text" } } + currentIndex: 0 + + delegate: Text { + objectName: "wrapper" + font.pointSize: 20 + text: index + z: 241 + } + + header: Rectangle { + width: 240 + height: 30 + z: 242 + } + + footer: Rectangle { + width: 240 + height: 30 + z: 243 + } + + highlight: Rectangle { + width: 240 + height: 30 + z: 244 + } + + section.property: "text" + section.delegate: Text { + objectName: "section" + font.pointSize: 20 + text: section + z: 245 + } + } +} + diff --git a/tests/auto/quick/qquicklistview/data/defaultZValues.qml b/tests/auto/quick/qquicklistview/data/defaultZValues.qml new file mode 100644 index 0000000000..7326340ae4 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/defaultZValues.qml @@ -0,0 +1,49 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + + ListView { + id: list + + property real itemZ: 1 + property real headerZ: 1 + property real footerZ: 1 + property real highlightZ: 0 + property real sectionZ: 2 + + anchors.fill: parent + objectName: "list" + model: ListModel { ListElement { text: "text" } } + currentIndex: 0 + + delegate: Text { + objectName: "wrapper" + font.pointSize: 20 + text: index + } + + header: Rectangle { + width: 240 + height: 30 + } + + footer: Rectangle { + width: 240 + height: 30 + } + + highlight: Rectangle { + width: 240 + height: 30 + } + + section.property: "text" + section.delegate: Text { + objectName: "section" + font.pointSize: 20 + text: section + } + } +} diff --git a/tests/auto/quick/qquicklistview/data/initialZValues.qml b/tests/auto/quick/qquicklistview/data/initialZValues.qml deleted file mode 100644 index 3a8e78debb..0000000000 --- a/tests/auto/quick/qquicklistview/data/initialZValues.qml +++ /dev/null @@ -1,35 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 240 - height: 320 - - ListView { - id: list - - property real initialZ: 342 - - anchors.fill: parent - objectName: "list" - model: ListModel {} - - delegate: Text { - objectName: "wrapper" - font.pointSize: 20 - text: index - } - - header: Rectangle { - width: 240 - height: 30 - z: list.initialZ - } - - footer: Rectangle { - width: 240 - height: 30 - z: list.initialZ - } - } -} - diff --git a/tests/auto/quick/qquicklistview/data/outsideViewportChangeNotAffectingView.qml b/tests/auto/quick/qquicklistview/data/outsideViewportChangeNotAffectingView.qml index 7903c392d1..c57cde5eda 100644 --- a/tests/auto/quick/qquicklistview/data/outsideViewportChangeNotAffectingView.qml +++ b/tests/auto/quick/qquicklistview/data/outsideViewportChangeNotAffectingView.qml @@ -42,13 +42,16 @@ import QtQuick 2.1 import QtTest 1.0 Item { + width: 300 + height: 542 + function resizeThirdItem(size) { resizingListModel.setProperty(3, "size", size) } ListView { - width: 300 - height: 542 + id: list + anchors.fill: parent model: ListModel { id: resizingListModel ListElement { size: 300; } @@ -62,6 +65,9 @@ Item { width: parent.width color: index % 2 == 0 ? "red" : "blue" height: size + Text { anchors.centerIn: parent; text: index } } } + + Text { text: list.contentY; color: "white" } } diff --git a/tests/auto/quick/qquicklistview/data/roundingErrors.qml b/tests/auto/quick/qquicklistview/data/roundingErrors.qml new file mode 100644 index 0000000000..aebdce04c3 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/roundingErrors.qml @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.0 +import QtQml.Models 2.1 + +ListView { + id: listview + + width: 600 + height: 200 + + spacing: 8 + orientation: ListView.Horizontal + + Component.onCompleted: { + var colors = ["blue", "green", "red", "yellow", "orange", "purple", "cyan", + "magenta", "chartreuse", "aquamarine", "indigo", "lightsteelblue", + "violet", "grey", "springgreen", "salmon", "blanchedalmond", + "forestgreen", "pink", "navy", "goldenrod", "crimson", "teal" ] + for (var i = 0; i < 100; ++i) + colorModel.append( { nid: i, color: colors[i%colors.length] } ) + } + + model: DelegateModel { + id: visualModel + + model: ListModel { + id: colorModel + } + + delegate: MouseArea { + id: delegateRoot + objectName: model.nid + + width: 107.35 + height: 63.35 + + drag.target: icon + + Rectangle{ + id: icon + width: delegateRoot.width + height: delegateRoot.height + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + color: model.color + + Drag.active: delegateRoot.drag.active + Drag.source: delegateRoot + Drag.hotSpot.x: 36 + Drag.hotSpot.y: 36 + + Text { + id: text + anchors.fill: parent + font.pointSize: 40 + text: model.nid + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + } + + states: [ + State { + when: icon.Drag.active + ParentChange { + target: icon + parent: delegateRoot.ListView.view + } + + AnchorChanges { + target: icon + anchors.horizontalCenter: undefined + anchors.verticalCenter: undefined + } + } + ] + } + } + } + + DropArea { + anchors.fill: parent + onPositionChanged: { + var to = listview.indexAt(drag.x + listview.contentX, 0) + if (to !== -1) { + var from = drag.source.DelegateModel.itemsIndex + if (from !== to) + visualModel.items.move(from, to) + drag.accept() + } + } + } +} diff --git a/tests/auto/quick/qquicklistview/qquicklistview.pro b/tests/auto/quick/qquicklistview/qquicklistview.pro index 4ac47679da..2ae04d32fe 100644 --- a/tests/auto/quick/qquicklistview/qquicklistview.pro +++ b/tests/auto/quick/qquicklistview/qquicklistview.pro @@ -17,4 +17,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 -mac:CONFIG += insignificant_test # QTBUG-27740 diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index efd0fa8103..29755e3890 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -147,6 +147,7 @@ private slots: void modelChanges(); void manualHighlight(); void initialZValues(); + void initialZValues_data(); void header(); void header_data(); void header_delayItemCreation(); @@ -223,6 +224,9 @@ private slots: void QTBUG_36481(); void QTBUG_35920(); + void roundingErrors(); + void roundingErrors_data(); + private: template <class T> void items(const QUrl &source); template <class T> void changed(const QUrl &source); @@ -3346,9 +3350,9 @@ void tst_QQuickListView::modelChanges() void tst_QQuickListView::QTBUG_9791() { QQuickView *window = createView(); - window->setSource(testFileUrl("strictlyenforcerange.qml")); - qApp->processEvents(); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); QQuickListView *listview = qobject_cast<QQuickListView*>(window->rootObject()); QTRY_VERIFY(listview != 0); @@ -3465,8 +3469,9 @@ void tst_QQuickListView::QTBUG_11105() void tst_QQuickListView::initialZValues() { + QFETCH(QString, fileName); QQuickView *window = createView(); - window->setSource(testFileUrl("initialZValues.qml")); + window->setSource(testFileUrl(fileName)); qApp->processEvents(); QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); @@ -3474,15 +3479,33 @@ void tst_QQuickListView::initialZValues() QQuickItem *contentItem = listview->contentItem(); QTRY_VERIFY(contentItem != 0); + QVERIFY(listview->currentItem()); + QTRY_COMPARE(listview->currentItem()->z(), listview->property("itemZ").toReal()); + QVERIFY(listview->headerItem()); - QTRY_COMPARE(listview->headerItem()->z(), listview->property("initialZ").toReal()); + QTRY_COMPARE(listview->headerItem()->z(), listview->property("headerZ").toReal()); QVERIFY(listview->footerItem()); - QTRY_COMPARE(listview->footerItem()->z(), listview->property("initialZ").toReal()); + QTRY_COMPARE(listview->footerItem()->z(), listview->property("footerZ").toReal()); + + QVERIFY(listview->highlightItem()); + QTRY_COMPARE(listview->highlightItem()->z(), listview->property("highlightZ").toReal()); + + QQuickText *sectionItem = 0; + QTRY_VERIFY(sectionItem = findItem<QQuickText>(contentItem, "section")); + QTRY_COMPARE(sectionItem->z(), listview->property("sectionZ").toReal()); delete window; } +void tst_QQuickListView::initialZValues_data() +{ + QTest::addColumn<QString>("fileName"); + QTest::newRow("defaults") << "defaultZValues.qml"; + QTest::newRow("constants") << "constantZValues.qml"; + QTest::newRow("bindings") << "boundZValues.qml"; +} + void tst_QQuickListView::header() { QFETCH(QQuickListView::Orientation, orientation); @@ -7027,9 +7050,7 @@ void tst_QQuickListView::outsideViewportChangeNotAffectingView() window->show(); QVERIFY(QTest::qWaitForWindowExposed(window)); - flick(window, QPoint(20, 200), QPoint(20, 20), 10); - - QTRY_COMPARE(listview->isFlicking(), false); + listview->setContentY(1250); QTRY_COMPARE(listview->indexAt(0, listview->contentY()), 4); QTRY_COMPARE(listview->itemAt(0, listview->contentY())->y(), 1200.); @@ -7127,12 +7148,12 @@ void tst_QQuickListView::displayMargin() void tst_QQuickListView::highlightItemGeometryChanges() { - QQmlEngine engine; - QQmlComponent component(&engine, testFileUrl("HighlightResize.qml")); - - QScopedPointer<QObject> object(component.create()); + QScopedPointer<QQuickView> window(createView()); + window->setSource(testFileUrl("HighlightResize.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); - QQuickListView *listview = qobject_cast<QQuickListView *>(object.data()); + QQuickListView *listview = qobject_cast<QQuickListView *>(window->rootObject()); QVERIFY(listview); QCOMPARE(listview->count(), 5); @@ -7183,6 +7204,63 @@ void tst_QQuickListView::QTBUG_35920() QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(10,100)); } +void tst_QQuickListView::roundingErrors() +{ + QFETCH(bool, pixelAligned); + + QScopedPointer<QQuickView> window(createView()); + window->setSource(testFileUrl("roundingErrors.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickListView *listview = qobject_cast<QQuickListView *>(window->rootObject()); + QVERIFY(listview); + listview->setPixelAligned(pixelAligned); + listview->positionViewAtIndex(20, QQuickListView::Beginning); + + QQuickItem *content = listview->contentItem(); + QVERIFY(content); + + const QPoint viewPos(150, 36); + const QPointF contentPos = content->mapFromItem(listview, viewPos); + + QPointer<QQuickItem> item = listview->itemAt(contentPos.x(), contentPos.y()); + QVERIFY(item); + + // QTBUG-37339: drag an item and verify that it doesn't + // get prematurely released due to rounding errors + QTest::mousePress(window.data(), Qt::LeftButton, 0, viewPos); + for (int i = 0; i < 150; i += 5) { + QTest::mouseMove(window.data(), viewPos - QPoint(i, 0)); + QVERIFY(item); + } + QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(0, 36)); + + // maintain position relative to the right edge + listview->setLayoutDirection(Qt::RightToLeft); + const qreal contentX = listview->contentX(); + listview->setContentX(contentX + 0.2); + QCOMPARE(listview->contentX(), pixelAligned ? qRound(contentX + 0.2) : contentX + 0.2); + listview->setWidth(listview->width() - 0.2); + QCOMPARE(listview->contentX(), pixelAligned ? qRound(contentX + 0.2) : contentX + 0.2); + + // maintain position relative to the bottom edge + listview->setOrientation(QQuickListView::Vertical); + listview->setVerticalLayoutDirection(QQuickListView::BottomToTop); + const qreal contentY = listview->contentY(); + listview->setContentY(contentY + 0.2); + QCOMPARE(listview->contentY(), pixelAligned ? qRound(contentY + 0.2) : contentY + 0.2); + listview->setHeight(listview->height() - 0.2); + QCOMPARE(listview->contentY(), pixelAligned ? qRound(contentY + 0.2) : contentY + 0.2); +} + +void tst_QQuickListView::roundingErrors_data() +{ + QTest::addColumn<bool>("pixelAligned"); + QTest::newRow("pixelAligned=true") << true; + QTest::newRow("pixelAligned=false") << false; +} + QTEST_MAIN(tst_QQuickListView) #include "tst_qquicklistview.moc" diff --git a/tests/auto/quick/qquicksmoothedanimation/tst_qquicksmoothedanimation.cpp b/tests/auto/quick/qquicksmoothedanimation/tst_qquicksmoothedanimation.cpp index 650ce09dfa..7642583bb1 100644 --- a/tests/auto/quick/qquicksmoothedanimation/tst_qquicksmoothedanimation.cpp +++ b/tests/auto/quick/qquicksmoothedanimation/tst_qquicksmoothedanimation.cpp @@ -61,6 +61,7 @@ private slots: void behavior(); void deleteOnUpdate(); void zeroDuration(); + void noStart(); private: QQmlEngine engine; @@ -263,6 +264,27 @@ void tst_qquicksmoothedanimation::zeroDuration() delete rect; } +//verify that an empty SmoothedAnimation does not fire up the animation system +//and keep it running forever +void tst_qquicksmoothedanimation::noStart() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("smoothedanimation1.qml")); + QQuickSmoothedAnimation *obj = qobject_cast<QQuickSmoothedAnimation*>(c.create()); + + QVERIFY(obj != 0); + + obj->start(); + QCOMPARE(obj->isRunning(), false); + QTest::qWait(100); + QCOMPARE(obj->isRunning(), false); + //this could fail if the test is being run in parallel with other tests + //or if an earlier test failed and didn't clean up (left an animation running) + //QCOMPARE(QUnifiedTimer::instance()->runningAnimationCount(), 0); + + delete obj; +} + QTEST_MAIN(tst_qquicksmoothedanimation) #include "tst_qquicksmoothedanimation.moc" diff --git a/tests/auto/quick/qquickstates/data/QTBUG-38492.qml b/tests/auto/quick/qquickstates/data/QTBUG-38492.qml new file mode 100644 index 0000000000..d6d6d81fd3 --- /dev/null +++ b/tests/auto/quick/qquickstates/data/QTBUG-38492.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 + +Item { + id: root + property string text; + + states: [ + State { + name: 'apply' + PropertyChanges { + target: root + text: qsTr("Test") + } + } + ] +} diff --git a/tests/auto/quick/qquickstates/tst_qquickstates.cpp b/tests/auto/quick/qquickstates/tst_qquickstates.cpp index 0c9b75636f..6b46ab1fae 100644 --- a/tests/auto/quick/qquickstates/tst_qquickstates.cpp +++ b/tests/auto/quick/qquickstates/tst_qquickstates.cpp @@ -148,6 +148,7 @@ private slots: void QTBUG_14830(); void avoidFastForward(); void revertListBug(); + void QTBUG_38492(); }; void tst_qquickstates::initTestCase() @@ -1626,6 +1627,21 @@ void tst_qquickstates::revertListBug() QCOMPARE(rect2->parentItem(), origParent2); //QTBUG-22583 causes rect2's parent item to be origParent1 } +void tst_qquickstates::QTBUG_38492() +{ + QQmlEngine engine; + + QQmlComponent rectComponent(&engine, testFileUrl("QTBUG-38492.qml")); + QQuickItem *item = qobject_cast<QQuickItem*>(rectComponent.create()); + QVERIFY(item != 0); + + QQuickItemPrivate::get(item)->setState("apply"); + + QCOMPARE(item->property("text").toString(), QString("Test")); + + delete item; +} + QTEST_MAIN(tst_qquickstates) #include "tst_qquickstates.moc" diff --git a/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp b/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp index a2e05ba883..be46f362d6 100644 --- a/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp +++ b/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp @@ -126,26 +126,26 @@ void tst_qquickstyledtext::textOutput_data() QTest::newRow("paragraph closed") << "text<p>more text</p>more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList() << false; QTest::newRow("paragraph closed bold") << "<b>text<p>more text</p>more text</b>" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << (FormatList() << Format(Format::Bold, 0, 24)) << false; QTest::newRow("unknown tag") << "<a href='#'><foo>underline</foo></a> not" << "underline not" << (FormatList() << Format(Format::Underline, 0, 9)) << false; - QTest::newRow("ordered list") << "<ol><li>one<li>two" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("1.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("2.") + QString(2, QChar::Nbsp) + QLatin1String("two") << FormatList() << false; - QTest::newRow("ordered list closed") << "<ol><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("1.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("2.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; - QTest::newRow("ordered list alpha") << "<ol type=\"a\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("a.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("b.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; - QTest::newRow("ordered list upper alpha") << "<ol type=\"A\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("A.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("B.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; - QTest::newRow("ordered list roman") << "<ol type=\"i\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("i.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("ii.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; - QTest::newRow("ordered list upper roman") << "<ol type=\"I\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("I.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("II.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; - QTest::newRow("ordered list bad") << "<ol type=\"z\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("1.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("2.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; - QTest::newRow("unordered list") << "<ul><li>one<li>two" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("two") << FormatList() << false; - QTest::newRow("unordered list closed") << "<ul><li>one</li><li>two</li></ul>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; - QTest::newRow("unordered list disc") << "<ul type=\"disc\"><li>one</li><li>two</li></ul>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + disc + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + disc + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; - QTest::newRow("unordered list square") << "<ul type=\"square\"><li>one</li><li>two</li></ul>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + square + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + square + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; - QTest::newRow("unordered list bad") << "<ul type=\"bad\"><li>one</li><li>two</li></ul>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; - QTest::newRow("header close") << "<h1>head</h1>more" << QChar(QChar::LineSeparator) + QLatin1String("head") + QChar(QChar::LineSeparator) + QLatin1String("more") << (FormatList() << Format(Format::Bold, 0, 5)) << true; + QTest::newRow("ordered list") << "<ol><li>one<li>two" << QString(6, QChar::Nbsp) + QLatin1String("1.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("2.") + QString(2, QChar::Nbsp) + QLatin1String("two") << FormatList() << false; + QTest::newRow("ordered list closed") << "<ol><li>one</li><li>two</li></ol>" << QString(6, QChar::Nbsp) + QLatin1String("1.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("2.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("ordered list alpha") << "<ol type=\"a\"><li>one</li><li>two</li></ol>" << QString(6, QChar::Nbsp) + QLatin1String("a.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("b.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("ordered list upper alpha") << "<ol type=\"A\"><li>one</li><li>two</li></ol>" << QString(6, QChar::Nbsp) + QLatin1String("A.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("B.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("ordered list roman") << "<ol type=\"i\"><li>one</li><li>two</li></ol>" << QString(6, QChar::Nbsp) + QLatin1String("i.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("ii.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("ordered list upper roman") << "<ol type=\"I\"><li>one</li><li>two</li></ol>" << QString(6, QChar::Nbsp) + QLatin1String("I.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("II.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("ordered list bad") << "<ol type=\"z\"><li>one</li><li>two</li></ol>" << QString(6, QChar::Nbsp) + QLatin1String("1.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("2.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("unordered list") << "<ul><li>one<li>two" << QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("two") << FormatList() << false; + QTest::newRow("unordered list closed") << "<ul><li>one</li><li>two</li></ul>" << QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("unordered list disc") << "<ul type=\"disc\"><li>one</li><li>two</li></ul>" << QString(6, QChar::Nbsp) + disc + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + disc + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("unordered list square") << "<ul type=\"square\"><li>one</li><li>two</li></ul>" << QString(6, QChar::Nbsp) + square + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + square + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("unordered list bad") << "<ul type=\"bad\"><li>one</li><li>two</li></ul>" << QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("header close") << "<h1>head</h1>more" << QLatin1String("head") + QChar(QChar::LineSeparator) + QLatin1String("more") << (FormatList() << Format(Format::Bold, 0, 4)) << true; QTest::newRow("h0") << "<h0>head" << "head" << FormatList() << false; - QTest::newRow("h1") << "<h1>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)) << true; - QTest::newRow("h2") << "<h2>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)) << true; - QTest::newRow("h3") << "<h3>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)) << true; - QTest::newRow("h4") << "<h4>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)) << true; - QTest::newRow("h5") << "<h5>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)) << true; - QTest::newRow("h6") << "<h6>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)) << true; + QTest::newRow("h1") << "<h1>head" << "head" << (FormatList() << Format(Format::Bold, 0, 4)) << true; + QTest::newRow("h2") << "<h2>head" << "head" << (FormatList() << Format(Format::Bold, 0, 4)) << true; + QTest::newRow("h3") << "<h3>head" << "head" << (FormatList() << Format(Format::Bold, 0, 4)) << true; + QTest::newRow("h4") << "<h4>head" << "head" << (FormatList() << Format(Format::Bold, 0, 4)) << true; + QTest::newRow("h5") << "<h5>head" << "head" << (FormatList() << Format(Format::Bold, 0, 4)) << true; + QTest::newRow("h6") << "<h6>head" << "head" << (FormatList() << Format(Format::Bold, 0, 4)) << true; QTest::newRow("h7") << "<h7>head" << "head" << FormatList() << false; QTest::newRow("pre") << "normal<pre>pre text</pre>normal" << QLatin1String("normal") + QChar(QChar::LineSeparator) + QLatin1String("pre") + QChar(QChar::Nbsp) + QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("normal") << (FormatList() << Format(0, 6, 9)) << false; QTest::newRow("pre lb") << "normal<pre>pre\n text</pre>normal" << QLatin1String("normal") + QChar(QChar::LineSeparator) + QLatin1String("pre") + QChar(QChar::LineSeparator) + QChar(QChar::Nbsp) + QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("normal") << (FormatList() << Format(0, 6, 10)) << false; @@ -155,7 +155,7 @@ void tst_qquickstyledtext::textOutput_data() QTest::newRow("consecutive whitespace") << " consecutive \t \n whitespace" << "consecutive whitespace" << FormatList() << false; QTest::newRow("space after newline") << "text<br/> more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList() << false; QTest::newRow("space after paragraph") << "text<p> more text</p> more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList() << false; - QTest::newRow("space in header") << "<h1> head</h1> " << QChar(QChar::LineSeparator) + QLatin1String("head") + QChar(QChar::LineSeparator) << (FormatList() << Format(Format::Bold, 0, 5)) << true; + QTest::newRow("space in header") << "<h1> head</h1> " << QLatin1String("head") + QChar(QChar::LineSeparator) << (FormatList() << Format(Format::Bold, 0, 4)) << true; QTest::newRow("space before bold") << "this is <b>bold</b>" << "this is bold" << (FormatList() << Format(Format::Bold, 8, 4)) << false; QTest::newRow("space leading bold") << "this is<b> bold</b>" << "this is bold" << (FormatList() << Format(Format::Bold, 7, 5)) << false; QTest::newRow("space trailing bold") << "this is <b>bold </b>" << "this is bold " << (FormatList() << Format(Format::Bold, 8, 5)) << false; diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp index 3bf872569f..88b9c2d792 100644 --- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp @@ -1296,7 +1296,7 @@ void tst_qquicktextedit::selectionOnFocusOut() QVERIFY(edit2->hasActiveFocus()); edit2->setFocus(false, Qt::PopupFocusReason); - QVERIFY(!edit2->hasActiveFocus()); + QVERIFY(edit2->hasActiveFocus()); QCOMPARE(edit2->selectedText(), QLatin1String("text 2")); } diff --git a/tests/auto/quick/qquicktextinput/qquicktextinput.pro b/tests/auto/quick/qquicktextinput/qquicktextinput.pro index c14b09c545..521f41df43 100644 --- a/tests/auto/quick/qquicktextinput/qquicktextinput.pro +++ b/tests/auto/quick/qquicktextinput/qquicktextinput.pro @@ -14,3 +14,5 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +macx: CONFIG+=insignificant_test # QTBUG-38363 diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index 05cf0b9a5b..684229aa07 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -3606,7 +3606,8 @@ void tst_qquicktextinput::focusOutNotClearSelection() input.setFocus(false, Qt::PopupFocusReason); QGuiApplication::processEvents(); QTRY_COMPARE(input.selectedText(), QLatin1String("llo")); - QTRY_COMPARE(input.hasActiveFocus(), false); + // QTBUG-36332 and 36292: a popup window does not take focus + QTRY_COMPARE(input.hasActiveFocus(), true); input.setFocus(true); QTRY_COMPARE(input.hasActiveFocus(), true); diff --git a/tests/auto/quick/qquicktimeline/tst_qquicktimeline.cpp b/tests/auto/quick/qquicktimeline/tst_qquicktimeline.cpp index e9fbb5448c..9b62eb311c 100644 --- a/tests/auto/quick/qquicktimeline/tst_qquicktimeline.cpp +++ b/tests/auto/quick/qquicktimeline/tst_qquicktimeline.cpp @@ -53,6 +53,12 @@ private slots: void tst_QQuickTimeLine::overflow() { + // Test ensures that time value used in QQuickTimeLine::accel methods is always positive. + // On platforms where casting qreal value infinity to int yields a positive value this is + // always the case and the test would fail. Strictly speaking, the cast is undefined behavior. + if (static_cast<int>(qInf()) > 0) + QSKIP("Test is not applicable on this platform"); + QQuickTimeLine timeline; QQuickTimeLineValue value; diff --git a/tests/auto/quick/qquickwindow/data/active.qml b/tests/auto/quick/qquickwindow/data/active.qml index af0b7edeb2..4d47225b4e 100644 --- a/tests/auto/quick/qquickwindow/data/active.qml +++ b/tests/auto/quick/qquickwindow/data/active.qml @@ -14,7 +14,6 @@ Window { anchors.fill: parent; onPressed: window2.requestActivate(); } - Component.onCompleted: window2.show(); } Window { @@ -22,6 +21,7 @@ Window { objectName: "window2"; color: "#FF0000"; width: 100; height: 100; + visible: true Item { width: 100; height: 100; } diff --git a/tests/auto/quick/qquickwindow/data/windoworder.qml b/tests/auto/quick/qquickwindow/data/windoworder.qml new file mode 100644 index 0000000000..33aea95694 --- /dev/null +++ b/tests/auto/quick/qquickwindow/data/windoworder.qml @@ -0,0 +1,42 @@ +import QtQuick 2.1 +import QtQuick.Window 2.1 + +Window { + id: window1; + objectName: "window1"; + width: 100; height: 100; + visible: true + color: "blue" + property alias win2: window2 + property alias win3: window3 + property alias win4: window4 + property alias win5: window5 + Window { + id: window2; + objectName: "window2"; + width: 100; height: 100; + visible: true + color: "green" + Window { + id: window3; + objectName: "window3"; + width: 100; height: 100; + visible: true + } + + Window { //Is invisible by default + id: window4 + objectName: "window4"; + height: 200 + width: 200 + color: "black" + Window { + id: window5 + objectName: "window5"; + height: 200 + width: 200 + visible: true + } + } + } +} diff --git a/tests/auto/quick/qquickwindow/qquickwindow.pro b/tests/auto/quick/qquickwindow/qquickwindow.pro index 2d1d62c135..e95b7dbb10 100644 --- a/tests/auto/quick/qquickwindow/qquickwindow.pro +++ b/tests/auto/quick/qquickwindow/qquickwindow.pro @@ -15,6 +15,7 @@ OTHER_FILES += \ data/active.qml \ data/AnimationsWhileHidden.qml \ data/Headless.qml \ - data/showHideAnimate.qml + data/showHideAnimate.qml \ + data/windoworder.qml DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index de4067b6e5..a2e2980223 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -343,6 +343,8 @@ private slots: void requestActivate(); + void testWindowVisibilityOrder(); + void blockClosing(); void crashWhenHoverItemDeleted(); @@ -1132,6 +1134,43 @@ void tst_qquickwindow::animationsWhileHidden() QTRY_VERIFY(window->isVisible()); } +// When running on native Nvidia graphics cards on linux, the +// distance field glyph pixels have a measurable, but not visible +// pixel error. Use a custom compare function to avoid +// +// This was GT-216 with the ubuntu "nvidia-319" driver package. +// llvmpipe does not show the same issue. +// +bool compareImages(const QImage &ia, const QImage &ib) +{ + if (ia.size() != ib.size()) + qDebug() << "images are of different size" << ia.size() << ib.size(); + Q_ASSERT(ia.size() == ib.size()); + Q_ASSERT(ia.format() == ib.format()); + + int w = ia.width(); + int h = ia.height(); + const int tolerance = 5; + for (int y=0; y<h; ++y) { + const uint *as= (const uint *) ia.constScanLine(y); + const uint *bs= (const uint *) ib.constScanLine(y); + for (int x=0; x<w; ++x) { + uint a = as[x]; + uint b = bs[x]; + + // No tolerance for error in the alpha. + if ((a & 0xff000000) != (b & 0xff000000)) + return false; + if (qAbs(qRed(a) - qRed(b)) > tolerance) + return false; + if (qAbs(qRed(a) - qRed(b)) > tolerance) + return false; + if (qAbs(qRed(a) - qRed(b)) > tolerance) + return false; + } + } + return true; +} void tst_qquickwindow::headless() { @@ -1179,8 +1218,7 @@ void tst_qquickwindow::headless() // Verify that the visual output is the same QImage newContent = window->grabWindow(); - - QCOMPARE(originalContent, newContent); + QVERIFY(compareImages(newContent, originalContent)); } void tst_qquickwindow::noUpdateWhenNothingChanges() @@ -1600,7 +1638,8 @@ void tst_qquickwindow::requestActivate() QVERIFY(windows.at(0)->objectName() == "window2"); window1->show(); - window1->requestActivate(); + QVERIFY(QTest::qWaitForWindowExposed(windows.at(0))); //We wait till window 2 comes up + window1->requestActivate(); // and then transfer the focus to window1 QTRY_VERIFY(QGuiApplication::focusWindow() == window1); QVERIFY(window1->isActive() == true); @@ -1626,6 +1665,54 @@ void tst_qquickwindow::requestActivate() QTRY_VERIFY(QGuiApplication::focusWindow() == windows.at(0)); QVERIFY(windows.at(0)->isActive()); + delete window1; +} + +void tst_qquickwindow::testWindowVisibilityOrder() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("windoworder.qml")); + QQuickWindow *window1 = qobject_cast<QQuickWindow *>(component.create()); + QQuickWindow *window2 = window1->property("win2").value<QQuickWindow*>(); + QQuickWindow *window3 = window1->property("win3").value<QQuickWindow*>(); + QQuickWindow *window4 = window1->property("win4").value<QQuickWindow*>(); + QQuickWindow *window5 = window1->property("win5").value<QQuickWindow*>(); + QVERIFY(window1); + QVERIFY(window2); + QVERIFY(window3); + + QTest::qWaitForWindowExposed(window3); + + QWindowList windows = QGuiApplication::topLevelWindows(); + QTRY_COMPARE(windows.size(), 5); + + QVERIFY(window3 == QGuiApplication::focusWindow()); + QVERIFY(window1->isActive()); + QVERIFY(window2->isActive()); + QVERIFY(window3->isActive()); + + //Test if window4 is shown 2 seconds after the application startup + //with window4 visible window5 (transient child) should also become visible + QVERIFY(!window4->isVisible()); + QVERIFY(!window5->isVisible()); + + window4->setVisible(true); + + QTest::qWaitForWindowExposed(window5); + QVERIFY(window4->isVisible()); + QVERIFY(window5->isVisible()); + window4->hide(); + window5->hide(); + + window3->hide(); +#if defined(Q_OS_OSX) + QEXPECT_FAIL("","Focus is not transferred to transient parent on window close (QTBUG-33423)", Continue); +#endif + QTRY_COMPARE(window2 == QGuiApplication::focusWindow(), true); + + window2->hide(); + QTRY_COMPARE(window1 == QGuiApplication::focusWindow(), true); } void tst_qquickwindow::blockClosing() diff --git a/tests/auto/quick/qquickxmllistmodel/data/proxyCrash.qml b/tests/auto/quick/qquickxmllistmodel/data/proxyCrash.qml new file mode 100644 index 0000000000..c0c5a25e3c --- /dev/null +++ b/tests/auto/quick/qquickxmllistmodel/data/proxyCrash.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 +import QtQuick.XmlListModel 2.0 +import SortFilterProxyModel 1.0 + +SortFilterProxyModel { + source: XmlListModel { + XmlRole { } + } +} diff --git a/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp b/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp index a3cfa0011a..1d5518047f 100644 --- a/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp +++ b/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp @@ -51,6 +51,7 @@ #include <QtCore/qtimer.h> #include <QtCore/qfile.h> #include <QtCore/qtemporaryfile.h> +#include <QtCore/qsortfilterproxymodel.h> #include "../../shared/util.h" #include <private/qqmlengine_p.h> @@ -106,6 +107,7 @@ private slots: void selectAncestor(); void roleCrash(); + void proxyCrash(); private: QString errorString(QAbstractItemModel *model) { @@ -988,6 +990,28 @@ void tst_qquickxmllistmodel::roleCrash() delete model; } +class SortFilterProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT + Q_PROPERTY(QObject *source READ source WRITE setSource) + +public: + SortFilterProxyModel(QObject *parent = 0) : QSortFilterProxyModel(parent) { sort(0); } + QObject *source() const { return sourceModel(); } + void setSource(QObject *source) { setSourceModel(qobject_cast<QAbstractItemModel *>(source)); } +}; + +void tst_qquickxmllistmodel::proxyCrash() +{ + qmlRegisterType<SortFilterProxyModel>("SortFilterProxyModel", 1, 0, "SortFilterProxyModel"); + + // don't crash + QQmlComponent component(&engine, testFileUrl("proxyCrash.qml")); + QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create()); + QVERIFY(model != 0); + delete model; +} + QTEST_MAIN(tst_qquickxmllistmodel) #include "tst_qquickxmllistmodel.moc" diff --git a/tests/auto/quick/scenegraph/data/render_bug37422.qml b/tests/auto/quick/scenegraph/data/render_bug37422.qml new file mode 100644 index 0000000000..38e2b64da7 --- /dev/null +++ b/tests/auto/quick/scenegraph/data/render_bug37422.qml @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 + +/* + The test verifies that batching does not interfere with overlapping + regions. + + #samples: 8 + PixelPos R G B Error-tolerance + #base: 0 0 1.0 0.0 0.0 0.05 + #base: 1 1 0.0 0.0 1.0 0.05 + #base: 10 10 1.0 0.0 0.0 0.05 + #base: 1 11 0.0 0.0 1.0 0.05 + + #final: 0 0 1.0 0.0 0.0 0.05 + #final: 1 1 0.0 1.0 0.0 0.05 + #final: 10 10 1.0 0.0 0.0 0.05 + #final: 1 11 0.0 1.0 0.0 0.05 + +*/ + +RenderTestBase +{ + id: root + + opacity: 0.99 + + Rectangle { + width: 100 + height: 9 + color: Qt.rgba(1, 0, 0); + + Rectangle { + id: box + width: 5 + height: 5 + x: 1 + y: 1 + color: Qt.rgba(0, 0, 1); + } + } + + ShaderEffect { // Something which blends and is different than rectangle. Will get its own batch + width: 100 + height: 9 + y: 10 + fragmentShader: "varying highp vec2 qt_TexCoord0; void main() { gl_FragColor = vec4(1, 0, 0, 1); }" + + Rectangle { + width: 5 + height: 5 + x: 1 + y: 1 + color: box.color + } + } + + onEnterFinalStage: { + box.color = Qt.rgba(0, 1, 0); + root.finalStageComplete = true; + } + +} diff --git a/tests/auto/quick/scenegraph/tst_scenegraph.cpp b/tests/auto/quick/scenegraph/tst_scenegraph.cpp index 5d393fedb5..ac4938e8bc 100644 --- a/tests/auto/quick/scenegraph/tst_scenegraph.cpp +++ b/tests/auto/quick/scenegraph/tst_scenegraph.cpp @@ -119,7 +119,7 @@ bool compareImages(const QImage &ia, const QImage &ib) int w = ia.width(); int h = ia.height(); - const int tolerance = 1; + const int tolerance = 5; for (int y=0; y<h; ++y) { const uint *as= (const uint *) ia.constScanLine(y); const uint *bs= (const uint *) ib.constScanLine(y); @@ -328,6 +328,7 @@ void tst_SceneGraph::render_data() << "data/render_StackingOrder.qml" << "data/render_Mipmap.qml" << "data/render_ImageFiltering.qml" + << "data/render_bug37555.qml" ; QRegExp sampleCount("#samples: *(\\d+)"); |