diff options
Diffstat (limited to 'tests/auto')
325 files changed, 11083 insertions, 2329 deletions
diff --git a/tests/auto/bic/data/QtQuick.5.0.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQuick.5.0.0.linux-gcc-amd64.txt index 6c8ed16153..01f76a894f 100644 --- a/tests/auto/bic/data/QtQuick.5.0.0.linux-gcc-amd64.txt +++ b/tests/auto/bic/data/QtQuick.5.0.0.linux-gcc-amd64.txt @@ -7542,10 +7542,6 @@ Class QJSValueIterator base size=8 base align=8 QJSValueIterator (0x0x7f49b0d69420) 0 -Class DesignerSupport - size=8 align=8 - base size=8 base align=8 -DesignerSupport (0x0x7f49b0d69540) 0 Class QQuickTransform::QPrivateSignal size=1 align=1 diff --git a/tests/auto/bic/data/QtQuick.5.1.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQuick.5.1.0.linux-gcc-amd64.txt index 4f970788e3..18ee25dccb 100644 --- a/tests/auto/bic/data/QtQuick.5.1.0.linux-gcc-amd64.txt +++ b/tests/auto/bic/data/QtQuick.5.1.0.linux-gcc-amd64.txt @@ -7864,10 +7864,6 @@ Class QJSValueIterator base size=8 base align=8 QJSValueIterator (0x0x7fd8c4ff79c0) 0 -Class DesignerSupport - size=8 align=8 - base size=8 base align=8 -DesignerSupport (0x0x7fd8c4ff7ae0) 0 Class QQuickTransform::QPrivateSignal size=1 align=1 diff --git a/tests/auto/bic/data/QtQuick.5.2.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQuick.5.2.0.linux-gcc-amd64.txt index c652ca32d6..aa46b9ca87 100644 --- a/tests/auto/bic/data/QtQuick.5.2.0.linux-gcc-amd64.txt +++ b/tests/auto/bic/data/QtQuick.5.2.0.linux-gcc-amd64.txt @@ -8216,10 +8216,6 @@ QQmlPropertyMap (0x0x7f6f5eb9a4e0) 0 QObject (0x0x7f6f5e8cb060) 0 primary-for QQmlPropertyMap (0x0x7f6f5eb9a4e0) -Class DesignerSupport - size=8 align=8 - base size=8 base align=8 -DesignerSupport (0x0x7f6f5e8cb120) 0 Class QQuickTransform::QPrivateSignal size=1 align=1 diff --git a/tests/auto/bic/data/QtQuick.5.3.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQuick.5.3.0.linux-gcc-amd64.txt index c268efa08c..080e8b9041 100644 --- a/tests/auto/bic/data/QtQuick.5.3.0.linux-gcc-amd64.txt +++ b/tests/auto/bic/data/QtQuick.5.3.0.linux-gcc-amd64.txt @@ -8247,11 +8247,6 @@ QQmlPropertyMap (0x0x7fc57b23ed68) 0 QObject (0x0x7fc57b1146c0) 0 primary-for QQmlPropertyMap (0x0x7fc57b23ed68) -Class DesignerSupport - size=8 align=8 - base size=8 base align=8 -DesignerSupport (0x0x7fc57b114780) 0 - Class QQuickTransform::QPrivateSignal size=1 align=1 base size=0 base align=1 diff --git a/tests/auto/bic/data/QtQuick.5.4.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQuick.5.4.0.linux-gcc-amd64.txt index e689193076..de684fa2f8 100644 --- a/tests/auto/bic/data/QtQuick.5.4.0.linux-gcc-amd64.txt +++ b/tests/auto/bic/data/QtQuick.5.4.0.linux-gcc-amd64.txt @@ -8549,11 +8549,6 @@ QQmlPropertyMap (0x0x7faeca8d9e38) 0 QObject (0x0x7faeca7bb780) 0 primary-for QQmlPropertyMap (0x0x7faeca8d9e38) -Class DesignerSupport - size=8 align=8 - base size=8 base align=8 -DesignerSupport (0x0x7faeca7bb840) 0 - Class QQuickTransform::QPrivateSignal size=1 align=1 base size=0 base align=1 diff --git a/tests/auto/bic/data/QtQuickWidgets.5.3.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQuickWidgets.5.3.0.linux-gcc-amd64.txt index 1b55d5e268..48409f49b7 100644 --- a/tests/auto/bic/data/QtQuickWidgets.5.3.0.linux-gcc-amd64.txt +++ b/tests/auto/bic/data/QtQuickWidgets.5.3.0.linux-gcc-amd64.txt @@ -8247,10 +8247,6 @@ QQmlPropertyMap (0x0x7f249928bd68) 0 QObject (0x0x7f2498d5f720) 0 primary-for QQmlPropertyMap (0x0x7f249928bd68) -Class DesignerSupport - size=8 align=8 - base size=8 base align=8 -DesignerSupport (0x0x7f2498d5f7e0) 0 Class QQuickTransform::QPrivateSignal size=1 align=1 diff --git a/tests/auto/bic/data/QtQuickWidgets.5.4.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQuickWidgets.5.4.0.linux-gcc-amd64.txt index 93e620995e..57b4485857 100644 --- a/tests/auto/bic/data/QtQuickWidgets.5.4.0.linux-gcc-amd64.txt +++ b/tests/auto/bic/data/QtQuickWidgets.5.4.0.linux-gcc-amd64.txt @@ -8549,11 +8549,6 @@ QQmlPropertyMap (0x0x7f4037b54e38) 0 QObject (0x0x7f40376357e0) 0 primary-for QQmlPropertyMap (0x0x7f4037b54e38) -Class DesignerSupport - size=8 align=8 - base size=8 base align=8 -DesignerSupport (0x0x7f40376358a0) 0 - Class QQuickTransform::QPrivateSignal size=1 align=1 base size=0 base align=1 diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index f62d2f3bdb..4b9fbe75ac 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -13,3 +13,5 @@ test_module_includes( Qml QQmlEngine Quick QQuickWindow ) + +expect_pass(test_plugins) diff --git a/tests/auto/cmake/test_plugins/CMakeLists.txt b/tests/auto/cmake/test_plugins/CMakeLists.txt new file mode 100644 index 0000000000..a23f9c332c --- /dev/null +++ b/tests/auto/cmake/test_plugins/CMakeLists.txt @@ -0,0 +1,16 @@ +project(test_plugins) + +cmake_minimum_required(VERSION 2.8) +if (POLICY CMP0056) + cmake_policy(SET CMP0056 NEW) +endif() + +find_package(Qt5Qml REQUIRED) + +# See QTBUG-43438 +if (NOT TARGET Qt5::QTcpServerConnectionFactory) + message(SEND_ERROR "Qt5::QTcpServerConnectionFactory does not exist") +endif() +if (NOT TARGET Qt5::QLocalClientConnectionFactory) + message(SEND_ERROR "Qt5::QLocalClientConnectionFactory does not exist") +endif() diff --git a/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp b/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp index 325702f9c4..8132f3e24b 100644 --- a/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp +++ b/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp @@ -68,7 +68,7 @@ void tst_qquickpointattractor::test_basic() QVERIFY(d->x != 0.f); QVERIFY(d->y != 0.f); - QVERIFY(d->x == d->y); + QCOMPARE(d->x, d->y); QCOMPARE(d->vx, 0.f); QCOMPARE(d->vy, 0.f); QCOMPARE(d->ax, 0.f); diff --git a/tests/auto/qml/animation/qpauseanimationjob/tst_qpauseanimationjob.cpp b/tests/auto/qml/animation/qpauseanimationjob/tst_qpauseanimationjob.cpp index 21384ef3d8..92065d35e3 100644 --- a/tests/auto/qml/animation/qpauseanimationjob/tst_qpauseanimationjob.cpp +++ b/tests/auto/qml/animation/qpauseanimationjob/tst_qpauseanimationjob.cpp @@ -120,10 +120,10 @@ void tst_QPauseAnimationJob::changeDirectionWhileRunning() animation.setDuration(400); animation.start(); QTest::qWait(100); - QVERIFY(animation.state() == QAbstractAnimationJob::Running); + QCOMPARE(animation.state(), QAbstractAnimationJob::Running); animation.setDirection(QAbstractAnimationJob::Backward); QTest::qWait(animation.totalDuration() + 50); - QVERIFY(animation.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(animation.state(), QAbstractAnimationJob::Stopped); } void tst_QPauseAnimationJob::noTimerUpdates_data() @@ -155,7 +155,7 @@ void tst_QPauseAnimationJob::noTimerUpdates() QEXPECT_FAIL("", winTimerError, Abort); #endif - QVERIFY(animation.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(animation.state(), QAbstractAnimationJob::Stopped); const int expectedLoopCount = 1 + loopCount; #ifdef Q_OS_WIN @@ -183,13 +183,13 @@ void tst_QPauseAnimationJob::multiplePauseAnimations() if (animation.state() != QAbstractAnimationJob::Stopped) QEXPECT_FAIL("", winTimerError, Abort); #endif - QVERIFY(animation.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(animation.state(), QAbstractAnimationJob::Stopped); #ifdef Q_OS_WIN if (animation2.state() != QAbstractAnimationJob::Running) QEXPECT_FAIL("", winTimerError, Abort); #endif - QVERIFY(animation2.state() == QAbstractAnimationJob::Running); + QCOMPARE(animation2.state(), QAbstractAnimationJob::Running); #ifdef Q_OS_WIN if (animation.m_updateCurrentTimeCount != 2) @@ -224,7 +224,7 @@ void tst_QPauseAnimationJob::pauseAndPropertyAnimations() QCOMPARE(animation.state(), QAbstractAnimationJob::Running); QTRY_COMPARE(animation.state(), QAbstractAnimationJob::Running); - QVERIFY(pause.state() == QAbstractAnimationJob::Running); + QCOMPARE(pause.state(), QAbstractAnimationJob::Running); QVERIFY2(pause.m_updateCurrentTimeCount >= 2, QByteArrayLiteral("pause.m_updateCurrentTimeCount=") + QByteArray::number(pause.m_updateCurrentTimeCount)); @@ -245,7 +245,7 @@ void tst_QPauseAnimationJob::pauseResume() QCOMPARE(animation.state(), QAbstractAnimationJob::Paused); animation.start(); QTest::qWait(300); - QTRY_VERIFY(animation.state() == QAbstractAnimationJob::Stopped); + QTRY_COMPARE(animation.state(), QAbstractAnimationJob::Stopped); QVERIFY2(animation.m_updateCurrentTimeCount >= 3, QByteArrayLiteral("animation.m_updateCurrentTimeCount=") + QByteArray::number(animation.m_updateCurrentTimeCount)); } @@ -266,39 +266,39 @@ void tst_QPauseAnimationJob::sequentialPauseGroup() QCOMPARE(animation2.m_updateCurrentTimeCount, 0); QCOMPARE(animation3.m_updateCurrentTimeCount, 0); - QVERIFY(group.state() == QAbstractAnimationJob::Running); - QVERIFY(animation1.state() == QAbstractAnimationJob::Running); - QVERIFY(animation2.state() == QAbstractAnimationJob::Stopped); - QVERIFY(animation3.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(group.state(), QAbstractAnimationJob::Running); + QCOMPARE(animation1.state(), QAbstractAnimationJob::Running); + QCOMPARE(animation2.state(), QAbstractAnimationJob::Stopped); + QCOMPARE(animation3.state(), QAbstractAnimationJob::Stopped); group.setCurrentTime(250); QCOMPARE(animation1.m_updateCurrentTimeCount, 2); QCOMPARE(animation2.m_updateCurrentTimeCount, 1); QCOMPARE(animation3.m_updateCurrentTimeCount, 0); - QVERIFY(group.state() == QAbstractAnimationJob::Running); - QVERIFY(animation1.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(group.state(), QAbstractAnimationJob::Running); + QCOMPARE(animation1.state(), QAbstractAnimationJob::Stopped); QCOMPARE((QAbstractAnimationJob*)&animation2, group.currentAnimation()); - QVERIFY(animation2.state() == QAbstractAnimationJob::Running); - QVERIFY(animation3.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(animation2.state(), QAbstractAnimationJob::Running); + QCOMPARE(animation3.state(), QAbstractAnimationJob::Stopped); group.setCurrentTime(500); QCOMPARE(animation1.m_updateCurrentTimeCount, 2); QCOMPARE(animation2.m_updateCurrentTimeCount, 2); QCOMPARE(animation3.m_updateCurrentTimeCount, 1); - QVERIFY(group.state() == QAbstractAnimationJob::Running); - QVERIFY(animation1.state() == QAbstractAnimationJob::Stopped); - QVERIFY(animation2.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(group.state(), QAbstractAnimationJob::Running); + QCOMPARE(animation1.state(), QAbstractAnimationJob::Stopped); + QCOMPARE(animation2.state(), QAbstractAnimationJob::Stopped); QCOMPARE((QAbstractAnimationJob*)&animation3, group.currentAnimation()); - QVERIFY(animation3.state() == QAbstractAnimationJob::Running); + QCOMPARE(animation3.state(), QAbstractAnimationJob::Running); group.setCurrentTime(750); - QVERIFY(group.state() == QAbstractAnimationJob::Stopped); - QVERIFY(animation1.state() == QAbstractAnimationJob::Stopped); - QVERIFY(animation2.state() == QAbstractAnimationJob::Stopped); - QVERIFY(animation3.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(group.state(), QAbstractAnimationJob::Stopped); + QCOMPARE(animation1.state(), QAbstractAnimationJob::Stopped); + QCOMPARE(animation2.state(), QAbstractAnimationJob::Stopped); + QCOMPARE(animation3.state(), QAbstractAnimationJob::Stopped); QCOMPARE(animation1.m_updateCurrentTimeCount, 2); QCOMPARE(animation2.m_updateCurrentTimeCount, 2); @@ -318,22 +318,22 @@ void tst_QPauseAnimationJob::sequentialGroupWithPause() group.start(); - QVERIFY(group.state() == QAbstractAnimationJob::Running); - QVERIFY(animation.state() == QAbstractAnimationJob::Running); - QVERIFY(pause.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(group.state(), QAbstractAnimationJob::Running); + QCOMPARE(animation.state(), QAbstractAnimationJob::Running); + QCOMPARE(pause.state(), QAbstractAnimationJob::Stopped); group.setCurrentTime(300); - QVERIFY(group.state() == QAbstractAnimationJob::Running); - QVERIFY(animation.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(group.state(), QAbstractAnimationJob::Running); + QCOMPARE(animation.state(), QAbstractAnimationJob::Stopped); QCOMPARE((QAbstractAnimationJob*)&pause, group.currentAnimation()); - QVERIFY(pause.state() == QAbstractAnimationJob::Running); + QCOMPARE(pause.state(), QAbstractAnimationJob::Running); group.setCurrentTime(600); - QVERIFY(group.state() == QAbstractAnimationJob::Stopped); - QVERIFY(animation.state() == QAbstractAnimationJob::Stopped); - QVERIFY(pause.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(group.state(), QAbstractAnimationJob::Stopped); + QCOMPARE(animation.state(), QAbstractAnimationJob::Stopped); + QCOMPARE(pause.state(), QAbstractAnimationJob::Stopped); QCOMPARE(pause.m_updateCurrentTimeCount, 2); } @@ -383,11 +383,11 @@ void tst_QPauseAnimationJob::multipleSequentialGroups() group.start(); - QVERIFY(group.state() == QAbstractAnimationJob::Running); - QVERIFY(subgroup1.state() == QAbstractAnimationJob::Running); - QVERIFY(subgroup2.state() == QAbstractAnimationJob::Running); - QVERIFY(subgroup3.state() == QAbstractAnimationJob::Running); - QVERIFY(subgroup4.state() == QAbstractAnimationJob::Running); + QCOMPARE(group.state(), QAbstractAnimationJob::Running); + QCOMPARE(subgroup1.state(), QAbstractAnimationJob::Running); + QCOMPARE(subgroup2.state(), QAbstractAnimationJob::Running); + QCOMPARE(subgroup3.state(), QAbstractAnimationJob::Running); + QCOMPARE(subgroup4.state(), QAbstractAnimationJob::Running); // This is a pretty long animation so it tends to get rather out of sync // when using the consistent timer, so run for an extra half second for good @@ -398,31 +398,31 @@ void tst_QPauseAnimationJob::multipleSequentialGroups() if (group.state() != QAbstractAnimationJob::Stopped) QEXPECT_FAIL("", winTimerError, Abort); #endif - QTRY_VERIFY(group.state() == QAbstractAnimationJob::Stopped); + QTRY_COMPARE(group.state(), QAbstractAnimationJob::Stopped); #ifdef Q_OS_WIN if (subgroup1.state() != QAbstractAnimationJob::Stopped) QEXPECT_FAIL("", winTimerError, Abort); #endif - QVERIFY(subgroup1.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(subgroup1.state(), QAbstractAnimationJob::Stopped); #ifdef Q_OS_WIN if (subgroup2.state() != QAbstractAnimationJob::Stopped) QEXPECT_FAIL("", winTimerError, Abort); #endif - QVERIFY(subgroup2.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(subgroup2.state(), QAbstractAnimationJob::Stopped); #ifdef Q_OS_WIN if (subgroup3.state() != QAbstractAnimationJob::Stopped) QEXPECT_FAIL("", winTimerError, Abort); #endif - QVERIFY(subgroup3.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(subgroup3.state(), QAbstractAnimationJob::Stopped); #ifdef Q_OS_WIN if (subgroup4.state() != QAbstractAnimationJob::Stopped) QEXPECT_FAIL("", winTimerError, Abort); #endif - QVERIFY(subgroup4.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(subgroup4.state(), QAbstractAnimationJob::Stopped); #ifdef Q_OS_WIN if (pause5.m_updateCurrentTimeCount != 4) @@ -437,7 +437,7 @@ void tst_QPauseAnimationJob::zeroDuration() animation.setDuration(0); animation.start(); QTest::qWait(animation.totalDuration() + 100); - QVERIFY(animation.state() == QAbstractAnimationJob::Stopped); + QCOMPARE(animation.state(), QAbstractAnimationJob::Stopped); QCOMPARE(animation.m_updateCurrentTimeCount, 1); } diff --git a/tests/auto/qml/animation/qsequentialanimationgroupjob/BLACKLIST b/tests/auto/qml/animation/qsequentialanimationgroupjob/BLACKLIST new file mode 100644 index 0000000000..2afe6074d7 --- /dev/null +++ b/tests/auto/qml/animation/qsequentialanimationgroupjob/BLACKLIST @@ -0,0 +1,2 @@ +[finishWithUncontrolledAnimation] +* diff --git a/tests/auto/qml/animation/qsequentialanimationgroupjob/tst_qsequentialanimationgroupjob.cpp b/tests/auto/qml/animation/qsequentialanimationgroupjob/tst_qsequentialanimationgroupjob.cpp index 848bec0b0b..f004593d94 100644 --- a/tests/auto/qml/animation/qsequentialanimationgroupjob/tst_qsequentialanimationgroupjob.cpp +++ b/tests/auto/qml/animation/qsequentialanimationgroupjob/tst_qsequentialanimationgroupjob.cpp @@ -911,7 +911,7 @@ void tst_QSequentialAnimationGroupJob::startDelay() QTest::qWait(500); QTRY_COMPARE(group.state(), QAnimationGroupJob::Stopped); - QVERIFY(group.currentLoopTime() == 375); + QCOMPARE(group.currentLoopTime(), 375); } void tst_QSequentialAnimationGroupJob::clearGroup() @@ -1456,7 +1456,7 @@ void tst_QSequentialAnimationGroupJob::addRemoveAnimation() void tst_QSequentialAnimationGroupJob::currentAnimation() { QSequentialAnimationGroupJob group; - QVERIFY(group.currentAnimation() == 0); + QVERIFY(!group.currentAnimation()); TestAnimation anim(0); group.appendAnimation(&anim); @@ -1466,7 +1466,7 @@ void tst_QSequentialAnimationGroupJob::currentAnimation() void tst_QSequentialAnimationGroupJob::currentAnimationWithZeroDuration() { QSequentialAnimationGroupJob group; - QVERIFY(group.currentAnimation() == 0); + QVERIFY(!group.currentAnimation()); TestAnimation zero1(0); TestAnimation zero2(0); diff --git a/tests/auto/qml/debugger/debugger.pro b/tests/auto/qml/debugger/debugger.pro index fc1c0b537b..6b47801720 100644 --- a/tests/auto/qml/debugger/debugger.pro +++ b/tests/auto/qml/debugger/debugger.pro @@ -8,10 +8,12 @@ PUBLICTESTS += \ qpacketprotocol \ qqmlenginedebuginspectorintegrationtest \ qqmlenginecontrol \ - qqmldebuggingenabler + qqmldebuggingenabler \ + qqmlnativeconnector PRIVATETESTS += \ qqmldebugclient \ + qqmldebuglocal \ qqmldebugservice SUBDIRS += $$PUBLICTESTS diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp index 6f559d7833..d0801dd4ee 100644 --- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp +++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp @@ -185,7 +185,7 @@ void tst_QDebugMessageService::init() if (m_client->state() != QQmlDebugClient::Enabled) QQmlDebugTest::waitForSignal(m_client, SIGNAL(enabled())); - QVERIFY(m_client->state() == QQmlDebugClient::Enabled); + QCOMPARE(m_client->state(), QQmlDebugClient::Enabled); } void tst_QDebugMessageService::cleanup() diff --git a/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp b/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp index 155f11bdaf..db9e621d54 100644 --- a/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp +++ b/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp @@ -222,7 +222,7 @@ void tst_QPacketProtocol::read() void tst_QPacketProtocol::device() { QPacketProtocol p(m_client); - QVERIFY(p.device() == m_client); + QCOMPARE(p.device(), m_client); } void tst_QPacketProtocol::tst_QPacket_clear() diff --git a/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp b/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp index 7ca69b6d44..6fc6c6a914 100644 --- a/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp +++ b/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp @@ -42,6 +42,8 @@ #include "debugutil_p.h" #include "qqmldebugtestservice.h" +#include <private/qqmldebugconnector_p.h> + #define PORT 13770 #define STR_PORT "13770" @@ -51,6 +53,7 @@ class tst_QQmlDebugClient : public QObject private: QQmlDebugConnection *m_conn; + QQmlDebugTestService *m_service; private slots: void initTestCase(); @@ -64,26 +67,31 @@ private slots: void tst_QQmlDebugClient::initTestCase() { + QQmlDebugConnector::setPluginKey(QLatin1String("QQmlDebugServer")); + QTest::ignoreMessage(QtWarningMsg, + "QML debugger: Cannot set plugin key after loading the plugin."); + + m_service = new QQmlDebugTestService("tst_QQmlDebugClient::handshake()"); const QString waitingMsg = QString("QML Debugger: Waiting for connection on port %1...").arg(PORT); QTest::ignoreMessage(QtDebugMsg, waitingMsg.toLatin1().constData()); + QQmlDebuggingEnabler::startTcpDebugServer(PORT); + new QQmlEngine(this); m_conn = new QQmlDebugConnection(this); QQmlDebugTestClient client("tst_QQmlDebugClient::handshake()", m_conn); - QQmlDebugTestService service("tst_QQmlDebugClient::handshake()"); + for (int i = 0; i < 50; ++i) { // try for 5 seconds ... m_conn->connectToHost("127.0.0.1", PORT); - if (m_conn->waitForConnected()) + if (m_conn->waitForConnected(100)) break; - QTest::qSleep(100); } QVERIFY(m_conn->isConnected()); - QTRY_VERIFY(QQmlDebugService::hasDebuggingClient()); QTRY_COMPARE(client.state(), QQmlDebugClient::Enabled); } @@ -107,14 +115,6 @@ void tst_QQmlDebugClient::state() QQmlDebugTestClient client("tst_QQmlDebugClient::state()", m_conn); QCOMPARE(client.state(), QQmlDebugClient::Unavailable); - { - QQmlDebugTestService service("tst_QQmlDebugClient::state()", 2); - QTRY_COMPARE(client.state(), QQmlDebugClient::Enabled); - QCOMPARE(client.serviceVersion(), 2.0f); - } - - QTRY_COMPARE(client.state(), QQmlDebugClient::Unavailable); - // duplicate plugin name QTest::ignoreMessage(QtWarningMsg, "QQmlDebugClient: Conflicting plugin name \"tst_QQmlDebugClient::state()\""); QQmlDebugClient client2("tst_QQmlDebugClient::state()", m_conn); @@ -126,8 +126,7 @@ void tst_QQmlDebugClient::state() void tst_QQmlDebugClient::sendMessage() { - QQmlDebugTestService service("tst_QQmlDebugClient::sendMessage()"); - QQmlDebugTestClient client("tst_QQmlDebugClient::sendMessage()", m_conn); + QQmlDebugTestClient client("tst_QQmlDebugClient::handshake()", m_conn); QByteArray msg = "hello!"; @@ -153,7 +152,6 @@ void tst_QQmlDebugClient::sequentialConnect() { QQmlDebugConnection connection2; QQmlDebugTestClient client2("tst_QQmlDebugClient::handshake()", &connection2); - QQmlDebugTestService service("tst_QQmlDebugClient::handshake()"); m_conn->close(); QVERIFY(!m_conn->isConnected()); @@ -165,23 +163,10 @@ void tst_QQmlDebugClient::sequentialConnect() connection2.connectToHost("127.0.0.1", PORT); QVERIFY(connection2.waitForConnected()); QVERIFY(connection2.isConnected()); - QTRY_VERIFY(client2.state() == QQmlDebugClient::Enabled); + QTRY_COMPARE(client2.state(), QQmlDebugClient::Enabled); } -int main(int argc, char *argv[]) -{ - int _argc = argc + 1; - char **_argv = new char*[_argc]; - for (int i = 0; i < argc; ++i) - _argv[i] = argv[i]; - char arg[] = "-qmljsdebugger=port:" STR_PORT; - _argv[_argc - 1] = arg; - - QGuiApplication app(_argc, _argv); - tst_QQmlDebugClient tc; - return QTest::qExec(&tc, _argc, _argv); - delete _argv; -} +QTEST_MAIN(tst_QQmlDebugClient) #include "tst_qqmldebugclient.moc" diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp index 4ab1ac0a4c..98ef590317 100644 --- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp +++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp @@ -98,7 +98,7 @@ bool tst_QQmlDebuggingEnabler::init(bool blockMode, bool qmlscene, int portFrom, if (qmlscene) { process->start(QStringList() << QLatin1String("-qmljsdebugger=port:") + - QString::number(portFrom) + QLatin1String(",") + QString::number(portTo) + + QString::number(portFrom) + QLatin1Char(',') + QString::number(portTo) + QLatin1String(blockMode ? ",block": "") << testFile(QLatin1String("test.qml"))); } else { diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp index ed424b5a67..7dbe35807d 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp @@ -120,6 +120,8 @@ const char *UNCAUGHT = "uncaught"; const char *BLOCKMODE = "-qmljsdebugger=port:3771,3800,block"; const char *NORMALMODE = "-qmljsdebugger=port:3771,3800"; +const char *BLOCKRESTRICTEDMODE = "-qmljsdebugger=port:3771,3800,block,services:V8Debugger"; +const char *NORMALRESTRICTEDMODE = "-qmljsdebugger=port:3771,3800,services:V8Debugger"; const char *TEST_QMLFILE = "test.qml"; const char *TEST_JSFILE = "test.js"; const char *TIMER_QMLFILE = "timer.qml"; @@ -157,7 +159,8 @@ class tst_QQmlDebugJS : public QQmlDataTest { Q_OBJECT - bool init(const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true); + void init(const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true, + bool restrictServices = false); private slots: void initTestCase(); @@ -165,6 +168,7 @@ private slots: void cleanup(); + void connect_data(); void connect(); void interrupt(); void getVersion(); @@ -822,33 +826,29 @@ void tst_QQmlDebugJS::cleanupTestCase() // qDebug() << "Time Elapsed:" << t.elapsed(); } -bool tst_QQmlDebugJS::init(const QString &qmlFile, bool blockMode) +void tst_QQmlDebugJS::init(const QString &qmlFile, bool blockMode, bool restrictServices) { connection = new QQmlDebugConnection(); process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this); client = new QJSDebugClient(connection); + const char *args = 0; if (blockMode) - process->start(QStringList() << QLatin1String(BLOCKMODE) << testFile(qmlFile)); + args = restrictServices ? BLOCKRESTRICTEDMODE : BLOCKMODE; else - process->start(QStringList() << QLatin1String(NORMALMODE) << testFile(qmlFile)); + args = restrictServices ? NORMALRESTRICTEDMODE : NORMALMODE; - if (!process->waitForSessionStart()) { - qDebug() << "could not launch application, or did not get 'Waiting for connection'."; - return false; - } + process->start(QStringList() << QLatin1String(args) << testFile(qmlFile)); + + QVERIFY(process->waitForSessionStart()); const int port = process->debugPort(); connection->connectToHost("127.0.0.1", port); - if (!connection->waitForConnected()) { - qDebug() << "could not connect to host!"; - return false; - } + QVERIFY(connection->waitForConnected()); - if (client->state() == QQmlDebugClient::Enabled) - return true; - return QQmlDebugTest::waitForSignal(client, SIGNAL(enabled())); + if (client->state() != QQmlDebugClient::Enabled) + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(enabled()))); } void tst_QQmlDebugJS::cleanup() @@ -874,11 +874,21 @@ void tst_QQmlDebugJS::cleanup() connection = 0; } -void tst_QQmlDebugJS::connect() +void tst_QQmlDebugJS::connect_data() { - //void connect() + QTest::addColumn<bool>("blockMode"); + QTest::addColumn<bool>("restrictMode"); + QTest::newRow("normal/unrestricted") << false << false; + QTest::newRow("block/unrestricted") << true << false; + QTest::newRow("normal/restricted") << false << true; + QTest::newRow("block/restricted") << true << true; +} - QVERIFY(init()); +void tst_QQmlDebugJS::connect() +{ + QFETCH(bool, blockMode); + QFETCH(bool, restrictMode); + init(QString(TEST_QMLFILE), blockMode, restrictMode); client->connect(); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected()))); } @@ -887,7 +897,7 @@ void tst_QQmlDebugJS::interrupt() { //void connect() - QVERIFY(init()); + init(); client->connect(); client->interrupt(); @@ -898,7 +908,7 @@ void tst_QQmlDebugJS::getVersion() { //void version() - QVERIFY(init()); + init(); client->connect(); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected()))); @@ -923,7 +933,7 @@ void tst_QQmlDebugJS::disconnect() { //void disconnect() - QVERIFY(init()); + init(); client->connect(); client->disconnect(); @@ -935,7 +945,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted() //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) int sourceLine = 39; - QVERIFY(init(ONCOMPLETED_QMLFILE)); + init(ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); client->connect(); @@ -955,7 +965,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated() //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) int sourceLine = 39; - QVERIFY(init(CREATECOMPONENT_QMLFILE)); + init(CREATECOMPONENT_QMLFILE); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); client->connect(); @@ -973,7 +983,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated() void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback() { int sourceLine = 40; - QVERIFY(init(TIMER_QMLFILE)); + init(TIMER_QMLFILE); client->connect(); //We can set the breakpoint after connect() here because the timer is repeating and if we miss @@ -995,7 +1005,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile() //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) int sourceLine = 35; - QVERIFY(init(LOADJSFILE_QMLFILE)); + init(LOADJSFILE_QMLFILE); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_JSFILE), sourceLine, -1, true); client->connect(); @@ -1016,7 +1026,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComment() int sourceLine = 39; int actualLine = 41; - QVERIFY(init(BREAKPOINTRELOCATION_QMLFILE)); + init(BREAKPOINTRELOCATION_QMLFILE); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); client->connect(); @@ -1038,7 +1048,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine() int sourceLine = 40; int actualLine = 41; - QVERIFY(init(BREAKPOINTRELOCATION_QMLFILE)); + init(BREAKPOINTRELOCATION_QMLFILE); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); client->connect(); @@ -1059,7 +1069,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding() //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) int sourceLine = 44; - QVERIFY(init(BREAKPOINTRELOCATION_QMLFILE)); + init(BREAKPOINTRELOCATION_QMLFILE); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); client->connect(); @@ -1078,7 +1088,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition() { int out = 10; int sourceLine = 42; - QVERIFY(init(CONDITION_QMLFILE)); + init(CONDITION_QMLFILE); client->connect(); //The breakpoint is in a timer loop so we can set it after connect(). @@ -1112,7 +1122,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition() void tst_QQmlDebugJS::setBreakpointInScriptThatQuits() { - QVERIFY(init(QUIT_QMLFILE)); + init(QUIT_QMLFILE); int sourceLine = 41; @@ -1153,7 +1163,7 @@ void tst_QQmlDebugJS::setBreakpointOnEvent() //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) - QVERIFY(init(TIMER_QMLFILE)); + init(TIMER_QMLFILE); client->setBreakpoint(QLatin1String(EVENT), QLatin1String("triggered"), -1, -1, true); client->connect(); @@ -1174,7 +1184,7 @@ void tst_QQmlDebugJS::clearBreakpoint() int sourceLine1 = 42; int sourceLine2 = 43; - QVERIFY(init(CHANGEBREAKPOINT_QMLFILE)); + init(CHANGEBREAKPOINT_QMLFILE); client->connect(); //The breakpoints are in a timer loop so we can set them after connect(). @@ -1219,7 +1229,7 @@ void tst_QQmlDebugJS::setExceptionBreak() { //void setExceptionBreak(QString type, bool enabled = false); - QVERIFY(init(EXCEPTION_QMLFILE)); + init(EXCEPTION_QMLFILE); client->setExceptionBreak(QJSDebugClient::All,true); client->connect(); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); @@ -1230,7 +1240,7 @@ void tst_QQmlDebugJS::stepNext() //void continueDebugging(StepAction stepAction, int stepCount = 1); int sourceLine = 42; - QVERIFY(init(STEPACTION_QMLFILE)); + init(STEPACTION_QMLFILE); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true); client->connect(); @@ -1254,7 +1264,7 @@ void tst_QQmlDebugJS::stepIn() int sourceLine = 46; int actualLine = 42; - QVERIFY(init(STEPACTION_QMLFILE)); + init(STEPACTION_QMLFILE); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true); client->connect(); @@ -1278,7 +1288,7 @@ void tst_QQmlDebugJS::stepOut() int sourceLine = 42; int actualLine = 46; - QVERIFY(init(STEPACTION_QMLFILE)); + init(STEPACTION_QMLFILE); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true); client->connect(); @@ -1302,7 +1312,7 @@ void tst_QQmlDebugJS::continueDebugging() int sourceLine1 = 46; int sourceLine2 = 43; - QVERIFY(init(STEPACTION_QMLFILE)); + init(STEPACTION_QMLFILE); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true); @@ -1326,7 +1336,7 @@ void tst_QQmlDebugJS::backtrace() //void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false); int sourceLine = 39; - QVERIFY(init(ONCOMPLETED_QMLFILE)); + init(ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); client->connect(); @@ -1341,7 +1351,7 @@ void tst_QQmlDebugJS::getFrameDetails() //void frame(int number = -1); int sourceLine = 39; - QVERIFY(init(ONCOMPLETED_QMLFILE)); + init(ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); client->connect(); @@ -1356,7 +1366,7 @@ void tst_QQmlDebugJS::getScopeDetails() //void scope(int number = -1, int frameNumber = -1); int sourceLine = 39; - QVERIFY(init(ONCOMPLETED_QMLFILE)); + init(ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); client->connect(); @@ -1371,7 +1381,7 @@ void tst_QQmlDebugJS::evaluateInGlobalScope() { //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap()); - QVERIFY(init()); + init(); client->connect(); client->evaluate(QLatin1String("console.log('Hello World')"), true); @@ -1393,7 +1403,7 @@ void tst_QQmlDebugJS::evaluateInLocalScope() //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap()); int sourceLine = 47; - QVERIFY(init(ONCOMPLETED_QMLFILE)); + init(ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); client->connect(); @@ -1427,7 +1437,7 @@ void tst_QQmlDebugJS::getScripts() { //void scripts(int types = -1, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant()); - QVERIFY(init()); + init(); client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QString(TEST_QMLFILE), 40, -1, true); client->connect(); diff --git a/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro b/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro new file mode 100644 index 0000000000..b612da11de --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro @@ -0,0 +1,16 @@ +CONFIG += testcase +TARGET = tst_qqmldebuglocal +osx:CONFIG -= app_bundle + +HEADERS += ../shared/qqmldebugtestservice.h + +SOURCES += tst_qqmldebuglocal.cpp \ + ../shared/qqmldebugtestservice.cpp + +INCLUDEPATH += ../shared +include(../shared/debugutil.pri) + +CONFIG += parallel_test +QT += qml-private testlib gui-private core-private + +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 QT_QML_DEBUG_NO_WARNING diff --git a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp new file mode 100644 index 0000000000..0343ea77ee --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include <QSignalSpy> +#include <QTimer> +#include <QHostAddress> +#include <QDebug> +#include <QThread> +#include <ctime> + +#include "debugutil_p.h" +#include "qqmldebugtestservice.h" + +#include <private/qqmldebugconnector_p.h> + +QString fileName; + +class tst_QQmlDebugLocal : public QObject +{ + Q_OBJECT + +private: + QQmlDebugConnection *m_conn; + QQmlDebugTestService *m_service; + + bool connect(); + +signals: + void waiting(); + void parallel(); + +private slots: + void initTestCase(); + + void name(); + void state(); + void sendMessage(); +}; + +void tst_QQmlDebugLocal::initTestCase() +{ + fileName = QString::fromLatin1("tst_QQmlDebugLocal%1").arg(std::time(0)); + QQmlDebugConnector::setPluginKey("QQmlDebugServer"); + QTest::ignoreMessage(QtWarningMsg, + "QML debugger: Cannot set plugin key after loading the plugin."); + m_service = new QQmlDebugTestService("tst_QQmlDebugLocal::handshake()"); + + const QString waitingMsg = QString("QML Debugger: Connecting to socket %1...").arg(fileName); + QTest::ignoreMessage(QtDebugMsg, waitingMsg.toLatin1().constData()); + + m_conn = new QQmlDebugConnection(this); + m_conn->startLocalServer(fileName); + + QQmlDebuggingEnabler::connectToLocalDebugger(fileName); + + new QQmlEngine(this); + + QQmlDebugTestClient client("tst_QQmlDebugLocal::handshake()", m_conn); + + for (int i = 0; i < 50; ++i) { + // try for 5 seconds ... + if (m_conn->waitForConnected(100)) + break; + } + + QVERIFY(m_conn->isConnected()); + + QTRY_COMPARE(client.state(), QQmlDebugClient::Enabled); +} + +void tst_QQmlDebugLocal::name() +{ + QString name = "tst_QQmlDebugLocal::name()"; + + QQmlDebugClient client(name, m_conn); + QCOMPARE(client.name(), name); +} + +void tst_QQmlDebugLocal::state() +{ + { + QQmlDebugConnection dummyConn; + QQmlDebugClient client("tst_QQmlDebugLocal::state()", &dummyConn); + QCOMPARE(client.state(), QQmlDebugClient::NotConnected); + QCOMPARE(client.serviceVersion(), -1.0f); + } + + QQmlDebugTestClient client("tst_QQmlDebugLocal::state()", m_conn); + QCOMPARE(client.state(), QQmlDebugClient::Unavailable); + + // duplicate plugin name + QTest::ignoreMessage(QtWarningMsg, "QQmlDebugClient: Conflicting plugin name \"tst_QQmlDebugLocal::state()\""); + QQmlDebugClient client2("tst_QQmlDebugLocal::state()", m_conn); + QCOMPARE(client2.state(), QQmlDebugClient::NotConnected); + + QQmlDebugClient client3("tst_QQmlDebugLocal::state3()", 0); + QCOMPARE(client3.state(), QQmlDebugClient::NotConnected); +} + +void tst_QQmlDebugLocal::sendMessage() +{ + QQmlDebugTestClient client("tst_QQmlDebugLocal::handshake()", m_conn); + + QByteArray msg = "hello!"; + + QTRY_COMPARE(client.state(), QQmlDebugClient::Enabled); + + client.sendMessage(msg); + QByteArray resp = client.waitForResponse(); + QCOMPARE(resp, msg); +} + +QTEST_MAIN(tst_QQmlDebugLocal) + +#include "tst_qqmldebuglocal.moc" diff --git a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.pro b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.pro new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.pro diff --git a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp index de05594161..b63c5c0a6d 100644 --- a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp +++ b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp @@ -44,6 +44,7 @@ #include "debugutil_p.h" #include "qqmldebugclient.h" #include "qqmldebugtestservice.h" +#include <private/qqmldebugconnector_p.h> #define PORT 3769 #define STR_PORT "3769" @@ -53,7 +54,7 @@ class tst_QQmlDebugService : public QQmlDataTest Q_OBJECT private: QQmlDebugConnection *m_conn; - + QQmlDebugTestService *m_service; private slots: @@ -65,7 +66,6 @@ private slots: void sendMessage(); void idForObject(); void objectForId(); - void objectToString(); void checkSupportForDataStreamVersion(); void checkSupportForOldDataStreamVersion(); }; @@ -73,8 +73,15 @@ private slots: void tst_QQmlDebugService::initTestCase() { QQmlDataTest::initTestCase(); + QQmlDebugConnector::setPluginKey(QLatin1String("QQmlDebugServer")); + QTest::ignoreMessage(QtWarningMsg, + "QML debugger: Cannot set plugin key after loading the plugin."); + m_service = new QQmlDebugTestService("tst_QQmlDebugService", 2); + const QString waitingMsg = QString("QML Debugger: Waiting for connection on port %1...").arg(PORT); QTest::ignoreMessage(QtDebugMsg, waitingMsg.toLatin1().constData()); + QQmlDebuggingEnabler::startTcpDebugServer(PORT); + new QQmlEngine(this); m_conn = new QQmlDebugConnection(this); @@ -87,8 +94,6 @@ void tst_QQmlDebugService::initTestCase() QTest::qSleep(100); } QVERIFY(m_conn->isConnected()); - - QTRY_VERIFY(QQmlDebugService::hasDebuggingClient()); } void tst_QQmlDebugService::checkPortRange() @@ -128,67 +133,64 @@ void tst_QQmlDebugService::checkPortRange() void tst_QQmlDebugService::name() { - QString name = "tst_QQmlDebugService::name()"; - - QQmlDebugService service(name, 1); - QCOMPARE(service.name(), name); + QCOMPARE(m_service->name(), QLatin1String("tst_QQmlDebugService")); } void tst_QQmlDebugService::version() { - QString name = "tst_QQmlDebugService::name()"; - - QQmlDebugService service(name, 2); - QCOMPARE(service.version(), 2.0f); + QCOMPARE(m_service->version(), 2.0f); } void tst_QQmlDebugService::state() { - QQmlDebugTestService service("tst_QQmlDebugService::state()"); - QCOMPARE(service.state(), QQmlDebugService::Unavailable); + QCOMPARE(m_service->state(), QQmlDebugService::Unavailable); { - QQmlDebugTestClient client("tst_QQmlDebugService::state()", m_conn); + QQmlDebugTestClient client("tst_QQmlDebugService", m_conn); QTRY_COMPARE(client.state(), QQmlDebugClient::Enabled); - QTRY_COMPARE(service.state(), QQmlDebugService::Enabled); + QTRY_COMPARE(m_service->state(), QQmlDebugService::Enabled); } + QTRY_COMPARE(m_service->state(), QQmlDebugService::Unavailable); - QTRY_COMPARE(service.state(), QQmlDebugService::Unavailable); - - QTest::ignoreMessage(QtWarningMsg, "QQmlDebugService: Conflicting plugin name \"tst_QQmlDebugService::state()\""); - QQmlDebugTestService duplicate("tst_QQmlDebugService::state()"); + // We can do this because it will never addService() + QTest::ignoreMessage(QtWarningMsg, + "QQmlDebugService: Conflicting plugin name \"tst_QQmlDebugService\""); + QQmlDebugTestService duplicate("tst_QQmlDebugService"); QCOMPARE(duplicate.state(), QQmlDebugService::NotConnected); + QTest::ignoreMessage(QtWarningMsg, + "QQmlDebugService: Plugin \"tst_QQmlDebugService\" is not registered."); } void tst_QQmlDebugService::sendMessage() { - QQmlDebugTestService service("tst_QQmlDebugService::sendMessage()"); - QQmlDebugTestClient client("tst_QQmlDebugService::sendMessage()", m_conn); + QQmlDebugTestClient client("tst_QQmlDebugService", m_conn); QByteArray msg = "hello!"; QTRY_COMPARE(client.state(), QQmlDebugClient::Enabled); - QTRY_COMPARE(service.state(), QQmlDebugService::Enabled); + QTRY_COMPARE(m_service->state(), QQmlDebugService::Enabled); client.sendMessage(msg); QByteArray resp = client.waitForResponse(); QCOMPARE(resp, msg); - QTest::ignoreMessage(QtWarningMsg, "QQmlDebugService: Conflicting plugin name \"tst_QQmlDebugService::sendMessage()\""); - QQmlDebugTestService duplicate("tst_QQmlDebugService::sendMessage()"); - duplicate.sendMessage("msg"); + QTest::ignoreMessage(QtWarningMsg, + "QQmlDebugService: Conflicting plugin name \"tst_QQmlDebugService\""); + QQmlDebugTestService duplicate("tst_QQmlDebugService"); + emit duplicate.messageToClient(duplicate.name(), "msg"); + QTest::ignoreMessage(QtWarningMsg, + "QQmlDebugService: Plugin \"tst_QQmlDebugService\" is not registered."); } void tst_QQmlDebugService::checkSupportForDataStreamVersion() { - QQmlDebugTestService service("tst_QQmlDebugService::sendMessage2()"); - QQmlDebugTestClient client("tst_QQmlDebugService::sendMessage2()", m_conn); + QQmlDebugTestClient client("tst_QQmlDebugService", m_conn); QByteArray msg = "hello!"; QTRY_COMPARE(client.state(), QQmlDebugClient::Enabled); - QTRY_COMPARE(service.state(), QQmlDebugService::Enabled); + QTRY_COMPARE(m_service->state(), QQmlDebugService::Enabled); client.sendMessage(msg); QByteArray resp = client.waitForResponse(); @@ -231,18 +233,6 @@ void tst_QQmlDebugService::objectForId() QCOMPARE(QQmlDebugService::objectForId(id), static_cast<QObject*>(0)); } -void tst_QQmlDebugService::objectToString() -{ - QCOMPARE(QQmlDebugService::objectToString(0), QString("NULL")); - - QObject *obj = new QObject; - QCOMPARE(QQmlDebugService::objectToString(obj), QString("QObject: <unnamed>")); - - obj->setObjectName("Hello"); - QCOMPARE(QQmlDebugService::objectToString(obj), QString("QObject: Hello")); - delete obj; -} - void tst_QQmlDebugService::checkSupportForOldDataStreamVersion() { //create a new connection; @@ -258,14 +248,12 @@ void tst_QQmlDebugService::checkSupportForOldDataStreamVersion() } QVERIFY(m_conn->isConnected()); - QTRY_VERIFY(QQmlDebugService::hasDebuggingClient()); - QQmlDebugTestService service("tst_QQmlDebugService::sendMessage2()"); - QQmlDebugTestClient client("tst_QQmlDebugService::sendMessage2()", m_conn); + QQmlDebugTestClient client("tst_QQmlDebugService", m_conn); QByteArray msg = "hello!"; QTRY_COMPARE(client.state(), QQmlDebugClient::Enabled); - QTRY_COMPARE(service.state(), QQmlDebugService::Enabled); + QTRY_COMPARE(m_service->state(), QQmlDebugService::Enabled); client.sendMessage(msg); QByteArray resp = client.waitForResponse(); @@ -273,20 +261,6 @@ void tst_QQmlDebugService::checkSupportForOldDataStreamVersion() QCOMPARE(m_conn->dataStreamVersion(), int(QDataStream::Qt_4_7)); } - -int main(int argc, char *argv[]) -{ - int _argc = argc + 1; - char **_argv = new char*[_argc]; - for (int i = 0; i < argc; ++i) - _argv[i] = argv[i]; - char arg[] = "-qmljsdebugger=port:" STR_PORT ",host:127.0.0.1"; - _argv[_argc - 1] = arg; - - QGuiApplication app(_argc, _argv); - tst_QQmlDebugService tc; - return QTest::qExec(&tc, _argc, _argv); - delete _argv; -} +QTEST_MAIN(tst_QQmlDebugService) #include "tst_qqmldebugservice.moc" diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp index f6cf9dae60..11fa56d710 100644 --- a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp +++ b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp @@ -103,12 +103,15 @@ private: QQmlDebugConnection *m_connection; QQmlEngineControlClient *m_client; - void connect(const QString &testFile); + void connect(const QString &testFile, bool restrictServices); + void engine_data(); private slots: void cleanup(); + void startEngine_data(); void startEngine(); + void stopEngine_data(); void stopEngine(); }; @@ -148,11 +151,13 @@ void QQmlEngineControlClient::messageReceived(const QByteArray &message) QVERIFY(stream.atEnd()); } -void tst_QQmlEngineControl::connect(const QString &testFile) +void tst_QQmlEngineControl::connect(const QString &testFile, bool restrictServices) { const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene"; QStringList arguments; - arguments << QString("-qmljsdebugger=port:" STR_PORT_FROM "," STR_PORT_TO ",block"); + arguments << QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3") + .arg(STR_PORT_FROM).arg(STR_PORT_TO) + .arg(restrictServices ? QStringLiteral(",services:EngineControl") : QString()); arguments << QQmlDataTest::instance()->testFile(testFile); @@ -165,6 +170,8 @@ void tst_QQmlEngineControl::connect(const QString &testFile) const int port = m_process->debugPort(); m_connection->connectToHost(QLatin1String("127.0.0.1"), port); + + QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); } void tst_QQmlEngineControl::cleanup() @@ -183,11 +190,23 @@ void tst_QQmlEngineControl::cleanup() m_connection = 0; } +void tst_QQmlEngineControl::engine_data() +{ + QTest::addColumn<bool>("restrictMode"); + QTest::newRow("unrestricted") << false; + QTest::newRow("restricted") << true; +} + +void tst_QQmlEngineControl::startEngine_data() +{ + engine_data(); +} + void tst_QQmlEngineControl::startEngine() { - connect("test.qml"); - QVERIFY(m_client); - QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); + QFETCH(bool, restrictMode); + + connect("test.qml", restrictMode); QTRY_VERIFY(!m_client->startingEngines.empty()); m_client->command(QQmlEngineControlClient::StartWaitingEngine, m_client->startingEngines.last()); @@ -196,11 +215,16 @@ void tst_QQmlEngineControl::startEngine() "No engine start message received in time."); } +void tst_QQmlEngineControl::stopEngine_data() +{ + engine_data(); +} + void tst_QQmlEngineControl::stopEngine() { - connect("exit.qml"); - QVERIFY(m_client); - QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); + QFETCH(bool, restrictMode); + + connect("exit.qml", restrictMode); QTRY_VERIFY(!m_client->startingEngines.empty()); m_client->command(QQmlEngineControlClient::StartWaitingEngine, m_client->startingEngines.last()); diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp index 8d119a30d7..0285bae189 100644 --- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp @@ -61,6 +61,7 @@ public: private: + void init(bool restrictServices); QmlDebugObjectReference findRootObject(); QQmlDebugProcess *m_process; @@ -68,9 +69,9 @@ private: QQmlEngineDebugClient *m_engineDebugClient; private slots: - void init(); void cleanup(); + void connect_data(); void connect(); void clearObjectReferenceHashonReloadQml(); }; @@ -93,9 +94,12 @@ QmlDebugObjectReference tst_QQmlEngineDebugInspectorIntegration::findRootObject( } -void tst_QQmlEngineDebugInspectorIntegration::init() +void tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices) { - const QString argument = "-qmljsdebugger=port:" STR_PORT_FROM "," STR_PORT_TO ",block"; + const QString argument = QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3") + .arg(STR_PORT_FROM).arg(STR_PORT_TO) + .arg(restrictServices ? QStringLiteral(",services:QmlDebugger,QmlInspector") : + QString()); // ### Still using qmlscene because of QTBUG-33376 m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) @@ -108,10 +112,8 @@ void tst_QQmlEngineDebugInspectorIntegration::init() m_inspectorClient = new QQmlInspectorClient(m_connection); m_engineDebugClient = new QQmlEngineDebugClient(m_connection); - const int port = m_process->debugPort(); - m_connection->connectToHost(QLatin1String("127.0.0.1"), port); - bool ok = m_connection->waitForConnected(); - QVERIFY(ok); + m_connection->connectToHost(QLatin1String("127.0.0.1"), m_process->debugPort()); + QVERIFY(m_connection->waitForConnected()); } void tst_QQmlEngineDebugInspectorIntegration::cleanup() @@ -125,14 +127,24 @@ void tst_QQmlEngineDebugInspectorIntegration::cleanup() delete m_inspectorClient; } +void tst_QQmlEngineDebugInspectorIntegration::connect_data() +{ + QTest::addColumn<bool>("restrictMode"); + QTest::newRow("unrestricted") << false; + QTest::newRow("restricted") << true; +} + void tst_QQmlEngineDebugInspectorIntegration::connect() { + QFETCH(bool, restrictMode); + init(restrictMode); QTRY_COMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled); QTRY_COMPARE(m_engineDebugClient->state(), QQmlDebugClient::Enabled); } void tst_QQmlEngineDebugInspectorIntegration::clearObjectReferenceHashonReloadQml() { + init(true); QTRY_COMPARE(m_engineDebugClient->state(), QQmlDebugClient::Enabled); bool success = false; QmlDebugObjectReference rootObject = findRootObject(); diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp index d3bb5c38ca..bc3220ad8c 100644 --- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp @@ -87,6 +87,8 @@ public: class tst_QQmlEngineDebugService : public QObject { Q_OBJECT +public: + tst_QQmlEngineDebugService() : m_conn(0), m_dbg(0), m_engine(0), m_rootItem(0) {} private: QmlDebugObjectReference findRootObject(int context = 0, @@ -349,9 +351,8 @@ void tst_QQmlEngineDebugService::initTestCase() bool ok = m_conn->waitForConnected(); QVERIFY(ok); - QTRY_VERIFY(QQmlDebugService::hasDebuggingClient()); m_dbg = new QQmlEngineDebugClient(m_conn); - QTRY_VERIFY(m_dbg->state() == QQmlEngineDebugClient::Enabled); + QTRY_COMPARE(m_dbg->state(), QQmlEngineDebugClient::Enabled); } void tst_QQmlEngineDebugService::cleanupTestCase() @@ -372,7 +373,7 @@ void tst_QQmlEngineDebugService::setMethodBody() QVariant rv; QVERIFY(QMetaObject::invokeMethod(root, "myMethodNoArgs", Qt::DirectConnection, Q_RETURN_ARG(QVariant, rv))); - QVERIFY(rv == QVariant(qreal(3))); + QCOMPARE(rv, QVariant(qreal(3))); QVERIFY(m_dbg->setMethodBody(obj.debugId, "myMethodNoArgs", "return 7", @@ -382,7 +383,7 @@ void tst_QQmlEngineDebugService::setMethodBody() QVERIFY(QMetaObject::invokeMethod(root, "myMethodNoArgs", Qt::DirectConnection, Q_RETURN_ARG(QVariant, rv))); - QVERIFY(rv == QVariant(qreal(7))); + QCOMPARE(rv, QVariant(qreal(7))); } // With args @@ -390,7 +391,7 @@ void tst_QQmlEngineDebugService::setMethodBody() QVariant rv; QVERIFY(QMetaObject::invokeMethod(root, "myMethod", Qt::DirectConnection, Q_RETURN_ARG(QVariant, rv), Q_ARG(QVariant, QVariant(19)))); - QVERIFY(rv == QVariant(qreal(28))); + QCOMPARE(rv, QVariant(qreal(28))); QVERIFY(m_dbg->setMethodBody(obj.debugId, "myMethod", "return a + 7", &success)); @@ -399,7 +400,7 @@ void tst_QQmlEngineDebugService::setMethodBody() QVERIFY(QMetaObject::invokeMethod(root, "myMethod", Qt::DirectConnection, Q_RETURN_ARG(QVariant, rv), Q_ARG(QVariant, QVariant(19)))); - QVERIFY(rv == QVariant(qreal(26))); + QCOMPARE(rv, QVariant(qreal(26))); } } @@ -731,7 +732,7 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation() QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); - QVERIFY(m_dbg->objects().count() == 1); + QCOMPARE(m_dbg->objects().count(), 1); QmlDebugObjectReference obj = m_dbg->objects().first(); // check source as defined in main() @@ -1018,7 +1019,7 @@ void tst_QQmlEngineDebugService::setBindingForObject() mouseAreaObject = m_dbg->object(); onEnteredRef = findProperty(mouseAreaObject.properties, "onEntered"); QCOMPARE(onEnteredRef.name, QString("onEntered")); - QCOMPARE(onEnteredRef.value, QVariant("{console.log('hello, world') }")); + QCOMPARE(onEnteredRef.value, QVariant("function() { [code] }")); } void tst_QQmlEngineDebugService::resetBindingForObject() @@ -1224,7 +1225,7 @@ int main(int argc, char *argv[]) char **_argv = new char*[_argc]; for (int i = 0; i < argc; ++i) _argv[i] = argv[i]; - char arg[] = "-qmljsdebugger=port:3768"; + char arg[] = "-qmljsdebugger=port:3768,services:QmlDebugger"; _argv[_argc - 1] = arg; QGuiApplication app(_argc, _argv); diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp index 5ed866c04d..70833f5e2c 100644 --- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp +++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp @@ -60,7 +60,7 @@ public: } private: - void startQmlsceneProcess(const char *qmlFile); + void startQmlsceneProcess(const char *qmlFile, bool restrictMode = true); private: QQmlDebugProcess *m_process; @@ -68,18 +68,20 @@ private: QQmlInspectorClient *m_client; private slots: - void init(); void cleanup(); + void connect_data(); void connect(); void showAppOnTop(); void reloadQml(); void reloadQmlWindow(); }; -void tst_QQmlInspector::startQmlsceneProcess(const char * /* qmlFile */) +void tst_QQmlInspector::startQmlsceneProcess(const char * /* qmlFile */, bool restrictServices) { - const QString argument = "-qmljsdebugger=port:" STR_PORT_FROM "," STR_PORT_TO ",block"; + const QString argument = QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3") + .arg(STR_PORT_FROM).arg(STR_PORT_TO) + .arg(restrictServices ? QStringLiteral(",services:QmlInspector") : QString()); // ### This should be using qml instead of qmlscene, but can't because of QTBUG-33376 (same as the XFAIL testcase) m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this); @@ -87,15 +89,13 @@ void tst_QQmlInspector::startQmlsceneProcess(const char * /* qmlFile */) QVERIFY2(m_process->waitForSessionStart(), "Could not launch application, or did not get 'Waiting for connection'."); - QQmlDebugConnection *m_connection = new QQmlDebugConnection(); + m_connection = new QQmlDebugConnection(); m_client = new QQmlInspectorClient(m_connection); - const int port = m_process->debugPort(); - m_connection->connectToHost(QLatin1String("127.0.0.1"), port); -} + m_connection->connectToHost(QLatin1String("127.0.0.1"), m_process->debugPort()); + QVERIFY(m_client); + QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); -void tst_QQmlInspector::init() -{ } void tst_QQmlInspector::cleanup() @@ -104,20 +104,31 @@ void tst_QQmlInspector::cleanup() qDebug() << "Process State:" << m_process->state(); qDebug() << "Application Output:" << m_process->output(); } - delete m_process; - delete m_connection; delete m_client; + m_client = 0; + delete m_connection; + m_connection = 0; + delete m_process; + m_process = 0; +} + +void tst_QQmlInspector::connect_data() +{ + QTest::addColumn<bool>("restrictMode"); + QTest::newRow("unrestricted") << false; + QTest::newRow("restricted") << true; } void tst_QQmlInspector::connect() { - startQmlsceneProcess("qtquick2.qml"); - QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); + QFETCH(bool, restrictMode); + startQmlsceneProcess("qtquick2.qml", restrictMode); } void tst_QQmlInspector::showAppOnTop() { startQmlsceneProcess("qtquick2.qml"); + QVERIFY(m_client); QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); m_client->setShowAppOnTop(true); @@ -132,6 +143,7 @@ void tst_QQmlInspector::showAppOnTop() void tst_QQmlInspector::reloadQml() { startQmlsceneProcess("qtquick2.qml"); + QVERIFY(m_client); QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); QByteArray fileContents; @@ -157,6 +169,7 @@ void tst_QQmlInspector::reloadQml() void tst_QQmlInspector::reloadQmlWindow() { startQmlsceneProcess("window.qml"); + QVERIFY(m_client); QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); QByteArray fileContents; @@ -173,8 +186,8 @@ void tst_QQmlInspector::reloadQmlWindow() QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(responseReceived()))); QEXPECT_FAIL("", "cannot debug with a QML file containing a top-level Window", Abort); // QTBUG-33376 - QTRY_COMPARE(m_process->output().contains( - QString("version 2.0")), true); + // TODO: remove the timeout once we don't expect it to fail anymore. + QTRY_VERIFY_WITH_TIMEOUT(m_process->output().contains(QString("version 2.0")), 1); QCOMPARE(m_client->m_requestResult, true); QCOMPARE(m_client->m_reloadRequestId, m_client->m_responseId); diff --git a/tests/auto/qml/debugger/qqmlnativeconnector/qqmlnativeconnector.pro b/tests/auto/qml/debugger/qqmlnativeconnector/qqmlnativeconnector.pro new file mode 100644 index 0000000000..757aa0306d --- /dev/null +++ b/tests/auto/qml/debugger/qqmlnativeconnector/qqmlnativeconnector.pro @@ -0,0 +1,6 @@ +CONFIG += testcase qml_debug +TARGET = tst_qqmlnativeconnector +QT += qml testlib gui-private core-private +osx:CONFIG -= app_bundle + +SOURCES += tst_qqmlnativeconnector.cpp diff --git a/tests/auto/qml/debugger/qqmlnativeconnector/tst_qqmlnativeconnector.cpp b/tests/auto/qml/debugger/qqmlnativeconnector/tst_qqmlnativeconnector.cpp new file mode 100644 index 0000000000..099b952352 --- /dev/null +++ b/tests/auto/qml/debugger/qqmlnativeconnector/tst_qqmlnativeconnector.cpp @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qjsondocument.h> +#include <QtCore/qjsonobject.h> +#include <QtCore/qtimer.h> +#include <QtTest/qtest.h> +#include <QtQml/qqmlapplicationengine.h> +#include <QtQml/qqmlcomponent.h> + +#include <private/qhooks_p.h> + +const char testData[] = +"import QtQuick 2.0\n" +"Item {\n" +" id: item\n" +" property int a: 0\n" +" Timer {\n" +" id: timer; interval: 1; repeat: true; running: true\n" +" onTriggered: {\n" +" a++\n" +" }\n" +" }\n" +"}\n"; + +struct ResolvedHooks +{ + quintptr version; + quintptr numEntries; + const char **qt_qmlDebugMessageBuffer; + int *qt_qmlDebugMessageLength; + bool (*qt_qmlDebugSendDataToService)(const char *serviceName, const char *hexData); + bool (*qt_qmlDebugEnableService)(const char *data); + bool (*qt_qmlDebugDisableService)(const char *data); + void (*qt_qmlDebugObjectAvailable)(); +} *hooks; + +class Application : public QGuiApplication +{ + Q_OBJECT +public: + Application(int &argc, char **argv) + : QGuiApplication(argc, argv), + component(&engine) + { + component.setData(testData, QUrl("MyStuff")); + mainObject = component.create(); + } + +private slots: + void testEcho() + { + QJsonObject request; + QJsonObject arguments; + arguments.insert(QLatin1String("test"), QLatin1String("BUH")); + request.insert(QLatin1String("command"), QLatin1String("echo")); + request.insert(QLatin1String("arguments"), arguments); + QJsonDocument doc; + doc.setObject(request); + QByteArray hexdata = doc.toJson(QJsonDocument::Compact).toHex(); + + hooks = (ResolvedHooks *)qtHookData[QHooks::Startup]; + QCOMPARE(bool(hooks), true); // Available after connector start only. + QCOMPARE(hooks->version, quintptr(1)); + QCOMPARE(hooks->numEntries, quintptr(6)); + QCOMPARE(bool(hooks->qt_qmlDebugSendDataToService), true); + QCOMPARE(bool(hooks->qt_qmlDebugMessageBuffer), true); + QCOMPARE(bool(hooks->qt_qmlDebugMessageLength), true); + QCOMPARE(bool(hooks->qt_qmlDebugEnableService), true); + + hooks->qt_qmlDebugEnableService("NativeQmlDebugger"); + hooks->qt_qmlDebugSendDataToService("NativeQmlDebugger", hexdata); + QByteArray response(*hooks->qt_qmlDebugMessageBuffer, *hooks->qt_qmlDebugMessageLength); + + QCOMPARE(response, QByteArray("NativeQmlDebugger 25 {\"result\":{\"test\":\"BUH\"}}")); + } + +private: + QQmlApplicationEngine engine; + QQmlComponent component; + QObject *mainObject; +}; + +int main(int argc, char *argv[]) +{ + char **argv2 = new char *[argc + 2]; + for (int i = 0; i < argc; ++i) + argv2[i] = argv[i]; + argv2[argc] = strdup("-qmljsdebugger=native,services:NativeQmlDebugger"); + ++argc; + argv2[argc] = 0; + Application app(argc, argv2); + return QTest::qExec(&app, argc, argv); +} + +#include "tst_qqmlnativeconnector.moc" diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/timer.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/timer.qml new file mode 100644 index 0000000000..18b8947172 --- /dev/null +++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/timer.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 100 + height: 62 + + Timer { + running: true + repeat: true + interval: 50 + onTriggered: height = (2 * height) % 99; + } +} + diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro index ec84139797..e422d3ef99 100644 --- a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro +++ b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro @@ -21,4 +21,5 @@ OTHER_FILES += \ data/scenegraphTest.qml \ data/TestImage_2x2.png \ data/signalSourceLocation.qml \ - data/javascript.qml + data/javascript.qml \ + data/timer.qml diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp index 094bf43549..0e63e18952 100644 --- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp +++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp @@ -139,16 +139,18 @@ public: { } - QList<QQmlProfilerData> qmlMessages; - QList<QQmlProfilerData> javascriptMessages; - QList<QQmlProfilerData> jsHeapMessages; - QList<QQmlProfilerData> asynchronousMessages; - QList<QQmlProfilerData> pixmapMessages; + QVector<QQmlProfilerData> qmlMessages; + QVector<QQmlProfilerData> javascriptMessages; + QVector<QQmlProfilerData> jsHeapMessages; + QVector<QQmlProfilerData> asynchronousMessages; + QVector<QQmlProfilerData> pixmapMessages; - void setTraceState(bool enabled) { + void setTraceState(bool enabled, quint32 flushInterval = 0) { QByteArray message; QDataStream stream(&message, QIODevice::WriteOnly); stream << enabled; + if (enabled && flushInterval) + stream << -1 << std::numeric_limits<quint64>::max() << flushInterval; sendMessage(message); } @@ -195,7 +197,7 @@ private: CheckAll = CheckMessageType | CheckDetailType | CheckLine | CheckColumn | CheckDataEndsWith }; - void connect(bool block, const QString &testFile); + void connect(bool block, const QString &testFile, bool restrictServices = true); void checkTraceReceived(); void checkJsHeap(); bool verify(MessageListType type, int expectedPosition, const QQmlProfilerData &expected, @@ -204,15 +206,15 @@ private: private slots: void cleanup(); - void blockingConnectWithTraceEnabled(); - void blockingConnectWithTraceDisabled(); - void nonBlockingConnect(); + void connect_data(); + void connect(); void pixmapCacheData(); void scenegraphData(); void profileOnExit(); void controlFromJS(); void signalSourceLocation(); void javascript(); + void flushInterval(); }; #define VERIFY(type, position, expected, checks) QVERIFY(verify(type, position, expected, checks)) @@ -354,17 +356,16 @@ void QQmlProfilerClient::messageReceived(const QByteArray &message) qmlMessages.append(data); } -void tst_QQmlProfilerService::connect(bool block, const QString &testFile) +void tst_QQmlProfilerService::connect(bool block, const QString &testFile, bool restrictServices) { // ### Still using qmlscene due to QTBUG-33377 const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene"; QStringList arguments; - if (block) - arguments << QString("-qmljsdebugger=port:" STR_PORT_FROM "," STR_PORT_TO ",block"); - else - arguments << QString("-qmljsdebugger=port:" STR_PORT_FROM "," STR_PORT_TO ); - - arguments << QQmlDataTest::instance()->testFile(testFile); + arguments << QString::fromLatin1("-qmljsdebugger=port:%1,%2%3%4") + .arg(STR_PORT_FROM).arg(STR_PORT_TO) + .arg(block ? QStringLiteral(",block") : QString()) + .arg(restrictServices ? QStringLiteral(",services:CanvasFrameRate") : QString()) + << QQmlDataTest::instance()->testFile(testFile); m_process = new QQmlDebugProcess(executable, this); m_process->start(QStringList() << arguments); @@ -375,6 +376,8 @@ void tst_QQmlProfilerService::connect(bool block, const QString &testFile) const int port = m_process->debugPort(); m_connection->connectToHost(QLatin1String("127.0.0.1"), port); + QVERIFY(m_client); + QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); } void tst_QQmlProfilerService::checkTraceReceived() @@ -449,7 +452,7 @@ bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType ty int expectedPosition, const QQmlProfilerData &expected, quint32 checks) { - QList<QQmlProfilerData> *target = 0; + QVector<QQmlProfilerData> *target = 0; switch (type) { case MessageListQML: target = &(m_client->qmlMessages); break; case MessageListJavaScript: target = &(m_client->javascriptMessages); break; @@ -509,7 +512,7 @@ bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType ty void tst_QQmlProfilerService::cleanup() { - if (QTest::currentTestFailed()) { + if (m_client && QTest::currentTestFailed()) { qDebug() << "QML Messages:" << m_client->qmlMessages.count(); int i = 0; foreach (const QQmlProfilerData &data, m_client->qmlMessages) { @@ -547,7 +550,7 @@ void tst_QQmlProfilerService::cleanup() qDebug() << "Process State:" << (m_process ? m_process->state() : QLatin1String("null")); qDebug() << "Application Output:" << (m_process ? m_process->output() : QLatin1String("null")); qDebug() << "Connection State:" << (m_connection ? m_connection->stateString() : QLatin1String("null")); - qDebug() << "Client State:" << (m_client ? m_client->stateString() : QLatin1String("null")); + qDebug() << "Client State:" << m_client->stateString(); } delete m_process; m_process = 0; @@ -557,37 +560,32 @@ void tst_QQmlProfilerService::cleanup() m_connection = 0; } -void tst_QQmlProfilerService::blockingConnectWithTraceEnabled() +void tst_QQmlProfilerService::connect_data() { - connect(true, "test.qml"); - QVERIFY(m_client); - QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); - - m_client->setTraceState(true); - m_client->setTraceState(false); - checkTraceReceived(); - checkJsHeap(); + QTest::addColumn<bool>("blockMode"); + QTest::addColumn<bool>("restrictMode"); + QTest::addColumn<bool>("traceEnabled"); + QTest::newRow("normal/unrestricted/disabled") << false << false << false; + QTest::newRow("block/unrestricted/disabled") << true << false << false; + QTest::newRow("normal/restricted/disabled") << false << true << false; + QTest::newRow("block/restricted/disabled") << true << true << false; + QTest::newRow("normal/unrestricted/enabled") << false << false << true; + QTest::newRow("block/unrestricted/enabled") << true << false << true; + QTest::newRow("normal/restricted/enabled") << false << true << true; + QTest::newRow("block/restricted/enabled") << true << true << true; } -void tst_QQmlProfilerService::blockingConnectWithTraceDisabled() +void tst_QQmlProfilerService::connect() { - connect(true, "test.qml"); - QVERIFY(m_client); - QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); + QFETCH(bool, blockMode); + QFETCH(bool, restrictMode); + QFETCH(bool, traceEnabled); - m_client->setTraceState(false); - m_client->setTraceState(true); - m_client->setTraceState(false); - checkTraceReceived(); - checkJsHeap(); -} - -void tst_QQmlProfilerService::nonBlockingConnect() -{ - connect(false, "test.qml"); - QVERIFY(m_client); - QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); + connect(blockMode, "test.qml", restrictMode); + // if the engine is waiting, then the first message determines if it starts with trace enabled + if (!traceEnabled) + m_client->setTraceState(false); m_client->setTraceState(true); m_client->setTraceState(false); checkTraceReceived(); @@ -597,8 +595,6 @@ void tst_QQmlProfilerService::nonBlockingConnect() void tst_QQmlProfilerService::pixmapCacheData() { connect(true, "pixmapCacheTest.qml"); - QVERIFY(m_client); - QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); m_client->setTraceState(true); QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput()))); @@ -636,8 +632,6 @@ void tst_QQmlProfilerService::pixmapCacheData() void tst_QQmlProfilerService::scenegraphData() { connect(true, "scenegraphTest.qml"); - QVERIFY(m_client); - QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); m_client->setTraceState(true); @@ -690,8 +684,6 @@ void tst_QQmlProfilerService::scenegraphData() void tst_QQmlProfilerService::profileOnExit() { connect(true, "exit.qml"); - QVERIFY(m_client); - QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); m_client->setTraceState(true); @@ -702,8 +694,6 @@ void tst_QQmlProfilerService::profileOnExit() void tst_QQmlProfilerService::controlFromJS() { connect(true, "controlFromJS.qml"); - QVERIFY(m_client); - QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); m_client->setTraceState(false); checkTraceReceived(); @@ -713,8 +703,6 @@ void tst_QQmlProfilerService::controlFromJS() void tst_QQmlProfilerService::signalSourceLocation() { connect(true, "signalSourceLocation.qml"); - QVERIFY(m_client); - QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); m_client->setTraceState(true); while (!(m_process->output().contains(QLatin1String("500")))) @@ -738,8 +726,6 @@ void tst_QQmlProfilerService::signalSourceLocation() void tst_QQmlProfilerService::javascript() { connect(true, "javascript.qml"); - QVERIFY(m_client); - QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); m_client->setTraceState(true); while (!(m_process->output().contains(QLatin1String("done")))) @@ -766,6 +752,22 @@ void tst_QQmlProfilerService::javascript() VERIFY(MessageListJavaScript, 21, expected, CheckMessageType | CheckDetailType); } +void tst_QQmlProfilerService::flushInterval() +{ + connect(true, "timer.qml"); + + m_client->setTraceState(true, 1); + + // Make sure we get multiple messages + QTRY_VERIFY(m_client->qmlMessages.length() > 0); + QVERIFY(m_client->qmlMessages.length() < 100); + QTRY_VERIFY(m_client->qmlMessages.length() > 100); + + m_client->setTraceState(false); + checkTraceReceived(); + checkJsHeap(); +} + QTEST_MAIN(tst_QQmlProfilerService) #include "tst_qqmlprofilerservice.moc" diff --git a/tests/auto/qml/debugger/shared/debugutil.cpp b/tests/auto/qml/debugger/shared/debugutil.cpp index 74f22e6997..51d706b818 100644 --- a/tests/auto/qml/debugger/shared/debugutil.cpp +++ b/tests/auto/qml/debugger/shared/debugutil.cpp @@ -91,7 +91,7 @@ QQmlDebugProcess::QQmlDebugProcess(const QString &executable, QObject *parent) m_timer.setSingleShot(true); m_timer.setInterval(5000); connect(&m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(processAppOutput())); - connect(&m_process, SIGNAL(error(QProcess::ProcessError)), + connect(&m_process, SIGNAL(errorOccurred(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError))); connect(&m_timer, SIGNAL(timeout()), SLOT(timeout())); } diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h index 440cf34e81..d544a89ff2 100644 --- a/tests/auto/qml/debugger/shared/debugutil_p.h +++ b/tests/auto/qml/debugger/shared/debugutil_p.h @@ -35,6 +35,17 @@ #ifndef DEBUGUTIL_H #define DEBUGUTIL_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include <QEventLoop> #include <QTimer> #include <QThread> diff --git a/tests/auto/qml/debugger/shared/qqmldebugclient.cpp b/tests/auto/qml/debugger/shared/qqmldebugclient.cpp index c7281dec69..0f7e572e02 100644 --- a/tests/auto/qml/debugger/shared/qqmldebugclient.cpp +++ b/tests/auto/qml/debugger/shared/qqmldebugclient.cpp @@ -39,6 +39,8 @@ #include <QtCore/qstringlist.h> #include <QtCore/qtimer.h> #include <QtNetwork/qnetworkproxy.h> +#include <QtNetwork/qlocalserver.h> +#include <QtNetwork/qlocalsocket.h> const int protocolVersion = 1; const QString serverId = QLatin1String("QDeclarativeDebugServer"); @@ -61,6 +63,7 @@ public: QQmlDebugConnection *q; QPacketProtocol *protocol; QIODevice *device; + QLocalServer *server; QEventLoop handshakeEventLoop; QTimer handshakeTimer; @@ -72,6 +75,10 @@ public: void connectDeviceSignals(); public Q_SLOTS: + void forwardStateChange(QLocalSocket::LocalSocketState state); + void forwardError(QLocalSocket::LocalSocketError error); + + void newConnection(); void connected(); void readyRead(); void deviceAboutToClose(); @@ -79,7 +86,7 @@ public Q_SLOTS: }; QQmlDebugConnectionPrivate::QQmlDebugConnectionPrivate(QQmlDebugConnection *c) - : QObject(c), q(c), protocol(0), device(0), gotHello(false) + : QObject(c), q(c), protocol(0), device(0), server(0), gotHello(false) { protocol = new QPacketProtocol(q, this); QObject::connect(c, SIGNAL(connected()), this, SLOT(connected())); @@ -307,10 +314,13 @@ void QQmlDebugConnection::close() bool QQmlDebugConnection::waitForConnected(int msecs) { QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device); - if (!socket) - return false; - if (!socket->waitForConnected(msecs)) + if (!socket) { + if (!d->server || (!d->server->hasPendingConnections() && + !d->server->waitForNewConnection(msecs))) + return false; + } else if (!socket->waitForConnected(msecs)) { return false; + } // wait for handshake d->handshakeTimer.start(); d->handshakeEventLoop.exec(); @@ -336,9 +346,13 @@ QString QQmlDebugConnection::stateString() const QAbstractSocket::SocketState QQmlDebugConnection::state() const { - QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device); - if (socket) - return socket->state(); + QAbstractSocket *abstractSocket = qobject_cast<QAbstractSocket*>(d->device); + if (abstractSocket) + return abstractSocket->state(); + + QLocalSocket *localSocket = qobject_cast<QLocalSocket*>(d->device); + if (localSocket) + return static_cast<QAbstractSocket::SocketState>(localSocket->state()); return QAbstractSocket::UnconnectedState; } @@ -366,6 +380,29 @@ void QQmlDebugConnection::connectToHost(const QString &hostName, quint16 port) QIODevice::open(ReadWrite | Unbuffered); } +void QQmlDebugConnection::startLocalServer(const QString &fileName) +{ + d->gotHello = false; + d->server = new QLocalServer(d); + // QueuedConnection so that waitForNewConnection() returns true. + connect(d->server, SIGNAL(newConnection()), d, SLOT(newConnection()), Qt::QueuedConnection); + d->server->listen(fileName); + QIODevice::open(ReadWrite | Unbuffered); +} + +void QQmlDebugConnectionPrivate::newConnection() +{ + QLocalSocket *socket = server->nextPendingConnection(); + server->close(); + device = socket; + connectDeviceSignals(); + connect(socket, SIGNAL(stateChanged(QLocalSocket::LocalSocketState)), + this, SLOT(forwardStateChange(QLocalSocket::LocalSocketState))); + connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)), + this, SLOT(forwardError(QLocalSocket::LocalSocketError))); + emit q->connected(); +} + void QQmlDebugConnectionPrivate::connectDeviceSignals() { connect(device, SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64))); @@ -373,7 +410,15 @@ void QQmlDebugConnectionPrivate::connectDeviceSignals() connect(device, SIGNAL(aboutToClose()), this, SLOT(deviceAboutToClose())); } -// +void QQmlDebugConnectionPrivate::forwardStateChange(QLocalSocket::LocalSocketState state) +{ + emit q->stateChanged(static_cast<QAbstractSocket::SocketState>(state)); +} + +void QQmlDebugConnectionPrivate::forwardError(QLocalSocket::LocalSocketError error) +{ + emit q->error(static_cast<QAbstractSocket::SocketError>(error)); +} QQmlDebugClientPrivate::QQmlDebugClientPrivate() : connection(0) diff --git a/tests/auto/qml/debugger/shared/qqmldebugclient.h b/tests/auto/qml/debugger/shared/qqmldebugclient.h index 52f428cca7..fe9da693c8 100644 --- a/tests/auto/qml/debugger/shared/qqmldebugclient.h +++ b/tests/auto/qml/debugger/shared/qqmldebugclient.h @@ -46,6 +46,7 @@ public: ~QQmlDebugConnection(); void connectToHost(const QString &hostName, quint16 port); + void startLocalServer(const QString &fileName); void setDataStreamVersion(int dataStreamVersion); int dataStreamVersion(); diff --git a/tests/auto/qml/debugger/shared/qqmldebugtestservice.cpp b/tests/auto/qml/debugger/shared/qqmldebugtestservice.cpp index 990cb1caa1..e62aa2ce61 100644 --- a/tests/auto/qml/debugger/shared/qqmldebugtestservice.cpp +++ b/tests/auto/qml/debugger/shared/qqmldebugtestservice.cpp @@ -37,13 +37,12 @@ QQmlDebugTestService::QQmlDebugTestService(const QString &s, float version, QObject *parent) : QQmlDebugService(s, version, parent) { - registerService(); } void QQmlDebugTestService::messageReceived(const QByteArray &ba) { Q_ASSERT(QThread::currentThread() != thread()); - QMetaObject::invokeMethod(this, "_sendMessage", Qt::QueuedConnection, Q_ARG(QByteArray, ba)); + emit messageToClient(name(), ba); } void QQmlDebugTestService::stateAboutToBeChanged(QQmlDebugService::State) @@ -56,8 +55,3 @@ void QQmlDebugTestService::stateChanged(State) Q_ASSERT(QThread::currentThread() != thread()); emit stateHasChanged(); } - -void QQmlDebugTestService::_sendMessage(const QByteArray &msg) -{ - QQmlDebugService::sendMessage(msg); -} diff --git a/tests/auto/qml/debugger/shared/qqmldebugtestservice.h b/tests/auto/qml/debugger/shared/qqmldebugtestservice.h index 7cb09798de..cc24f3c119 100644 --- a/tests/auto/qml/debugger/shared/qqmldebugtestservice.h +++ b/tests/auto/qml/debugger/shared/qqmldebugtestservice.h @@ -46,9 +46,6 @@ public: signals: void stateHasChanged(); -private slots: - void _sendMessage(const QByteArray &msg); - protected: virtual void messageReceived(const QByteArray &ba); virtual void stateAboutToBeChanged(State state); diff --git a/tests/auto/qml/parserstress/tests/ecma/Date/15.9.1.13-1.js b/tests/auto/qml/parserstress/tests/ecma/Date/15.9.1.13-1.js index 720b39dd54..720b39dd54 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma/Date/15.9.1.13-1.js +++ b/tests/auto/qml/parserstress/tests/ecma/Date/15.9.1.13-1.js diff --git a/tests/auto/qml/parserstress/tests/ecma/ExecutionContexts/10.1.3-2.js b/tests/auto/qml/parserstress/tests/ecma/ExecutionContexts/10.1.3-2.js index 3762842461..3762842461 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma/ExecutionContexts/10.1.3-2.js +++ b/tests/auto/qml/parserstress/tests/ecma/ExecutionContexts/10.1.3-2.js diff --git a/tests/auto/qml/parserstress/tests/ecma/README b/tests/auto/qml/parserstress/tests/ecma/README index 91f174ab61..91f174ab61 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma/README +++ b/tests/auto/qml/parserstress/tests/ecma/README diff --git a/tests/auto/qml/parserstress/tests/ecma_2/README b/tests/auto/qml/parserstress/tests/ecma_2/README index 6da6cdd514..6da6cdd514 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_2/README +++ b/tests/auto/qml/parserstress/tests/ecma_2/README diff --git a/tests/auto/qml/parserstress/tests/ecma_2/extensions/constructor-001.js b/tests/auto/qml/parserstress/tests/ecma_2/extensions/constructor-001.js index cc7907d006..cc7907d006 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_2/extensions/constructor-001.js +++ b/tests/auto/qml/parserstress/tests/ecma_2/extensions/constructor-001.js diff --git a/tests/auto/qml/parserstress/tests/ecma_2/extensions/function-001.js b/tests/auto/qml/parserstress/tests/ecma_2/extensions/function-001.js index 5153d25f9d..5153d25f9d 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_2/extensions/function-001.js +++ b/tests/auto/qml/parserstress/tests/ecma_2/extensions/function-001.js diff --git a/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-001.js b/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-001.js index 8ea446a248..8ea446a248 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-001.js +++ b/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-001.js diff --git a/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-002.js b/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-002.js index 9cc837d8ef..9cc837d8ef 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-002.js +++ b/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-002.js diff --git a/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-003-n.js b/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-003-n.js index 7a763a895c..7a763a895c 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-003-n.js +++ b/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-003-n.js diff --git a/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-004-n.js b/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-004-n.js index 1662ae566b..1662ae566b 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-004-n.js +++ b/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-004-n.js diff --git a/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-005-n.js b/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-005-n.js index 1a9b1b3437..1a9b1b3437 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-005-n.js +++ b/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-005-n.js diff --git a/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-006.js b/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-006.js index 03c0f16fb9..03c0f16fb9 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-006.js +++ b/tests/auto/qml/parserstress/tests/ecma_2/extensions/instanceof-006.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Array/15.4.4.11-01.js b/tests/auto/qml/parserstress/tests/ecma_3/Array/15.4.4.11-01.js index 0436b8c1e0..0436b8c1e0 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Array/15.4.4.11-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Array/15.4.4.11-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Array/15.4.5.1-01.js b/tests/auto/qml/parserstress/tests/ecma_3/Array/15.4.5.1-01.js index b55430b44e..b55430b44e 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Array/15.4.5.1-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Array/15.4.5.1-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-01.js b/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-01.js index 4e277e6da5..4e277e6da5 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-02.js b/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-02.js index ee426a0cec..ee426a0cec 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-02.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-02.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-03.js b/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-03.js index 95ee7f7a92..95ee7f7a92 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-03.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-03.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-04.js b/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-04.js index fe9f8fc71e..fe9f8fc71e 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-04.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-322135-04.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-387501.js b/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-387501.js index 36cf1478d2..36cf1478d2 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-387501.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-387501.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-421325.js b/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-421325.js index c869d7bff4..c869d7bff4 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-421325.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-421325.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-430717.js b/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-430717.js index f750ffb449..f750ffb449 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-430717.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Array/regress-430717.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.1.2-01.js b/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.1.2-01.js index 61b1de6ef1..61b1de6ef1 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.1.2-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.1.2-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.3.2-1.js b/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.3.2-1.js index d79b60b996..d79b60b996 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.3.2-1.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.3.2-1.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.4.3.js b/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.4.3.js index b197dcb9c2..b197dcb9c2 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.4.3.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.4.3.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.5.5-02.js b/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.5.5-02.js index e3b073e7ec..e3b073e7ec 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.5.5-02.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Date/15.9.5.5-02.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/ExecutionContexts/10.6.1-01.js b/tests/auto/qml/parserstress/tests/ecma_3/ExecutionContexts/10.6.1-01.js index 6fbe85e19f..6fbe85e19f 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/ExecutionContexts/10.6.1-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/ExecutionContexts/10.6.1-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/ExecutionContexts/regress-448595-01.js b/tests/auto/qml/parserstress/tests/ecma_3/ExecutionContexts/regress-448595-01.js index f303199b51..f303199b51 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/ExecutionContexts/regress-448595-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/ExecutionContexts/regress-448595-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.10-01.js b/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.10-01.js index fd47d5d86b..fd47d5d86b 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.10-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.10-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.10-02.js b/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.10-02.js index 8f387c1349..8f387c1349 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.10-02.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.10-02.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.10-03.js b/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.10-03.js index 99af0f87c5..99af0f87c5 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.10-03.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.10-03.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.7.1-01.js b/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.7.1-01.js index 05f9622ce2..05f9622ce2 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.7.1-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.7.1-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.7.2-01.js b/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.7.2-01.js index 64e426888a..64e426888a 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.7.2-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.7.2-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.7.3-01.js b/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.7.3-01.js index d5af3b86d4..d5af3b86d4 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.7.3-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Expressions/11.7.3-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Function/arguments-002.js b/tests/auto/qml/parserstress/tests/ecma_3/Function/arguments-002.js index 78005560a7..78005560a7 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Function/arguments-002.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Function/arguments-002.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Function/regress-313570.js b/tests/auto/qml/parserstress/tests/ecma_3/Function/regress-313570.js index e159c4c87f..e159c4c87f 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Function/regress-313570.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Function/regress-313570.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/LexicalConventions/7.9.1.js b/tests/auto/qml/parserstress/tests/ecma_3/LexicalConventions/7.9.1.js index 10ee26f929..10ee26f929 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/LexicalConventions/7.9.1.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/LexicalConventions/7.9.1.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Number/regress-442242-01.js b/tests/auto/qml/parserstress/tests/ecma_3/Number/regress-442242-01.js index e3fa070e5a..e3fa070e5a 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Number/regress-442242-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Number/regress-442242-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Object/8.6.1-01.js b/tests/auto/qml/parserstress/tests/ecma_3/Object/8.6.1-01.js index 2897ece555..2897ece555 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Object/8.6.1-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Object/8.6.1-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Object/regress-361274.js b/tests/auto/qml/parserstress/tests/ecma_3/Object/regress-361274.js index d3962004e3..d3962004e3 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Object/regress-361274.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Object/regress-361274.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Object/regress-385393-07.js b/tests/auto/qml/parserstress/tests/ecma_3/Object/regress-385393-07.js index 0473fe4956..0473fe4956 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Object/regress-385393-07.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Object/regress-385393-07.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Operators/11.13.1-002.js b/tests/auto/qml/parserstress/tests/ecma_3/Operators/11.13.1-002.js index 5d3307e4a7..5d3307e4a7 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Operators/11.13.1-002.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Operators/11.13.1-002.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Operators/11.4.1-002.js b/tests/auto/qml/parserstress/tests/ecma_3/Operators/11.4.1-002.js index c48565ba5f..c48565ba5f 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Operators/11.4.1-002.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Operators/11.4.1-002.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Operators/order-01.js b/tests/auto/qml/parserstress/tests/ecma_3/Operators/order-01.js index 671faceb81..671faceb81 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Operators/order-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Operators/order-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/README b/tests/auto/qml/parserstress/tests/ecma_3/README index eebd421c2e..eebd421c2e 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/README +++ b/tests/auto/qml/parserstress/tests/ecma_3/README diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/15.10.2.12.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/15.10.2.12.js index d68b86c2ed..d68b86c2ed 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/15.10.2.12.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/15.10.2.12.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-285219.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-285219.js index 9d462359fa..9d462359fa 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-285219.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-285219.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-289669.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-289669.js index 2e3d044b74..2e3d044b74 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-289669.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-289669.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-307456.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-307456.js index dd2f540f6c..dd2f540f6c 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-307456.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-307456.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-309840.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-309840.js index 8680b7bcfd..8680b7bcfd 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-309840.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-309840.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-311414.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-311414.js index a24a07bb2b..a24a07bb2b 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-311414.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-311414.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-312351.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-312351.js index a9b00d317c..a9b00d317c 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-312351.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-312351.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-330684.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-330684.js index b097fbc3d7..b097fbc3d7 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-330684.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-330684.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-334158.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-334158.js index 41ebf0a731..41ebf0a731 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-334158.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-334158.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-346090.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-346090.js index dfd53a9922..dfd53a9922 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-346090.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-346090.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-367888.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-367888.js index 923c1e5ab3..923c1e5ab3 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-367888.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-367888.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375642.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375642.js index 236eb00d28..236eb00d28 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375642.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375642.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375711.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375711.js index 6e7339f9e9..6e7339f9e9 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375711.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375711.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-01-n.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-01-n.js index 437dcbd5c5..437dcbd5c5 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-01-n.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-01-n.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-02.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-02.js index 3cd858e845..3cd858e845 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-02.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-02.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-03.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-03.js index ffc5c5a4cc..ffc5c5a4cc 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-03.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-03.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-04.js b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-04.js index 0c78a372ee..0c78a372ee 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-04.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/RegExp/regress-375715-04.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-385393-04.js b/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-385393-04.js index 6e735fd1d2..6e735fd1d2 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-385393-04.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-385393-04.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-419152.js b/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-419152.js index f57f3a4f98..f57f3a4f98 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-419152.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-419152.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-420087.js b/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-420087.js index 1f21d19739..1f21d19739 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-420087.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-420087.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-420610.js b/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-420610.js index ecd5a2dd42..ecd5a2dd42 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-420610.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-420610.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-441477-01.js b/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-441477-01.js index 27ddfab51d..27ddfab51d 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-441477-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Regress/regress-441477-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Statements/12.6.3.js b/tests/auto/qml/parserstress/tests/ecma_3/Statements/12.6.3.js index 97c3ca3136..97c3ca3136 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Statements/12.6.3.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Statements/12.6.3.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Statements/regress-302439.js b/tests/auto/qml/parserstress/tests/ecma_3/Statements/regress-302439.js index e1ebdb6e30..e1ebdb6e30 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Statements/regress-302439.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Statements/regress-302439.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Statements/regress-324650.js b/tests/auto/qml/parserstress/tests/ecma_3/Statements/regress-324650.js index 003cd0fa42..003cd0fa42 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Statements/regress-324650.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Statements/regress-324650.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/String/regress-304376.js b/tests/auto/qml/parserstress/tests/ecma_3/String/regress-304376.js index 733cd713d8..733cd713d8 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/String/regress-304376.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/String/regress-304376.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/String/regress-313567.js b/tests/auto/qml/parserstress/tests/ecma_3/String/regress-313567.js index 9610238cc3..9610238cc3 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/String/regress-313567.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/String/regress-313567.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/String/regress-392378.js b/tests/auto/qml/parserstress/tests/ecma_3/String/regress-392378.js index 59564b272e..59564b272e 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/String/regress-392378.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/String/regress-392378.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/Unicode/regress-352044-01.js b/tests/auto/qml/parserstress/tests/ecma_3/Unicode/regress-352044-01.js index bb10ac6f7a..bb10ac6f7a 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/Unicode/regress-352044-01.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/Unicode/regress-352044-01.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/browser.js b/tests/auto/qml/parserstress/tests/ecma_3/browser.js index 2339522cb6..2339522cb6 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/browser.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/browser.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/extensions/10.1.3-2.js b/tests/auto/qml/parserstress/tests/ecma_3/extensions/10.1.3-2.js index f941cb7800..f941cb7800 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/extensions/10.1.3-2.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/extensions/10.1.3-2.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/extensions/7.9.1.js b/tests/auto/qml/parserstress/tests/ecma_3/extensions/7.9.1.js index b69e9d065a..b69e9d065a 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/extensions/7.9.1.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/extensions/7.9.1.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-274152.js b/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-274152.js index d7074d9128..d7074d9128 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-274152.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-274152.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-320854.js b/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-320854.js index 85e684882f..85e684882f 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-320854.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-320854.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-327170.js b/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-327170.js index 5d15ce31a9..5d15ce31a9 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-327170.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-327170.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-368516.js b/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-368516.js index a5f5fb769b..a5f5fb769b 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-368516.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-368516.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-385393-03.js b/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-385393-03.js index 40c7e8dd81..40c7e8dd81 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-385393-03.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-385393-03.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-429248.js b/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-429248.js index 9966269115..9966269115 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-429248.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-429248.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-430740.js b/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-430740.js index 446adb95a6..446adb95a6 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-430740.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/extensions/regress-430740.js diff --git a/tests/auto/qml/parserstress/tests/ecma_3/template.js b/tests/auto/qml/parserstress/tests/ecma_3/template.js index 4dedd5a0e3..4dedd5a0e3 100755..100644 --- a/tests/auto/qml/parserstress/tests/ecma_3/template.js +++ b/tests/auto/qml/parserstress/tests/ecma_3/template.js diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index 5a9d6d20eb..39bc8b2e5f 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -155,7 +155,7 @@ private slots: void callConstants(); - void installTranslatorFunctions(); + void installTranslationFunctions(); void translateScript_data(); void translateScript(); void translateScript_crossScript(); @@ -172,6 +172,16 @@ private slots: void translateScriptUnicodeIdBased(); void translateFromBuiltinCallback(); + void installConsoleFunctions(); + void logging(); + void tracing(); + void asserts(); + void exceptions(); + + void installGarbageCollectionFunctions(); + + void installAllExtensions(); + void privateMethods(); void engineForObject(); @@ -336,7 +346,7 @@ void tst_QJSEngine::constructWithParent() QJSEngine *engine = new QJSEngine(&obj); ptr = engine; } - QVERIFY(ptr == 0); + QVERIFY(ptr.isNull()); } void tst_QJSEngine::newObject() @@ -631,7 +641,7 @@ void tst_QJSEngine::newQObject_ownership() eng.collectGarbage(); if (ptr) QGuiApplication::sendPostedEvents(ptr, QEvent::DeferredDelete); - QVERIFY(ptr == 0); + QVERIFY(ptr.isNull()); } { QPointer<QObject> ptr = new QObject(this); @@ -641,7 +651,7 @@ void tst_QJSEngine::newQObject_ownership() } QObject *before = ptr; eng.collectGarbage(); - QVERIFY(ptr == before); + QCOMPARE(ptr.data(), before); delete ptr; } { @@ -662,7 +672,7 @@ void tst_QJSEngine::newQObject_ownership() // no parent, so it should be like ScriptOwnership if (ptr) QGuiApplication::sendPostedEvents(ptr, QEvent::DeferredDelete); - QVERIFY(ptr == 0); + QVERIFY(ptr.isNull()); } { QObject *parent = new QObject(); @@ -1258,7 +1268,7 @@ void tst_QJSEngine::valueConversion_QVariant() { QVariant tmp1; QVariant tmp2(QMetaType::QVariant, &tmp1); - QVERIFY(QMetaType::Type(tmp2.type()) == QMetaType::QVariant); + QCOMPARE(QMetaType::Type(tmp2.type()), QMetaType::QVariant); QJSValue val1 = eng.toScriptValue(tmp1); QJSValue val2 = eng.toScriptValue(tmp2); @@ -1273,9 +1283,9 @@ void tst_QJSEngine::valueConversion_QVariant() QVariant tmp1(123); QVariant tmp2(QMetaType::QVariant, &tmp1); QVariant tmp3(QMetaType::QVariant, &tmp2); - QVERIFY(QMetaType::Type(tmp1.type()) == QMetaType::Int); - QVERIFY(QMetaType::Type(tmp2.type()) == QMetaType::QVariant); - QVERIFY(QMetaType::Type(tmp3.type()) == QMetaType::QVariant); + QCOMPARE(QMetaType::Type(tmp1.type()), QMetaType::Int); + QCOMPARE(QMetaType::Type(tmp2.type()), QMetaType::QVariant); + QCOMPARE(QMetaType::Type(tmp3.type()), QMetaType::QVariant); QJSValue val1 = eng.toScriptValue(tmp2); QJSValue val2 = eng.toScriptValue(tmp3); @@ -1285,8 +1295,8 @@ void tst_QJSEngine::valueConversion_QVariant() QVERIFY(val1.isVariant()); QEXPECT_FAIL("", "Variant are unrwapped, maybe we should not...", Continue); QVERIFY(val2.isVariant()); - QVERIFY(val1.toVariant().toInt() == 123); - QVERIFY(eng.toScriptValue(val2.toVariant()).toVariant().toInt() == 123); + QCOMPARE(val1.toVariant().toInt(), 123); + QCOMPARE(eng.toScriptValue(val2.toVariant()).toVariant().toInt(), 123); } { QJSValue val = eng.toScriptValue(QVariant(true)); @@ -1472,7 +1482,7 @@ void tst_QJSEngine::collectGarbage() eng.collectGarbage(); if (ptr) QGuiApplication::sendPostedEvents(ptr, QEvent::DeferredDelete); - QVERIFY(ptr == 0); + QVERIFY(ptr.isNull()); } void tst_QJSEngine::gcWithNestedDataStructure() @@ -1480,6 +1490,8 @@ void tst_QJSEngine::gcWithNestedDataStructure() // The GC must be able to traverse deeply nested objects, otherwise this // test would crash. QJSEngine eng; + eng.installExtensions(QJSEngine::GarbageCollectionExtension); + QJSValue ret = eng.evaluate( "function makeList(size)" "{" @@ -3171,7 +3183,7 @@ void tst_QJSEngine::callConstants() QCOMPARE(exceptionResult.toString(), QString("TypeError: true is not a function")); } -void tst_QJSEngine::installTranslatorFunctions() +void tst_QJSEngine::installTranslationFunctions() { QJSEngine eng; QJSValue global = eng.globalObject(); @@ -3182,7 +3194,7 @@ void tst_QJSEngine::installTranslatorFunctions() QVERIFY(global.property("qsTrId").isUndefined()); QVERIFY(global.property("QT_TRID_NOOP").isUndefined()); - eng.installTranslatorFunctions(); + eng.installExtensions(QJSEngine::TranslationExtension); QVERIFY(global.property("qsTranslate").isCallable()); QVERIFY(global.property("QT_TRANSLATE_NOOP").isCallable()); QVERIFY(global.property("qsTr").isCallable()); @@ -3597,6 +3609,107 @@ void tst_QJSEngine::translateFromBuiltinCallback() eng.evaluate("[10,20].forEach(foo)", "script.js"); } +void tst_QJSEngine::installConsoleFunctions() +{ + QJSEngine engine; + QJSValue global = engine.globalObject(); + QVERIFY(global.property("console").isUndefined()); + QVERIFY(global.property("print").isUndefined()); + + engine.installExtensions(QJSEngine::ConsoleExtension); + QVERIFY(global.property("console").isObject()); + QVERIFY(global.property("print").isCallable()); +} + +void tst_QJSEngine::logging() +{ + QLoggingCategory loggingCategory("js"); + QVERIFY(loggingCategory.isDebugEnabled()); + QVERIFY(loggingCategory.isWarningEnabled()); + QVERIFY(loggingCategory.isCriticalEnabled()); + + QJSEngine engine; + engine.installExtensions(QJSEngine::ConsoleExtension); + + QTest::ignoreMessage(QtDebugMsg, "console.debug"); + engine.evaluate("console.debug('console.debug')"); + QTest::ignoreMessage(QtDebugMsg, "console.log"); + engine.evaluate("console.log('console.log')"); + QTest::ignoreMessage(QtInfoMsg, "console.info"); + engine.evaluate("console.info('console.info')"); + QTest::ignoreMessage(QtWarningMsg, "console.warn"); + engine.evaluate("console.warn('console.warn')"); + QTest::ignoreMessage(QtCriticalMsg, "console.error"); + engine.evaluate("console.error('console.error')"); + + QTest::ignoreMessage(QtDebugMsg, ": 1"); + engine.evaluate("console.count()"); + + QTest::ignoreMessage(QtDebugMsg, ": 2"); + engine.evaluate("console.count()"); +} + +void tst_QJSEngine::tracing() +{ + QJSEngine engine; + engine.installExtensions(QJSEngine::ConsoleExtension); + + QTest::ignoreMessage(QtDebugMsg, "%entry (:1)"); + engine.evaluate("console.trace()"); + + QTest::ignoreMessage(QtDebugMsg, "a (:1)\nb (:1)\nc (:1)\n%entry (:1)"); + engine.evaluate("function a() { console.trace(); } function b() { a(); } function c() { b(); }"); + engine.evaluate("c()"); +} + +void tst_QJSEngine::asserts() +{ + QJSEngine engine; + engine.installExtensions(QJSEngine::ConsoleExtension); + + QTest::ignoreMessage(QtCriticalMsg, "This will fail\n%entry (:1)"); + engine.evaluate("console.assert(0, 'This will fail')"); + + QTest::ignoreMessage(QtCriticalMsg, "This will fail too\n%entry (:1)"); + engine.evaluate("console.assert(1 > 2, 'This will fail too')"); +} + +void tst_QJSEngine::exceptions() +{ + QJSEngine engine; + engine.installExtensions(QJSEngine::ConsoleExtension); + + QTest::ignoreMessage(QtCriticalMsg, "Exception 1\n%entry (:1)"); + engine.evaluate("console.exception('Exception 1')"); +} + +void tst_QJSEngine::installGarbageCollectionFunctions() +{ + QJSEngine engine; + QJSValue global = engine.globalObject(); + QVERIFY(global.property("gc").isUndefined()); + + engine.installExtensions(QJSEngine::GarbageCollectionExtension); + QVERIFY(global.property("gc").isCallable()); +} + +void tst_QJSEngine::installAllExtensions() +{ + QJSEngine engine; + QJSValue global = engine.globalObject(); + // Pick out a few properties from each extension and check that they're there. + QVERIFY(global.property("qsTranslate").isUndefined()); + QVERIFY(global.property("console").isUndefined()); + QVERIFY(global.property("print").isUndefined()); + QVERIFY(global.property("gc").isUndefined()); + + engine.installExtensions(QJSEngine::AllExtensions); + QVERIFY(global.property("qsTranslate").isCallable()); + QVERIFY(global.property("console").isObject()); + QVERIFY(global.property("print").isCallable()); + QVERIFY(global.property("gc").isCallable()); +} + class ObjectWithPrivateMethods : public QObject { Q_OBJECT diff --git a/tests/auto/qml/qjsonbinding/tst_qjsonbinding.cpp b/tests/auto/qml/qjsonbinding/tst_qjsonbinding.cpp index e01ea73e1b..52d676ef3c 100644 --- a/tests/auto/qml/qjsonbinding/tst_qjsonbinding.cpp +++ b/tests/auto/qml/qjsonbinding/tst_qjsonbinding.cpp @@ -110,7 +110,7 @@ QJsonValue tst_qjsonbinding::valueFromJson(const QByteArray &json) // QJsonDocument::fromJson() only handles objects and arrays... // Wrap the JSON inside a dummy object and extract the value. - QByteArray wrappedJson = "{\"prop\":" + json + "}"; + QByteArray wrappedJson = "{\"prop\":" + json + '}'; doc = QJsonDocument::fromJson(wrappedJson); Q_ASSERT(doc.isObject()); return doc.object().value("prop"); diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp index d608379d52..bf9bd18807 100644 --- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp +++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp @@ -1076,7 +1076,7 @@ void tst_QJSValue::toVariant() QVariantList listOut = ret.toList(); QCOMPARE(listOut.size(), listIn.size()); for (int i = 0; i < listIn.size(); ++i) - QVERIFY(listOut.at(i) == listIn.at(i)); + QCOMPARE(listOut.at(i), listIn.at(i)); // round-trip conversion QJSValue array2 = eng.toScriptValue(ret); QVERIFY(array2.isArray()); @@ -2261,7 +2261,7 @@ void tst_QJSValue::castToPointer() QCOMPARE(*cp, c); QBrush *bp = qjsvalue_cast<QBrush*>(v); - QVERIFY(bp == 0); + QVERIFY(!bp); QJSValue v2 = eng.toScriptValue(qVariantFromValue(cp)); QCOMPARE(qjsvalue_cast<QColor*>(v2), cp); @@ -2436,7 +2436,7 @@ void tst_QJSValue::prettyPrinter() QFETCH(QString, function); QFETCH(QString, expected); QJSEngine eng; - QJSValue val = eng.evaluate("(" + function + ")"); + QJSValue val = eng.evaluate(QLatin1Char('(') + function + QLatin1Char(')')); QVERIFY(val.isCallable()); QString actual = val.toString(); QSKIP("Function::toString() doesn't give the whole function on v4"); @@ -2465,15 +2465,15 @@ void tst_QJSValue::engineDeleted() delete eng; QVERIFY(v1.isUndefined()); - QVERIFY(v1.engine() == 0); + QVERIFY(!v1.engine()); QVERIFY(v2.isUndefined()); - QVERIFY(v2.engine() == 0); + QVERIFY(!v2.engine()); QVERIFY(v3.isUndefined()); - QVERIFY(v3.engine() == 0); + QVERIFY(!v3.engine()); QVERIFY(v4.isUndefined()); - QVERIFY(v4.engine() == 0); + QVERIFY(!v4.engine()); QVERIFY(v5.isString()); // was not bound to engine - QVERIFY(v5.engine() == 0); + QVERIFY(!v5.engine()); QVERIFY(v3.property("foo").isUndefined()); } diff --git a/tests/auto/qml/qjsvalueiterator/tst_qjsvalueiterator.cpp b/tests/auto/qml/qjsvalueiterator/tst_qjsvalueiterator.cpp index 6049e423e8..81a79331c3 100644 --- a/tests/auto/qml/qjsvalueiterator/tst_qjsvalueiterator.cpp +++ b/tests/auto/qml/qjsvalueiterator/tst_qjsvalueiterator.cpp @@ -92,7 +92,7 @@ void tst_QJSValueIterator::iterateForward() QFETCH(QStringList, propertyNames); QFETCH(QStringList, propertyValues); QMap<QString, QString> pmap; - QVERIFY(propertyNames.size() == propertyValues.size()); + QCOMPARE(propertyNames.size(), propertyValues.size()); QJSEngine engine; QJSValue object = engine.newObject(); diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro index 5d58beea1e..66c19098ef 100644 --- a/tests/auto/qml/qml.pro +++ b/tests/auto/qml/qml.pro @@ -37,6 +37,7 @@ PRIVATETESTS += \ qqmldirparser \ qqmlglobal \ qqmllanguage \ + qqmlopenmetaobject \ qqmlproperty \ qqmlpropertycache \ qqmlpropertymap \ @@ -60,7 +61,8 @@ PRIVATETESTS += \ qqmlenginecleanup \ v4misc \ qqmltranslation \ - qqmlimport + qqmlimport \ + qqmlobjectmodel qtHaveModule(widgets) { PUBLICTESTS += \ @@ -70,7 +72,10 @@ qtHaveModule(widgets) { SUBDIRS += $$PUBLICTESTS SUBDIRS += $$METATYPETESTS -!winrt: SUBDIRS += debugger qmllint # no QProcess on winrt +!winrt { # no QProcess on winrt + !contains(QT_CONFIG, no-qml-debug): SUBDIRS += debugger + SUBDIRS += qmllint +} contains(QT_CONFIG, private_tests) { SUBDIRS += $$PRIVATETESTS diff --git a/tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/Singleton.qml b/tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/Singleton.qml new file mode 100644 index 0000000000..b47d2e98f4 --- /dev/null +++ b/tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/Singleton.qml @@ -0,0 +1,6 @@ +pragma Singleton +import QtQuick 2.0 + +QtObject { + property int test: 0 +} diff --git a/tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/qmldir b/tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/qmldir new file mode 100644 index 0000000000..8df57f6d47 --- /dev/null +++ b/tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/qmldir @@ -0,0 +1,3 @@ +module tests.dumper.CompositeSingleton +singleton Singleton 1.0 Singleton.qml +depends QtQuick 2.0 diff --git a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp index 2a534b5913..82506b4217 100644 --- a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp +++ b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp @@ -47,6 +47,7 @@ public: private slots: void initTestCase(); void builtins(); + void singleton(); private: QString qmlplugindumpPath; @@ -84,7 +85,7 @@ void tst_qmlplugindump::builtins() if (dumper.error() != QProcess::UnknownError || dumper.exitStatus() != QProcess::NormalExit) { qWarning() << QString("Error while running '%1 %2'").arg( - qmlplugindumpPath, args.join(QLatin1String(" "))); + qmlplugindumpPath, args.join(QLatin1Char(' '))); } if (dumper.error() == QProcess::FailedToStart) { @@ -102,6 +103,20 @@ void tst_qmlplugindump::builtins() QVERIFY(result.contains(QLatin1String("Module {"))); } +void tst_qmlplugindump::singleton() +{ + QProcess dumper; + QStringList args; + args << QLatin1String("tests.dumper.CompositeSingleton") << QLatin1String("1.0") + << QLatin1String("."); + dumper.start(qmlplugindumpPath, args); + dumper.waitForFinished(); + + const QString &result = dumper.readAllStandardOutput(); + QVERIFY(result.contains(QLatin1String("exports: [\"Singleton 1.0\"]"))); + QVERIFY(result.contains(QLatin1String("exportMetaObjectRevisions: [0]"))); +} + QTEST_MAIN(tst_qmlplugindump) #include "tst_qmlplugindump.moc" diff --git a/tests/auto/qml/qqmlbinding/data/readonlyProperty.qml b/tests/auto/qml/qqmlbinding/data/readonlyProperty.qml new file mode 100644 index 0000000000..fa8d93d355 --- /dev/null +++ b/tests/auto/qml/qqmlbinding/data/readonlyProperty.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +Item { + id: root + + readonly property string name: "John" + + Binding { + target: root + property: "name" + value: "Doe" + } +} diff --git a/tests/auto/qml/qqmlbinding/data/unknownProperty.qml b/tests/auto/qml/qqmlbinding/data/unknownProperty.qml new file mode 100644 index 0000000000..36157bb4e7 --- /dev/null +++ b/tests/auto/qml/qqmlbinding/data/unknownProperty.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Item { + id: root + + Binding { + target: root + property: "unknown" + value: 42 + } +} diff --git a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp index 2d267cc668..3e49f3b3c4 100644 --- a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp +++ b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp @@ -50,6 +50,8 @@ private slots: void restoreBindingWithLoop(); void restoreBindingWithoutCrash(); void deletedObject(); + void warningOnUnknownProperty(); + void warningOnReadOnlyProperty(); private: QQmlEngine engine; @@ -224,6 +226,38 @@ void tst_qqmlbinding::deletedObject() delete rect; } +void tst_qqmlbinding::warningOnUnknownProperty() +{ + QQmlTestMessageHandler messageHandler; + + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("unknownProperty.qml")); + QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); + QVERIFY(item); + delete item; + + QCOMPARE(messageHandler.messages().count(), 1); + + const QString expectedMessage = c.url().toString() + QLatin1String(":6:5: QML Binding: Property 'unknown' does not exist on Item."); + QCOMPARE(messageHandler.messages().first(), expectedMessage); +} + +void tst_qqmlbinding::warningOnReadOnlyProperty() +{ + QQmlTestMessageHandler messageHandler; + + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("readonlyProperty.qml")); + QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); + QVERIFY(item); + delete item; + + QCOMPARE(messageHandler.messages().count(), 1); + + const QString expectedMessage = c.url().toString() + QLatin1String(":8:5: QML Binding: Property 'name' on Item is read-only."); + QCOMPARE(messageHandler.messages().first(), expectedMessage); +} + QTEST_MAIN(tst_qqmlbinding) #include "tst_qqmlbinding.moc" diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp index bb159d5931..85579a6019 100644 --- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp +++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp @@ -110,6 +110,7 @@ private slots: void qmlCreateParentReference(); void async(); void asyncHierarchy(); + void asyncForceSync(); void componentUrlCanonicalization(); void onDestructionLookup(); void onDestructionCount(); @@ -157,7 +158,7 @@ void tst_qqmlcomponent::qmlIncubateObject() QCOMPARE(object->property("test1").toBool(), true); QCOMPARE(object->property("test2").toBool(), false); - QTRY_VERIFY(object->property("test2").toBool() == true); + QTRY_VERIFY(object->property("test2").toBool()); delete object; } @@ -250,7 +251,7 @@ void tst_qqmlcomponent::qmlCreateObjectWithProperties() QObject *testObject1 = object->property("declarativerectangle").value<QObject*>(); QVERIFY(testObject1); - QVERIFY(testObject1->parent() == object); + QCOMPARE(testObject1->parent(), object); QCOMPARE(testObject1->property("x").value<int>(), 17); QCOMPARE(testObject1->property("y").value<int>(), 17); QCOMPARE(testObject1->property("color").value<QColor>(), QColor(255,255,255)); @@ -260,7 +261,7 @@ void tst_qqmlcomponent::qmlCreateObjectWithProperties() QObject *testObject2 = object->property("declarativeitem").value<QObject*>(); QVERIFY(testObject2); - QVERIFY(testObject2->parent() == object); + QCOMPARE(testObject2->parent(), object); //QCOMPARE(testObject2->metaObject()->className(), "QDeclarativeItem_QML_2"); QCOMPARE(testObject2->property("x").value<int>(), 17); QCOMPARE(testObject2->property("y").value<int>(), 17); @@ -371,6 +372,35 @@ void tst_qqmlcomponent::asyncHierarchy() delete root; } +void tst_qqmlcomponent::asyncForceSync() +{ + { + // 1) make sure that HTTP URLs cannot be completed synchronously + TestHTTPServer server; + QVERIFY2(server.listen(), qPrintable(server.errorString())); + server.serveDirectory(dataDirectory()); + + // ensure that the item hierarchy is compiled correctly. + QQmlComponent component(&engine); + component.loadUrl(server.url("/TestComponent.2.qml"), QQmlComponent::Asynchronous); + QCOMPARE(component.status(), QQmlComponent::Loading); + QQmlComponent component2(&engine, server.url("/TestComponent.2.qml"), QQmlComponent::PreferSynchronous); + QCOMPARE(component2.status(), QQmlComponent::Loading); + } + { + // 2) make sure that file:// URL can be completed synchronously + + // ensure that the item hierarchy is compiled correctly. + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("/TestComponent.2.qml"), QQmlComponent::Asynchronous); + QCOMPARE(component.status(), QQmlComponent::Loading); + QQmlComponent component2(&engine, testFileUrl("/TestComponent.2.qml"), QQmlComponent::PreferSynchronous); + QCOMPARE(component2.status(), QQmlComponent::Ready); + QCOMPARE(component.status(), QQmlComponent::Loading); + QTRY_COMPARE_WITH_TIMEOUT(component.status(), QQmlComponent::Ready, 0); + } +} + void tst_qqmlcomponent::componentUrlCanonicalization() { // ensure that url canonicalization succeeds so that type information @@ -418,7 +448,7 @@ void tst_qqmlcomponent::componentUrlCanonicalization() QQmlComponent component(&engine, testFileUrl("componentUrlCanonicalization.5.qml")); QTest::ignoreMessage(QtWarningMsg, QLatin1String("QQmlComponent: Component is not ready").data()); QScopedPointer<QObject> object(component.create()); - QVERIFY(object == 0); + QVERIFY(object.isNull()); } } diff --git a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp index 45393bf2f0..e529c74acc 100644 --- a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp +++ b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp @@ -72,7 +72,7 @@ void tst_qqmlconnections::defaultValues() QQmlConnections *item = qobject_cast<QQmlConnections*>(c.create()); QVERIFY(item != 0); - QVERIFY(item->target() == 0); + QVERIFY(!item->target()); delete item; } @@ -86,7 +86,7 @@ void tst_qqmlconnections::properties() QVERIFY(item != 0); QVERIFY(item != 0); - QVERIFY(item->target() == item); + QCOMPARE(item->target(), item); delete item; } @@ -146,7 +146,7 @@ void tst_qqmlconnections::targetChanged() QQuickItem *item2 = item->findChild<QQuickItem*>("item2"); QVERIFY(item2); - QVERIFY(connections->target() == item2); + QCOMPARE(connections->target(), item2); // If we don't crash then we're OK @@ -211,9 +211,9 @@ void tst_qqmlconnections::errors() QQmlEngine engine; QQmlComponent c(&engine, url); - QVERIFY(c.isError() == true); + QVERIFY(c.isError()); QList<QQmlError> errors = c.errors(); - QVERIFY(errors.count() == 1); + QCOMPARE(errors.count(), 1); QCOMPARE(errors.at(0).description(), error); } diff --git a/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp b/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp index 1ee675a91d..98e3a53b81 100644 --- a/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp +++ b/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp @@ -47,7 +47,7 @@ private slots: void logging(); void tracing(); void profiling(); - void assert(); + void testAssert(); void exception(); private: @@ -122,7 +122,7 @@ void tst_qqmlconsole::profiling() delete object; } -void tst_qqmlconsole::assert() +void tst_qqmlconsole::testAssert() { QUrl testUrl = testFileUrl("assert.qml"); diff --git a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp index 1bd070c2d0..18ef7ac31d 100644 --- a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp +++ b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp @@ -433,12 +433,12 @@ void tst_qqmlcontext::idAsContextProperty() QVERIFY(obj); QVariant a = obj->property("a"); - QVERIFY(a.userType() == QMetaType::QObjectStar); + QCOMPARE(a.userType(), int(QMetaType::QObjectStar)); QVariant ctxt = qmlContext(obj)->contextProperty("myObject"); - QVERIFY(ctxt.userType() == QMetaType::QObjectStar); + QCOMPARE(ctxt.userType(), int(QMetaType::QObjectStar)); - QVERIFY(a == ctxt); + QCOMPARE(a, ctxt); delete obj; } @@ -455,20 +455,20 @@ void tst_qqmlcontext::readOnlyContexts() QQmlContext *context = qmlContext(obj); QVERIFY(context); - QVERIFY(qvariant_cast<QObject*>(context->contextProperty("me")) == obj); - QVERIFY(context->contextObject() == obj); + QCOMPARE(qvariant_cast<QObject*>(context->contextProperty("me")), obj); + QCOMPARE(context->contextObject(), obj); QTest::ignoreMessage(QtWarningMsg, "QQmlContext: Cannot set property on internal context."); context->setContextProperty("hello", 12); - QVERIFY(context->contextProperty("hello") == QVariant()); + QCOMPARE(context->contextProperty("hello"), QVariant()); QTest::ignoreMessage(QtWarningMsg, "QQmlContext: Cannot set property on internal context."); context->setContextProperty("hello", obj); - QVERIFY(context->contextProperty("hello") == QVariant()); + QCOMPARE(context->contextProperty("hello"), QVariant()); QTest::ignoreMessage(QtWarningMsg, "QQmlContext: Cannot set context object for internal context."); context->setContextObject(0); - QVERIFY(context->contextObject() == obj); + QCOMPARE(context->contextObject(), obj); delete obj; } diff --git a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp index 6b2add309a..6f2febaccf 100644 --- a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp +++ b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp @@ -73,7 +73,7 @@ namespace { QString toString(const QQmlDirParser::Plugin &p) { - return p.name + "|" + p.path; + return p.name + QLatin1Char('|') + p.path; } QStringList toStringList(const QList<QQmlDirParser::Plugin> &plugins) @@ -88,7 +88,9 @@ namespace { QString toString(const QQmlDirParser::Component &c) { - return c.typeName + "|" + c.fileName + "|" + QString::number(c.majorVersion) + "|" + QString::number(c.minorVersion) + "|" + (c.internal ? "true" : "false"); + return c.typeName + QLatin1Char('|') + c.fileName + QLatin1Char('|') + + QString::number(c.majorVersion) + QLatin1Char('|') + QString::number(c.minorVersion) + + QLatin1Char('|') + (c.internal ? "true" : "false"); } QStringList toStringList(const QQmlDirComponents &components) @@ -104,7 +106,8 @@ namespace { QString toString(const QQmlDirParser::Script &s) { - return s.nameSpace + "|" + s.fileName + "|" + QString::number(s.majorVersion) + "|" + QString::number(s.minorVersion); + return s.nameSpace + QLatin1Char('|') + s.fileName + QLatin1Char('|') + + QString::number(s.majorVersion) + '|' + QString::number(s.minorVersion); } QStringList toStringList(const QList<QQmlDirParser::Script> &scripts) diff --git a/tests/auto/qml/qqmlecmascript/data/qtbug_46022.js b/tests/auto/qml/qqmlecmascript/data/qtbug_46022.js new file mode 100644 index 0000000000..385d7f9e97 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/qtbug_46022.js @@ -0,0 +1,21 @@ +var obj = {} +obj[5289] = 0 +obj[5290] = 0 +obj[5288] = 0 +obj[5287] = 0 +delete obj[5288] + +var a = Object.getOwnPropertyNames(obj) +var test1 = a.every(function(key) { + return obj.hasOwnProperty(key) +}) + +obj = {} +obj[8187] = 0 +obj[8188] = 0 +delete obj[8187] + +var b = Object.getOwnPropertyNames(obj) +var test2 = b.every(function(key) { + return obj.hasOwnProperty(key) +}) diff --git a/tests/auto/qml/qqmlecmascript/data/qtbug_46022.qml b/tests/auto/qml/qqmlecmascript/data/qtbug_46022.qml new file mode 100644 index 0000000000..2d2375de3e --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/qtbug_46022.qml @@ -0,0 +1,7 @@ +import "qtbug_46022.js" as Test +import QtQuick 2.0 + +QtObject { + property bool test1: Test.test1 + property bool test2: Test.test2 +} diff --git a/tests/auto/qml/qqmlecmascript/data/singletonTest.qml b/tests/auto/qml/qqmlecmascript/data/singletonTest.qml index 9e41bd4e2c..ca3784322a 100644 --- a/tests/auto/qml/qqmlecmascript/data/singletonTest.qml +++ b/tests/auto/qml/qqmlecmascript/data/singletonTest.qml @@ -45,4 +45,5 @@ Item { property bool qobjectTest: MyInheritedQmlObjectSingleton.isItYouQObject(MyInheritedQmlObjectSingleton) property bool myQmlObjectTest: MyInheritedQmlObjectSingleton.isItYouMyQmlObject(MyInheritedQmlObjectSingleton) property bool myInheritedQmlObjectTest: MyInheritedQmlObjectSingleton.isItYouMyInheritedQmlObject(MyInheritedQmlObjectSingleton) + property int testFoo: TestTypeCppSingleton.foo } diff --git a/tests/auto/qml/qqmlecmascript/data/singletonTest2.qml b/tests/auto/qml/qqmlecmascript/data/singletonTest2.qml index 67654dd81f..ef08745812 100644 --- a/tests/auto/qml/qqmlecmascript/data/singletonTest2.qml +++ b/tests/auto/qml/qqmlecmascript/data/singletonTest2.qml @@ -52,6 +52,7 @@ Item { property bool qobjectTest2: false property bool qobjectTest3: false property bool singletonEqualToItself: true + property int testFoo: -1 Component.onCompleted: { MyInheritedQmlObjectSingleton.myInheritedQmlObjectProperty = MyInheritedQmlObjectSingleton; @@ -70,5 +71,6 @@ Item { qobjectTest3 = MyInheritedQmlObjectSingleton == MyInheritedQmlObjectSingleton.qobjectProperty; singletonEqualToItself = MyInheritedQmlObjectSingleton == MyInheritedQmlObjectSingleton; + testFoo = TestTypeCppSingleton.foo } } diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp index edfd97b750..285158a4ea 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.cpp +++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp @@ -325,6 +325,38 @@ bool MyInheritedQmlObject::isItYouMyInheritedQmlObject(MyInheritedQmlObject *o) return o && o == theSingletonObject; } +class TestTypeCppSingleton : public QObject +{ + Q_OBJECT + Q_PROPERTY(int foo READ foo) + + Q_CLASSINFO("DefaultProperty", "foo") +public: + int foo() { return 0; } + static TestTypeCppSingleton *instance() { + static TestTypeCppSingleton cppSingleton; + return &cppSingleton; + } +private: + TestTypeCppSingleton(){} + ~TestTypeCppSingleton() { + // just to make sure it crashes on double delete + static int a = 0; + static int *ptr = &a; + *ptr = 1; + ptr = 0; + } +}; + +QObject *testTypeCppProvider(QQmlEngine *engine, QJSEngine *scriptEngine) +{ + Q_UNUSED(engine); + Q_UNUSED(scriptEngine); + TestTypeCppSingleton *o = TestTypeCppSingleton::instance(); + QQmlEngine::setObjectOwnership(o, QQmlEngine::CppOwnership); + return o; +} + static QObject *create_singletonWithEnum(QQmlEngine *, QJSEngine *) { return new SingletonWithEnum; @@ -391,6 +423,7 @@ void registerTypes() qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObjectAlias"); qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObject"); qmlRegisterSingletonType<MyInheritedQmlObject>("Test", 1, 0, "MyInheritedQmlObjectSingleton", inheritedQmlObject_provider); + qmlRegisterSingletonType<TestTypeCppSingleton>("Test", 1, 0, "TestTypeCppSingleton", testTypeCppProvider); qmlRegisterType<MyDeferredObject>("Qt.test", 1,0, "MyDeferredObject"); qmlRegisterType<MyVeryDeferredObject>("Qt.test", 1,0, "MyVeryDeferredObject"); qmlRegisterType<MyQmlContainer>("Qt.test", 1,0, "MyQmlContainer"); diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h index bbccf7b94b..eb4a3147d3 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.h +++ b/tests/auto/qml/qqmlecmascript/testtypes.h @@ -1253,7 +1253,7 @@ public: Q_INVOKABLE void addReference(QObject *other) { QQmlData *ddata = QQmlData::get(this); - assert(ddata); + Q_ASSERT(ddata); QV4::ExecutionEngine *v4 = ddata->jsWrapper.engine(); Q_ASSERT(v4); QV4::Scope scope(v4); diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index eb25eb70f4..b30dfcbd0b 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -326,6 +326,7 @@ private slots: void readUnregisteredQObjectProperty(); void writeUnregisteredQObjectProperty(); void switchExpression(); + void qtbug_46022(); private: // static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter); @@ -521,7 +522,7 @@ void tst_qqmlecmascript::idShortcutInvalidates() QVERIFY(object != 0); QVERIFY(object->objectProperty() != 0); delete object->objectProperty(); - QVERIFY(object->objectProperty() == 0); + QVERIFY(!object->objectProperty()); delete object; } @@ -531,7 +532,7 @@ void tst_qqmlecmascript::idShortcutInvalidates() QVERIFY(object != 0); QVERIFY(object->objectProperty() != 0); delete object->objectProperty(); - QVERIFY(object->objectProperty() == 0); + QVERIFY(!object->objectProperty()); delete object; } } @@ -885,7 +886,7 @@ void tst_qqmlecmascript::deferredProperties() qobject_cast<MyDeferredObject *>(component.create()); QVERIFY(object != 0); QCOMPARE(object->value(), 0); - QVERIFY(object->objectProperty() == 0); + QVERIFY(!object->objectProperty()); QVERIFY(object->objectProperty2() != 0); qmlExecuteDeferred(object); QCOMPARE(object->value(), 10); @@ -908,8 +909,8 @@ void tst_qqmlecmascript::deferredPropertiesErrors() qobject_cast<MyDeferredObject *>(component.create()); QVERIFY(object != 0); QCOMPARE(object->value(), 0); - QVERIFY(object->objectProperty() == 0); - QVERIFY(object->objectProperty2() == 0); + QVERIFY(!object->objectProperty()); + QVERIFY(!object->objectProperty2()); QString warning = component.url().toString() + ":6:21: Unable to assign [undefined] to QObject*"; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); @@ -932,7 +933,7 @@ void tst_qqmlecmascript::deferredPropertiesInComponents() MyDeferredObject *defObjectA = qobject_cast<MyDeferredObject *>(object->property("deferredInside").value<QObject*>()); QVERIFY(defObjectA != 0); - QVERIFY(defObjectA->objectProperty() == 0); + QVERIFY(!defObjectA->objectProperty()); qmlExecuteDeferred(defObjectA); QVERIFY(defObjectA->objectProperty() != 0); @@ -941,7 +942,7 @@ void tst_qqmlecmascript::deferredPropertiesInComponents() MyDeferredObject *defObjectB = qobject_cast<MyDeferredObject *>(object->property("deferredOutside").value<QObject*>()); QVERIFY(defObjectB != 0); - QVERIFY(defObjectB->objectProperty() == 0); + QVERIFY(!defObjectB->objectProperty()); qmlExecuteDeferred(defObjectB); QVERIFY(defObjectB->objectProperty() != 0); @@ -995,7 +996,7 @@ void tst_qqmlecmascript::overrideExtensionProperties() qobject_cast<OverrideDefaultPropertyObject *>(component.create()); QVERIFY(object != 0); QVERIFY(object->secondProperty() != 0); - QVERIFY(object->firstProperty() == 0); + QVERIFY(!object->firstProperty()); delete object; } @@ -1459,7 +1460,7 @@ void tst_qqmlecmascript::aliasPropertyReset() QVERIFY(object->property("sourceComponentAlias").value<QQmlComponent*>() != 0); QCOMPARE(object->property("aliasIsUndefined"), QVariant(false)); QMetaObject::invokeMethod(object, "resetAliased"); - QVERIFY(object->property("sourceComponentAlias").value<QQmlComponent*>() == 0); + QVERIFY(!object->property("sourceComponentAlias").value<QQmlComponent*>()); QCOMPARE(object->property("aliasIsUndefined"), QVariant(true)); delete object; @@ -1470,7 +1471,7 @@ void tst_qqmlecmascript::aliasPropertyReset() QVERIFY(object->property("sourceComponentAlias").value<QQmlComponent*>() != 0); QCOMPARE(object->property("loaderSourceComponentIsUndefined"), QVariant(false)); QMetaObject::invokeMethod(object, "resetAlias"); - QVERIFY(object->property("sourceComponentAlias").value<QQmlComponent*>() == 0); + QVERIFY(!object->property("sourceComponentAlias").value<QQmlComponent*>()); QCOMPARE(object->property("loaderSourceComponentIsUndefined"), QVariant(true)); delete object; @@ -1482,7 +1483,7 @@ void tst_qqmlecmascript::aliasPropertyReset() QCOMPARE(object->property("loaderOneSourceComponentIsUndefined"), QVariant(false)); QCOMPARE(object->property("loaderTwoSourceComponentIsUndefined"), QVariant(false)); QMetaObject::invokeMethod(object, "resetAlias"); - QVERIFY(object->property("sourceComponentAlias").value<QQmlComponent*>() == 0); + QVERIFY(!object->property("sourceComponentAlias").value<QQmlComponent*>()); QCOMPARE(object->property("loaderOneSourceComponentIsUndefined"), QVariant(true)); QCOMPARE(object->property("loaderTwoSourceComponentIsUndefined"), QVariant(false)); delete object; @@ -1498,9 +1499,9 @@ void tst_qqmlecmascript::aliasPropertyReset() delete loader; QVERIFY(object->property("sourceComponentAlias").value<QQmlComponent*>() == 0); // deletion should have caused value unset. QMetaObject::invokeMethod(object, "resetAlias"); // shouldn't crash. - QVERIFY(object->property("sourceComponentAlias").value<QQmlComponent*>() == 0); + QVERIFY(!object->property("sourceComponentAlias").value<QQmlComponent*>()); QMetaObject::invokeMethod(object, "setAlias"); // shouldn't crash, and shouldn't change value (since it's no longer referencing anything). - QVERIFY(object->property("sourceComponentAlias").value<QQmlComponent*>() == 0); + QVERIFY(!object->property("sourceComponentAlias").value<QQmlComponent*>()); delete object; // test that binding an alias property to an undefined value works correctly @@ -1680,7 +1681,7 @@ void tst_qqmlecmascript::dynamicDestruction() QObject *o = component.create(); QVERIFY(o != 0); - QVERIFY(qvariant_cast<QObject*>(o->property("objectProperty")) == 0); + QVERIFY(!qvariant_cast<QObject*>(o->property("objectProperty"))); QMetaObject::invokeMethod(o, "create"); @@ -1691,7 +1692,7 @@ void tst_qqmlecmascript::dynamicDestruction() QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); QCoreApplication::processEvents(); - QVERIFY(qvariant_cast<QObject*>(o->property("objectProperty")) == 0); + QVERIFY(!qvariant_cast<QObject*>(o->property("objectProperty"))); delete o; } @@ -1702,19 +1703,19 @@ void tst_qqmlecmascript::dynamicDestruction() QQmlComponent component(&engine, testFileUrl("dynamicDeletion.3.qml")); QObject *o = component.create(); QVERIFY(o != 0); - QVERIFY(qvariant_cast<QObject*>(o->property("objectProperty")) == 0); + QVERIFY(!qvariant_cast<QObject*>(o->property("objectProperty"))); QMetaObject::invokeMethod(o, "create"); createdQmlObject = qvariant_cast<QObject*>(o->property("objectProperty")); QVERIFY(createdQmlObject); QMetaObject::invokeMethod(o, "destroy"); - QVERIFY(qvariant_cast<bool>(o->property("test")) == false); + QCOMPARE(qvariant_cast<bool>(o->property("test")), false); for (int ii = 0; createdQmlObject && ii < 50; ++ii) { // After 5 seconds we should give up QTest::qWait(100); QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); QCoreApplication::processEvents(); } - QVERIFY(qvariant_cast<QObject*>(o->property("objectProperty")) == 0); - QVERIFY(qvariant_cast<bool>(o->property("test")) == true); + QVERIFY(!qvariant_cast<QObject*>(o->property("objectProperty"))); + QCOMPARE(qvariant_cast<bool>(o->property("test")), true); delete o; } } @@ -1750,9 +1751,9 @@ void tst_qqmlecmascript::objectHasOwnProperty() // test QObjects in QML QMetaObject::invokeMethod(object, "testHasOwnPropertySuccess"); - QVERIFY(object->property("result").value<bool>() == true); + QVERIFY(object->property("result").value<bool>()); QMetaObject::invokeMethod(object, "testHasOwnPropertyFailure"); - QVERIFY(object->property("result").value<bool>() == false); + QVERIFY(!object->property("result").value<bool>()); // now test other types in QML QObject *child = object->findChild<QObject*>("typeObj"); @@ -1846,7 +1847,7 @@ void tst_qqmlecmascript::uncreatableExtendedObjectFailureCheck() QQmlComponent component(&engine, testFileUrl("uncreatableExtendedObjectFailureCheck.qml")); QObject *object = component.create(); - QVERIFY(object == 0); + QVERIFY(!object); } /* @@ -2235,7 +2236,7 @@ void tst_qqmlecmascript::dynamicCreationCrash() QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready"); QMetaObject::invokeMethod(object, "dontCrash"); QObject *created = object->objectProperty(); - QVERIFY(created == 0); + QVERIFY(!created); delete object; } @@ -2993,7 +2994,7 @@ void tst_qqmlecmascript::listToVariant() QVariant v = object->property("test"); QCOMPARE(v.userType(), qMetaTypeId<QQmlListReference>()); - QVERIFY(qvariant_cast<QQmlListReference>(v).object() == &container); + QCOMPARE(qvariant_cast<QQmlListReference>(v).object(), &container); delete object; } @@ -3260,7 +3261,7 @@ void tst_qqmlecmascript::ownership() QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); QCoreApplication::processEvents(); - QVERIFY(own.object == 0); + QVERIFY(own.object.isNull()); delete object; } @@ -3319,7 +3320,7 @@ void tst_qqmlecmascript::cppOwnershipReturnValue() QQmlEngine engine; engine.rootContext()->setContextProperty("source", &source); - QVERIFY(source.value == 0); + QVERIFY(source.value.isNull()); QQmlComponent component(&engine); component.setData("import QtQuick 2.0\nQtObject {\nComponent.onCompleted: { var a = source.create(); }\n}\n", QUrl()); @@ -3347,7 +3348,7 @@ void tst_qqmlecmascript::ownershipCustomReturnValue() QQmlEngine engine; engine.rootContext()->setContextProperty("source", &source); - QVERIFY(source.value == 0); + QVERIFY(source.value.isNull()); QQmlComponent component(&engine); component.setData("import QtQuick 2.0\nQtObject {\nComponent.onCompleted: { var a = source.createQmlObject(); }\n}\n", QUrl()); @@ -3364,7 +3365,7 @@ void tst_qqmlecmascript::ownershipCustomReturnValue() QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); QCoreApplication::processEvents(); - QVERIFY(source.value == 0); + QVERIFY(source.value.isNull()); } //the return value from getObject will be JS ownership, @@ -3446,7 +3447,7 @@ void tst_qqmlecmascript::ownershipQmlIncubated() QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); QCoreApplication::processEvents(); - QVERIFY(object->property("incubatedItem").value<QObject*>() == 0); + QVERIFY(!object->property("incubatedItem").value<QObject*>()); delete object; } @@ -3863,7 +3864,7 @@ void tst_qqmlecmascript::singletonType() QObject *object = component.create(); if (!errorMessage.isEmpty()) { - QVERIFY(object == 0); + QVERIFY(!object); } else { QVERIFY(object != 0); for (int i = 0; i < readProperties.size(); ++i) @@ -3920,7 +3921,7 @@ void tst_qqmlecmascript::singletonTypeImportOrder() QQmlComponent component(&engine, testFileUrl("singletontype/singletonTypeImportOrder.qml")); QObject *object = component.create(); QVERIFY(object); - QVERIFY(object->property("v") == 1); + QCOMPARE(object->property("v").toInt(), 1); delete object; } @@ -3929,7 +3930,7 @@ void tst_qqmlecmascript::singletonTypeResolution() QQmlComponent component(&engine, testFileUrl("singletontype/singletonTypeResolution.qml")); QObject *object = component.create(); QVERIFY(object); - QVERIFY(object->property("success") == true); + QVERIFY(object->property("success").toBool()); delete object; } @@ -3941,12 +3942,12 @@ void tst_qqmlecmascript::verifyContextLifetime(QQmlContextData *ctxt) { QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QV4::Scope scope(v4); QV4::ScopedArrayObject scripts(scope, ctxt->importedScripts.value()); - QV4::ScopedValue qml(scope); + QV4::Scoped<QV4::QmlContextWrapper> qml(scope); for (quint32 i = 0; i < scripts->getLength(); ++i) { QQmlContextData *scriptContext, *newContext; qml = scripts->getIndexed(i); - scriptContext = QV4::QmlContextWrapper::getContext(qml); + scriptContext = qml ? qml->getContext() : 0; qml = QV4::Encode::undefined(); { @@ -3957,8 +3958,8 @@ void tst_qqmlecmascript::verifyContextLifetime(QQmlContextData *ctxt) { ctxt->engine->collectGarbage(); qml = scripts->getIndexed(i); - newContext = QV4::QmlContextWrapper::getContext(qml); - QVERIFY(scriptContext == newContext); + newContext = qml ? qml->getContext() : 0; + QCOMPARE(scriptContext, newContext); } } @@ -4202,9 +4203,7 @@ void tst_qqmlecmascript::importScripts() QFETCH(QStringList, propertyNames); QFETCH(QVariantList, propertyValues); - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(dataDirectory() + "/remote"); + ThreadedTestHTTPServer server(dataDirectory() + "/remote"); QStringList importPathList = engine.importPathList(); @@ -4232,7 +4231,7 @@ void tst_qqmlecmascript::importScripts() QObject *object = component.create(); if (!errorMessage.isEmpty()) { - QVERIFY(object == 0); + QVERIFY(!object); } else { QVERIFY(object != 0); @@ -4685,7 +4684,7 @@ void tst_qqmlecmascript::propertyChangeSlots() QString expectedErrorString = e1.url().toString() + QLatin1String(":9:5: Cannot assign to non-existent property \"on_nameWithUnderscoreChanged\""); QCOMPARE(e1.errors().at(0).toString(), expectedErrorString); object = e1.create(); - QVERIFY(object == 0); + QVERIFY(!object); delete object; QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready"); @@ -4693,7 +4692,7 @@ void tst_qqmlecmascript::propertyChangeSlots() expectedErrorString = e2.url().toString() + QLatin1String(":9:5: Cannot assign to non-existent property \"on____nameWithUnderscoresChanged\""); QCOMPARE(e2.errors().at(0).toString(), expectedErrorString); object = e2.create(); - QVERIFY(object == 0); + QVERIFY(!object); delete object; QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready"); @@ -4701,7 +4700,7 @@ void tst_qqmlecmascript::propertyChangeSlots() expectedErrorString = e3.url().toString() + QLatin1String(":9:5: Cannot assign to non-existent property \"on$NameWithDollarsignChanged\""); QCOMPARE(e3.errors().at(0).toString(), expectedErrorString); object = e3.create(); - QVERIFY(object == 0); + QVERIFY(!object); delete object; QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready"); @@ -4709,7 +4708,7 @@ void tst_qqmlecmascript::propertyChangeSlots() expectedErrorString = e4.url().toString() + QLatin1String(":9:5: Cannot assign to non-existent property \"on_6NameWithUnderscoreNumberChanged\""); QCOMPARE(e4.errors().at(0).toString(), expectedErrorString); object = e4.create(); - QVERIFY(object == 0); + QVERIFY(!object); delete object; } @@ -5007,6 +5006,12 @@ void tst_qqmlecmascript::propertyVarCircular() QObject *object = component.create(); QVERIFY(object != 0); QMetaObject::invokeMethod(object, "assignCircular"); // cause assignment and gc + { + QCOMPARE(object->property("canaryInt"), QVariant(5)); + QVariant canaryResourceVariant = object->property("canaryResource"); + QVERIFY(canaryResourceVariant.isValid()); + } + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper. QCoreApplication::processEvents(); QCOMPARE(object->property("canaryInt"), QVariant(5)); @@ -5703,9 +5708,10 @@ void tst_qqmlecmascript::deletedEngine() delete engine; - QCOMPARE(object->property("a").toInt(), 117); + QCOMPARE(object->property("a").toInt(), 0); object->setProperty("b", QVariant(10)); - QCOMPARE(object->property("a").toInt(), 117); + object->setProperty("b", QVariant()); + QCOMPARE(object->property("a").toInt(), 0); delete object; } @@ -5747,10 +5753,10 @@ void tst_qqmlecmascript::variants() QObject *object = component.create(); QVERIFY(object != 0); - QVERIFY(object->property("undefinedVariant").type() == QVariant::Invalid); - QVERIFY(object->property("nullVariant").type() == (int)QMetaType::VoidStar); - QVERIFY(object->property("intVariant").type() == QVariant::Int); - QVERIFY(object->property("doubleVariant").type() == QVariant::Double); + QCOMPARE(object->property("undefinedVariant").type(), QVariant::Invalid); + QCOMPARE(int(object->property("nullVariant").type()), int(QMetaType::VoidStar)); + QCOMPARE(object->property("intVariant").type(), QVariant::Int); + QCOMPARE(object->property("doubleVariant").type(), QVariant::Double); QVariant result; QMetaObject::invokeMethod(object, "checkNull", Q_RETURN_ARG(QVariant, result)); @@ -5801,7 +5807,7 @@ void tst_qqmlecmascript::qtcreatorbug_1289() delete nested; nested = qvariant_cast<QObject *>(o->property("object")); - QVERIFY(nested == 0); + QVERIFY(!nested); // If the bug is present, the next line will crash delete o; @@ -5848,7 +5854,7 @@ void tst_qqmlecmascript::canAssignNullToQObject() o->setProperty("runTest", true); - QVERIFY(o->objectProperty() == 0); + QVERIFY(!o->objectProperty()); delete o; } @@ -5859,7 +5865,7 @@ void tst_qqmlecmascript::canAssignNullToQObject() MyQmlObject *o = qobject_cast<MyQmlObject *>(component.create()); QVERIFY(o != 0); - QVERIFY(o->objectProperty() == 0); + QVERIFY(!o->objectProperty()); delete o; } @@ -6064,7 +6070,7 @@ void tst_qqmlecmascript::include() o->setProperty("serverBaseUrl", server.baseUrl().toString()); component.completeCreate(); - QTRY_VERIFY(o->property("done").toBool() == true); + QTRY_VERIFY(o->property("done").toBool()); QCOMPARE(o->property("test1").toBool(), true); QCOMPARE(o->property("test2").toBool(), true); @@ -6108,8 +6114,8 @@ void tst_qqmlecmascript::includeRemoteSuccess() o->setProperty("serverBaseUrl", server.baseUrl().toString()); component.completeCreate(); - QTRY_VERIFY(o->property("done").toBool() == true); - QTRY_VERIFY(o->property("done2").toBool() == true); + QTRY_VERIFY(o->property("done").toBool()); + QTRY_VERIFY(o->property("done2").toBool()); QCOMPARE(o->property("test1").toBool(), true); QCOMPARE(o->property("test2").toBool(), true); @@ -6132,7 +6138,7 @@ void tst_qqmlecmascript::signalHandlers() QObject *o = component.create(); QVERIFY(o != 0); - QVERIFY(o->property("count").toInt() == 0); + QCOMPARE(o->property("count").toInt(), 0); QMetaObject::invokeMethod(o, "testSignalCall"); QCOMPARE(o->property("count").toInt(), 1); @@ -6140,7 +6146,7 @@ void tst_qqmlecmascript::signalHandlers() QCOMPARE(o->property("count").toInt(), 1); QCOMPARE(o->property("errorString").toString(), QLatin1String("TypeError: Property 'onTestSignal' of object [object Object] is not a function")); - QVERIFY(o->property("funcCount").toInt() == 0); + QCOMPARE(o->property("funcCount").toInt(), 0); QMetaObject::invokeMethod(o, "testSignalConnection"); QCOMPARE(o->property("funcCount").toInt(), 1); @@ -6684,7 +6690,7 @@ void tst_qqmlecmascript::incrDecrSemicolon_error1() { QQmlComponent component(&engine, testFileUrl("incrDecrSemicolon_error1.qml")); QObject *object = component.create(); - QVERIFY(object == 0); + QVERIFY(!object); } void tst_qqmlecmascript::unaryExpression() @@ -7032,7 +7038,7 @@ void tst_qqmlecmascript::invokableWithQObjectDerived() QObject *object = component.create(); QVERIFY(object != 0); - QVERIFY(object->property("result").value<bool>() == true); + QVERIFY(object->property("result").value<bool>()); delete object; } @@ -7111,6 +7117,7 @@ void tst_qqmlecmascript::onDestruction() QObject *obj = c.create(); QVERIFY(obj != 0); delete obj; + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); } { @@ -7122,6 +7129,7 @@ void tst_qqmlecmascript::onDestruction() QQmlComponent c(&engine, testFileUrl("onDestruction.qml")); QObject *obj = c.create(); QVERIFY(obj != 0); + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); } } @@ -7320,7 +7328,7 @@ void tst_qqmlecmascript::sequenceSort_data() for (size_t t=0 ; t < sizeof(types)/sizeof(types[0]) ; ++t) { for (size_t s=0 ; s < sizeof(sort)/sizeof(sort[0]) ; ++s) { for (int c=0 ; c < 2 ; ++c) { - QString testName = QLatin1String(types[t]) + QLatin1String("_") + QLatin1String(sort[s]); + QString testName = QLatin1String(types[t]) + QLatin1Char('_') + QLatin1String(sort[s]); QString fnName = QLatin1String("test_") + testName; bool useComparer = c != 0; testName += useComparer ? QLatin1String("[custom]") : QLatin1String("[default]"); @@ -7344,7 +7352,7 @@ void tst_qqmlecmascript::sequenceSort() QVariant q; QMetaObject::invokeMethod(object, function.toAscii().constData(), Q_RETURN_ARG(QVariant, q), Q_ARG(QVariant, useComparer)); - QVERIFY(q.toBool() == true); + QVERIFY(q.toBool()); delete object; } @@ -7360,10 +7368,10 @@ void tst_qqmlecmascript::dateParse() QVariant q; QMetaObject::invokeMethod(object, "test_is_invalid_jsDateTime", Q_RETURN_ARG(QVariant, q)); - QVERIFY(q.toBool() == true); + QVERIFY(q.toBool()); QMetaObject::invokeMethod(object, "test_is_invalid_qtDateTime", Q_RETURN_ARG(QVariant, q)); - QVERIFY(q.toBool() == true); + QVERIFY(q.toBool()); QMetaObject::invokeMethod(object, "test_rfc2822_date", Q_RETURN_ARG(QVariant, q)); QCOMPARE(q.toLongLong(), 1379512851000LL); @@ -7381,7 +7389,7 @@ void tst_qqmlecmascript::utcDate() QVariant q; QVariant val = QString::fromLatin1("2014-07-16T23:30:31"); QMetaObject::invokeMethod(object, "check_utc", Q_RETURN_ARG(QVariant, q), Q_ARG(QVariant, val)); - QVERIFY(q.toBool() == true); + QVERIFY(q.toBool()); } void tst_qqmlecmascript::negativeYear() @@ -7478,7 +7486,7 @@ void tst_qqmlecmascript::stringParsing() file = file.arg(i); QQmlComponent component(&engine, testFileUrl(file)); QObject *object = component.create(); - QVERIFY(object == 0); + QVERIFY(!object); } } @@ -7491,7 +7499,7 @@ void tst_qqmlecmascript::push_and_shift() " array.push(5); array.unshift(5); array.push(5);" "}" "array.length;"; - QVERIFY(e.evaluate(program).toNumber() == 30000); + QCOMPARE(e.evaluate(program).toNumber(), double(30000)); } void tst_qqmlecmascript::qtbug_32801() @@ -7611,13 +7619,13 @@ void tst_qqmlecmascript::miscTypeTest() QVariant q; QMetaObject::invokeMethod(object, "test_invalid_url_equal", Q_RETURN_ARG(QVariant, q)); - QVERIFY(q.toBool() == true); + QVERIFY(q.toBool()); QMetaObject::invokeMethod(object, "test_invalid_url_strictequal", Q_RETURN_ARG(QVariant, q)); - QVERIFY(q.toBool() == true); + QVERIFY(q.toBool()); QMetaObject::invokeMethod(object, "test_valid_url_equal", Q_RETURN_ARG(QVariant, q)); - QVERIFY(q.toBool() == true); + QVERIFY(q.toBool()); QMetaObject::invokeMethod(object, "test_valid_url_strictequal", Q_RETURN_ARG(QVariant, q)); - QVERIFY(q.toBool() == true); + QVERIFY(q.toBool()); delete object; } @@ -7665,7 +7673,7 @@ void tst_qqmlecmascript::singletonWithEnum() qDebug() << component.errors().first().toString(); QVERIFY(!obj.isNull()); QVariant prop = obj->property("testValue"); - QVERIFY(prop.type() == QVariant::Int); + QCOMPARE(prop.type(), QVariant::Int); QCOMPARE(prop.toInt(), int(SingletonWithEnum::TestValue)); } @@ -7677,7 +7685,7 @@ void tst_qqmlecmascript::lazyBindingEvaluation() qDebug() << component.errors().first().toString(); QVERIFY(!obj.isNull()); QVariant prop = obj->property("arrayLength"); - QVERIFY(prop.type() == QVariant::Int); + QCOMPARE(prop.type(), QVariant::Int); QCOMPARE(prop.toInt(), 2); } @@ -7688,7 +7696,7 @@ void tst_qqmlecmascript::varPropertyAccessOnObjectWithInvalidContext() if (obj.isNull()) qDebug() << component.errors().first().toString(); QVERIFY(!obj.isNull()); - QVERIFY(obj->property("success") == true); + QVERIFY(obj->property("success").toBool()); } void tst_qqmlecmascript::importedScriptsAccessOnObjectWithInvalidContext() @@ -7698,7 +7706,7 @@ void tst_qqmlecmascript::importedScriptsAccessOnObjectWithInvalidContext() if (obj.isNull()) qDebug() << component.errors().first().toString(); QVERIFY(!obj.isNull()); - QTRY_VERIFY(obj->property("success") == true); + QTRY_VERIFY(obj->property("success").toBool()); } void tst_qqmlecmascript::importedScriptsWithoutQmlMode() @@ -7708,7 +7716,7 @@ void tst_qqmlecmascript::importedScriptsWithoutQmlMode() if (obj.isNull()) qDebug() << component.errors().first().toString(); QVERIFY(!obj.isNull()); - QTRY_VERIFY(obj->property("success") == true); + QTRY_VERIFY(obj->property("success").toBool()); } void tst_qqmlecmascript::contextObjectOnLazyBindings() @@ -7871,6 +7879,16 @@ void tst_qqmlecmascript::switchExpression() QCOMPARE(v.toBool(), true); } +void tst_qqmlecmascript::qtbug_46022() +{ + QQmlComponent component(&engine, testFileUrl("qtbug_46022.qml")); + + QScopedPointer<QObject> obj(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->property("test1").toBool(), true); + QCOMPARE(obj->property("test2").toBool(), true); +} + QTEST_MAIN(tst_qqmlecmascript) #include "tst_qqmlecmascript.moc" diff --git a/tests/auto/qml/qqmlengine/data/TypeofQmlProperty.qml b/tests/auto/qml/qqmlengine/data/TypeofQmlProperty.qml new file mode 100644 index 0000000000..2196543dc8 --- /dev/null +++ b/tests/auto/qml/qqmlengine/data/TypeofQmlProperty.qml @@ -0,0 +1,6 @@ +import QtQuick 2.5 + +Item { + property var someProp: 1 + Component.onCompleted: console.log("typeof someProp:", typeof(someProp)); +} diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp index eac648ef15..486a0b4e87 100644 --- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp +++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp @@ -75,6 +75,8 @@ private slots: void urlInterceptor_data(); void urlInterceptor(); + void qmlContextProperties(); + public slots: QObject *createAQObjectForOwnershipTest () { @@ -90,7 +92,7 @@ void tst_qqmlengine::rootContext() QVERIFY(engine.rootContext()); QCOMPARE(engine.rootContext()->engine(), &engine); - QVERIFY(engine.rootContext()->parentContext() == 0); + QVERIFY(!engine.rootContext()->parentContext()); } class NetworkAccessManagerFactory : public QQmlNetworkAccessManagerFactory @@ -119,8 +121,9 @@ void tst_qqmlengine::networkAccessManager() engine = new QQmlEngine; NetworkAccessManagerFactory factory; engine->setNetworkAccessManagerFactory(&factory); - QVERIFY(engine->networkAccessManagerFactory() == &factory); - QVERIFY(engine->networkAccessManager() == factory.manager); + QCOMPARE(engine->networkAccessManagerFactory(), &factory); + QNetworkAccessManager *engineNam = engine->networkAccessManager(); // calls NetworkAccessManagerFactory::create() + QCOMPARE(engineNam, factory.manager); delete engine; } @@ -184,7 +187,7 @@ void tst_qqmlengine::baseUrl() dir.cdUp(); QVERIFY(dir != QDir::current()); QDir::setCurrent(dir.path()); - QVERIFY(QDir::current() == dir); + QCOMPARE(QDir::current(), dir); QUrl cwd2 = QUrl::fromLocalFile(QDir::currentPath() + QDir::separator()); QCOMPARE(engine.baseUrl(), cwd2); @@ -200,11 +203,11 @@ void tst_qqmlengine::contextForObject() QQmlEngine *engine = new QQmlEngine; // Test null-object - QVERIFY(QQmlEngine::contextForObject(0) == 0); + QVERIFY(!QQmlEngine::contextForObject(0)); // Test an object with no context QObject object; - QVERIFY(QQmlEngine::contextForObject(&object) == 0); + QVERIFY(!QQmlEngine::contextForObject(&object)); // Test setting null-object QQmlEngine::setContextForObject(0, engine->rootContext()); @@ -214,18 +217,18 @@ void tst_qqmlengine::contextForObject() // Test setting context QQmlEngine::setContextForObject(&object, engine->rootContext()); - QVERIFY(QQmlEngine::contextForObject(&object) == engine->rootContext()); + QCOMPARE(QQmlEngine::contextForObject(&object), engine->rootContext()); QQmlContext context(engine->rootContext()); // Try changing context QTest::ignoreMessage(QtWarningMsg, "QQmlEngine::setContextForObject(): Object already has a QQmlContext"); QQmlEngine::setContextForObject(&object, &context); - QVERIFY(QQmlEngine::contextForObject(&object) == engine->rootContext()); + QCOMPARE(QQmlEngine::contextForObject(&object), engine->rootContext()); // Delete context delete engine; engine = 0; - QVERIFY(QQmlEngine::contextForObject(&object) == 0); + QVERIFY(!QQmlEngine::contextForObject(&object)); } void tst_qqmlengine::offlineStoragePath() @@ -446,7 +449,7 @@ void tst_qqmlengine::failedCompilation() QQmlComponent component(&engine, testFileUrl(file)); QVERIFY(!component.isReady()); QScopedPointer<QObject> object(component.create()); - QVERIFY(object == 0); + QVERIFY(object.isNull()); engine.collectGarbage(); engine.trimComponentCache(); @@ -470,7 +473,7 @@ void tst_qqmlengine::outputWarningsToStandardError() QQmlComponent c(&engine); c.setData("import QtQuick 2.0; QtObject { property int a: undefined }", QUrl()); - QVERIFY(c.isReady() == true); + QVERIFY(c.isReady()); QQmlTestMessageHandler messageHandler; @@ -777,6 +780,18 @@ void tst_qqmlengine::urlInterceptor() QCOMPARE(o->property("absoluteUrl").toString(), expectedAbsoluteUrl); } +void tst_qqmlengine::qmlContextProperties() +{ + QQmlEngine e; + + QQmlComponent c(&e, testFileUrl("TypeofQmlProperty.qml")); + QObject *o = c.create(); + if (!o) { + qDebug() << c.errorString(); + } + QVERIFY(o); +} + QTEST_MAIN(tst_qqmlengine) #include "tst_qqmlengine.moc" diff --git a/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp b/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp index e381976448..d9838a4941 100644 --- a/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp +++ b/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp @@ -140,7 +140,7 @@ void tst_qqmlexpression::expressionFromDataComponent() QQmlExpression expression(object->scriptString()); QVariant result = expression.evaluate(); - QVERIFY(result.type() == QVariant::String); + QCOMPARE(result.type(), QVariant::String); QCOMPARE(result.toString(), QStringLiteral("success")); } diff --git a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp index 26092595d9..2f581e296a 100644 --- a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp +++ b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp @@ -96,8 +96,8 @@ private: QList<QByteArray> actual; \ for (int ii = 0; ii < errors.count(); ++ii) { \ const QQmlError &error = errors.at(ii); \ - QByteArray errorStr = QByteArray::number(error.line()) + ":" + \ - QByteArray::number(error.column()) + ":" + \ + QByteArray errorStr = QByteArray::number(error.line()) + ':' + \ + QByteArray::number(error.column()) + ':' + \ error.description().toUtf8(); \ actual << errorStr; \ } \ @@ -148,7 +148,7 @@ void tst_qqmlincubator::objectDeleted() component.create(incubator); QCOMPARE(incubator.status(), QQmlIncubator::Loading); - QVERIFY(SelfRegisteringType::me() == 0); + QVERIFY(!SelfRegisteringType::me()); while (SelfRegisteringOuterType::me() == 0 && incubator.isLoading()) { bool b = false; @@ -172,7 +172,7 @@ void tst_qqmlincubator::objectDeleted() QVERIFY(incubator.isError()); VERIFY_ERRORS(incubator, "objectDeleted.errors.txt"); - QVERIFY(incubator.object() == 0); + QVERIFY(!incubator.object()); } QVERIFY(SelfRegisteringOuterType::beenDeleted); } @@ -236,7 +236,7 @@ void tst_qqmlincubator::clear() incubator.clear(); QVERIFY(incubator.isNull()); - QVERIFY(incubator.object() == 0); + QVERIFY(!incubator.object()); QVERIFY(!obj.isNull()); delete obj; @@ -413,7 +413,7 @@ void tst_qqmlincubator::clearDuringCompletion() component.create(incubator); QCOMPARE(incubator.status(), QQmlIncubator::Loading); - QVERIFY(CompletionRegisteringType::me() == 0); + QVERIFY(!CompletionRegisteringType::me()); while (CompletionRegisteringType::me() == 0 && incubator.isLoading()) { bool b = false; @@ -622,7 +622,7 @@ void tst_qqmlincubator::asynchronousIfNested() component.create(incubator); QVERIFY(incubator.isLoading()); - QVERIFY(SelfRegisteringType::me() == 0); + QVERIFY(!SelfRegisteringType::me()); while (SelfRegisteringType::me() == 0 && incubator.isLoading()) { bool b = false; controller.incubateWhile(&b); @@ -741,7 +741,7 @@ void tst_qqmlincubator::chainedAsynchronousIfNested() component.create(incubator); QVERIFY(incubator.isLoading()); - QVERIFY(SelfRegisteringType::me() == 0); + QVERIFY(!SelfRegisteringType::me()); while (SelfRegisteringType::me() == 0 && incubator.isLoading()) { bool b = false; @@ -855,7 +855,7 @@ void tst_qqmlincubator::chainedAsynchronousIfNestedOnCompleted() component.create(incubator); QVERIFY(incubator.isLoading()); - QVERIFY(SelfRegisteringType::me() == 0); + QVERIFY(!SelfRegisteringType::me()); while (SelfRegisteringType::me() == 0 && incubator.isLoading()) { bool b = false; @@ -983,7 +983,7 @@ void tst_qqmlincubator::chainedAsynchronousClear() component.create(incubator); QVERIFY(incubator.isLoading()); - QVERIFY(SelfRegisteringType::me() == 0); + QVERIFY(!SelfRegisteringType::me()); while (SelfRegisteringType::me() == 0 && incubator.isLoading()) { bool b = false; @@ -1106,7 +1106,7 @@ void tst_qqmlincubator::selfDelete() component.create(*incubator); QCOMPARE(incubator->QQmlIncubator::status(), QQmlIncubator::Loading); - QVERIFY(SelfRegisteringType::me() == 0); + QVERIFY(!SelfRegisteringType::me()); while (SelfRegisteringType::me() == 0 && incubator->isLoading()) { bool b = false; diff --git a/tests/auto/qml/qqmllanguage/BLACKLIST b/tests/auto/qml/qqmllanguage/BLACKLIST new file mode 100644 index 0000000000..c1c7e56df9 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/BLACKLIST @@ -0,0 +1,2 @@ +[importsPath] +windows diff --git a/tests/auto/qml/qqmllanguage/data/CompositeTypeWithAttachedProperty.qml b/tests/auto/qml/qqmllanguage/data/CompositeTypeWithAttachedProperty.qml new file mode 100644 index 0000000000..6a14e72a31 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/CompositeTypeWithAttachedProperty.qml @@ -0,0 +1,4 @@ +import Test 1.0 + +MyCompositeBaseType { +} diff --git a/tests/auto/qml/qqmllanguage/data/CompositeTypeWithEnum.qml b/tests/auto/qml/qqmllanguage/data/CompositeTypeWithEnum.qml new file mode 100644 index 0000000000..6a14e72a31 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/CompositeTypeWithEnum.qml @@ -0,0 +1,4 @@ +import Test 1.0 + +MyCompositeBaseType { +} diff --git a/tests/auto/qml/qqmllanguage/data/assignSignalFunctionExpression.qml b/tests/auto/qml/qqmllanguage/data/assignSignalFunctionExpression.qml new file mode 100644 index 0000000000..bf8f8556c1 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/assignSignalFunctionExpression.qml @@ -0,0 +1,5 @@ +import Test 1.0 +MyQmlObject { + onBasicSignal: function() { basicSlot() } + onBasicParameterizedSignal: function(param) { basicSlotWithArgs(param) } +} diff --git a/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithAttachedProperty.qml b/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithAttachedProperty.qml new file mode 100644 index 0000000000..d34e4650b3 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithAttachedProperty.qml @@ -0,0 +1,6 @@ +import Test 1.0 + +RegisteredCompositeTypeWithAttachedProperty { + RegisteredCompositeTypeWithAttachedProperty.objectName: "test" + property string attachedProperty: RegisteredCompositeTypeWithAttachedProperty.objectName +} diff --git a/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml b/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml new file mode 100644 index 0000000000..5f8c11e5f6 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml @@ -0,0 +1,6 @@ +import Test 1.0 + +RegisteredCompositeTypeWithEnum { + property int enumValue0: RegisteredCompositeTypeWithEnum.EnumValue0 + property int enumValue42: RegisteredCompositeTypeWithEnum.EnumValue42 +} diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp index 6fc4bae438..95a98788c3 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.cpp +++ b/tests/auto/qml/qqmllanguage/testtypes.cpp @@ -91,6 +91,8 @@ void registerTypes() qmlRegisterCustomExtendedType<SimpleObjectWithCustomParser, SimpleObjectExtension>("Test", 1, 0, "SimpleExtendedObjectWithCustomParser", new SimpleObjectCustomParser); qmlRegisterType<RootObjectInCreationTester>("Test", 1, 0, "RootObjectInCreationTester"); + + qmlRegisterType<MyCompositeBaseType>("Test", 1, 0, "MyCompositeBaseType"); } QVariant myCustomVariantTypeConverter(const QString &data) @@ -121,7 +123,7 @@ void CustomBinding::componentComplete() QQmlContextData *context = QQmlContextData::get(qmlContext(this)); QV4::Scope scope(QQmlEnginePrivate::getV4Engine(qmlEngine(this))); - QV4::ScopedValue function(scope, QV4::QmlBindingWrapper::createQmlCallableForFunction(context, m_target, cdata->compilationUnit->runtimeFunctions[bindingId])); + QV4::ScopedValue function(scope, QV4::FunctionObject::createQmlFunction(context, m_target, cdata->compilationUnit->runtimeFunctions[bindingId])); QQmlBinding *qmlBinding = new QQmlBinding(function, m_target, context); QQmlProperty property(m_target, name, qmlContext(this)); diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index b8792a892f..c64fda5ea1 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -1079,9 +1079,20 @@ class MyEnumDerivedClass : public MyEnum2Class Q_OBJECT }; +class MyCompositeBaseType : public QObject +{ + Q_OBJECT + Q_ENUMS(CompositeEnum) + +public: + enum CompositeEnum { EnumValue0, EnumValue42 = 42 }; + static QObject *qmlAttachedProperties(QObject *parent) { return new QObject(parent); } +}; + Q_DECLARE_METATYPE(MyEnum2Class::EnumB) Q_DECLARE_METATYPE(MyEnum1Class::EnumA) Q_DECLARE_METATYPE(Qt::TextFormat) +Q_DECLARE_METATYPE(MyCompositeBaseType::CompositeEnum) QML_DECLARE_TYPE(MyRevisionedBaseClassRegistered) QML_DECLARE_TYPE(MyRevisionedBaseClassUnregistered) @@ -1089,6 +1100,8 @@ QML_DECLARE_TYPE(MyRevisionedClass) QML_DECLARE_TYPE(MyRevisionedSubclass) QML_DECLARE_TYPE(MySubclass) QML_DECLARE_TYPE(MyReceiversTestObject) +QML_DECLARE_TYPE(MyCompositeBaseType) +QML_DECLARE_TYPEINFO(MyCompositeBaseType, QML_HAS_ATTACHED_PROPERTIES) class CustomBinding : public QObject, public QQmlParserStatus { diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 08da779d90..1f299c0dbb 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -55,6 +55,10 @@ #include "../../shared/util.h" +#if defined(Q_OS_MAC) +#include <unistd.h> +#endif + DEFINE_BOOL_CONFIG_OPTION(qmlCheckTypes, QML_CHECK_TYPES) static inline bool isCaseSensitiveFileSystem(const QString &path) { @@ -113,6 +117,7 @@ private slots: void idProperty(); void autoNotifyConnection(); void assignSignal(); + void assignSignalFunctionExpression(); void overrideSignal_data(); void overrideSignal(); void dynamicProperties(); @@ -154,6 +159,8 @@ private slots: void readonlyObjectProperties(); void receivers(); void registeredCompositeType(); + void registeredCompositeTypeWithEnum(); + void registeredCompositeTypeWithAttachedProperty(); void implicitImportsLast(); void basicRemote_data(); @@ -240,6 +247,8 @@ private slots: void earlyIdObjectAccess(); + void dataAlignment(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -275,8 +284,8 @@ private: QList<QQmlError> errors = component.errors(); \ for (int ii = 0; ii < errors.count(); ++ii) { \ const QQmlError &error = errors.at(ii); \ - QByteArray errorStr = QByteArray::number(error.line()) + ":" + \ - QByteArray::number(error.column()) + ":" + \ + QByteArray errorStr = QByteArray::number(error.line()) + ':' + \ + QByteArray::number(error.column()) + ':' + \ error.description().toUtf8(); \ actual << errorStr; \ } \ @@ -328,7 +337,7 @@ void tst_qqmllanguage::insertedSemicolon() if(create) { QObject *object = component.create(); - QVERIFY(object == 0); + QVERIFY(!object); } VERIFY_ERRORS(errorFile.toLatin1().constData()); @@ -550,7 +559,7 @@ void tst_qqmllanguage::errors() if (create) { QObject *object = component.create(); - QVERIFY(object == 0); + QVERIFY(!object); } VERIFY_ERRORS(errorFile.toLatin1().constData()); @@ -580,7 +589,7 @@ void tst_qqmllanguage::interfaceProperty() MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); QVERIFY(object != 0); QVERIFY(object->interface()); - QVERIFY(object->interface()->id == 913); + QCOMPARE(object->interface()->id, 913); } void tst_qqmllanguage::interfaceQList() @@ -589,9 +598,9 @@ void tst_qqmllanguage::interfaceQList() VERIFY_ERRORS(0); MyContainer *container= qobject_cast<MyContainer*>(component.create()); QVERIFY(container != 0); - QVERIFY(container->getQListInterfaces()->count() == 2); + QCOMPARE(container->getQListInterfaces()->count(), 2); for(int ii = 0; ii < 2; ++ii) - QVERIFY(container->getQListInterfaces()->at(ii)->id == 913); + QCOMPARE(container->getQListInterfaces()->at(ii)->id, 913); } void tst_qqmllanguage::assignObjectToSignal() @@ -630,7 +639,7 @@ void tst_qqmllanguage::assignQmlComponent() VERIFY_ERRORS(0); MyContainer *object = qobject_cast<MyContainer *>(component.create()); QVERIFY(object != 0); - QVERIFY(object->getChildren()->count() == 1); + QCOMPARE(object->getChildren()->count(), 1); QObject *child = object->getChildren()->at(0); QCOMPARE(child->property("x"), QVariant(10)); QCOMPARE(child->property("y"), QVariant(11)); @@ -722,17 +731,17 @@ void tst_qqmllanguage::assignLiteralToVariant() QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool); QCOMPARE(object->property("test12").userType(), (int)QVariant::Vector4D); - QVERIFY(object->property("test1") == QVariant(1)); - QVERIFY(object->property("test2") == QVariant((double)1.7)); + QCOMPARE(object->property("test1"), QVariant(1)); + QCOMPARE(object->property("test2"), QVariant((double)1.7)); QVERIFY(object->property("test3") == QVariant(QString(QLatin1String("Hello world!")))); - QVERIFY(object->property("test4") == QVariant(QColor::fromRgb(0xFF008800))); + QCOMPARE(object->property("test4"), QVariant(QColor::fromRgb(0xFF008800))); QVERIFY(object->property("test5") == QVariant(QRectF(10, 10, 10, 10))); QVERIFY(object->property("test6") == QVariant(QPointF(10, 10))); QVERIFY(object->property("test7") == QVariant(QSizeF(10, 10))); QVERIFY(object->property("test8") == QVariant(QVector3D(100, 100, 100))); - QVERIFY(object->property("test9") == QVariant(QString(QLatin1String("#FF008800")))); - QVERIFY(object->property("test10") == QVariant(bool(true))); - QVERIFY(object->property("test11") == QVariant(bool(false))); + QCOMPARE(object->property("test9"), QVariant(QString(QLatin1String("#FF008800")))); + QCOMPARE(object->property("test10"), QVariant(bool(true))); + QCOMPARE(object->property("test11"), QVariant(bool(false))); QVERIFY(object->property("test12") == QVariant(QVector4D(100, 100, 100, 100))); delete object; @@ -1170,7 +1179,7 @@ void tst_qqmllanguage::customParserTypes() VERIFY_ERRORS(0); QObject *object = component.create(); QVERIFY(object != 0); - QVERIFY(object->property("count") == QVariant(2)); + QCOMPARE(object->property("count"), QVariant(2)); } // Tests that the root item can be a custom component @@ -1259,6 +1268,17 @@ void tst_qqmllanguage::assignSignal() emit object->basicParameterizedSignal(9); } +void tst_qqmllanguage::assignSignalFunctionExpression() +{ + QQmlComponent component(&engine, testFileUrl("assignSignalFunctionExpression.qml")); + VERIFY_ERRORS(0); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot"); + emit object->basicSignal(); + QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlotWithArgs(9)"); + emit object->basicParameterizedSignal(9); +} void tst_qqmllanguage::overrideSignal_data() { @@ -1352,7 +1372,7 @@ void tst_qqmllanguage::dynamicObjectProperties() QObject *object = component.create(); QVERIFY(object != 0); - QVERIFY(object->property("objectProperty") == qVariantFromValue((QObject*)0)); + QCOMPARE(object->property("objectProperty"), qVariantFromValue((QObject*)0)); QVERIFY(object->property("objectProperty2") != qVariantFromValue((QObject*)0)); } { @@ -1661,7 +1681,7 @@ void tst_qqmllanguage::aliasProperties() v = object->property("otherAlias"); QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>()); o = qvariant_cast<MyQmlObject*>(v); - QVERIFY(o == 0); + QVERIFY(!o); delete object; } @@ -1691,7 +1711,7 @@ void tst_qqmllanguage::aliasProperties() QVERIFY(object2 != 0); QObject *alias = qvariant_cast<QObject *>(object->property("aliasedObject")); - QVERIFY(alias == object2); + QCOMPARE(alias, object2); delete object1; @@ -1700,7 +1720,7 @@ void tst_qqmllanguage::aliasProperties() void *a[] = { &alias2, 0, &status }; QMetaObject::metacall(object, QMetaObject::ReadProperty, object->metaObject()->indexOfProperty("aliasedObject"), a); - QVERIFY(alias2 == 0); + QVERIFY(!alias2); } // Simple composite type @@ -2106,50 +2126,50 @@ void tst_qqmllanguage::scriptStringComparison() const qreal n = 12.345; bool ok; - QVERIFY(object2->scriptProperty().stringLiteral() == s); + QCOMPARE(object2->scriptProperty().stringLiteral(), s); QVERIFY(object3->scriptProperty().numberLiteral(&ok) == n && ok); - QVERIFY(object1->scriptProperty() == object1->scriptProperty()); - QVERIFY(object2->scriptProperty() == object2->scriptProperty()); - QVERIFY(object3->scriptProperty() == object3->scriptProperty()); + QCOMPARE(object1->scriptProperty(), object1->scriptProperty()); + QCOMPARE(object2->scriptProperty(), object2->scriptProperty()); + QCOMPARE(object3->scriptProperty(), object3->scriptProperty()); QVERIFY(object2->scriptProperty() != object3->scriptProperty()); QVERIFY(object1->scriptProperty() != object2->scriptProperty()); QVERIFY(object1->scriptProperty() != object3->scriptProperty()); func.callWithInstance(inst2, QJSValueList() << n); - QVERIFY(object2->scriptProperty() == object3->scriptProperty()); + QCOMPARE(object2->scriptProperty(), object3->scriptProperty()); func.callWithInstance(inst2, QJSValueList() << s); QVERIFY(object2->scriptProperty() != object3->scriptProperty()); func.callWithInstance(inst3, QJSValueList() << s); - QVERIFY(object2->scriptProperty() == object3->scriptProperty()); + QCOMPARE(object2->scriptProperty(), object3->scriptProperty()); func.callWithInstance(inst2, QJSValueList() << QJSValue::UndefinedValue); QVERIFY(object2->scriptProperty() != object3->scriptProperty()); func.callWithInstance(inst3, QJSValueList() << QJSValue::UndefinedValue); - QVERIFY(object2->scriptProperty() == object3->scriptProperty()); + QCOMPARE(object2->scriptProperty(), object3->scriptProperty()); func.callWithInstance(inst2, QJSValueList() << QJSValue::NullValue); QVERIFY(object2->scriptProperty() != object3->scriptProperty()); func.callWithInstance(inst3, QJSValueList() << QJSValue::NullValue); - QVERIFY(object2->scriptProperty() == object3->scriptProperty()); + QCOMPARE(object2->scriptProperty(), object3->scriptProperty()); func.callWithInstance(inst2, QJSValueList() << false); QVERIFY(object2->scriptProperty() != object3->scriptProperty()); func.callWithInstance(inst3, QJSValueList() << false); - QVERIFY(object2->scriptProperty() == object3->scriptProperty()); + QCOMPARE(object2->scriptProperty(), object3->scriptProperty()); func.callWithInstance(inst2, QJSValueList() << true); QVERIFY(object2->scriptProperty() != object3->scriptProperty()); func.callWithInstance(inst3, QJSValueList() << true); - QVERIFY(object2->scriptProperty() == object3->scriptProperty()); + QCOMPARE(object2->scriptProperty(), object3->scriptProperty()); QVERIFY(object1->scriptProperty() != object2->scriptProperty()); object2->setScriptProperty(object1->scriptProperty()); - QVERIFY(object1->scriptProperty() == object2->scriptProperty()); + QCOMPARE(object1->scriptProperty(), object2->scriptProperty()); QVERIFY(object1->scriptProperty() != object3->scriptProperty()); func.callWithInstance(inst3, QJSValueList() << engine.toScriptValue(object1->scriptProperty())); - QVERIFY(object1->scriptProperty() == object3->scriptProperty()); + QCOMPARE(object1->scriptProperty(), object3->scriptProperty()); // While this are two instances of the same object they are still considered different // because the (none literal) script string may access variables which have different @@ -2525,9 +2545,7 @@ void tst_qqmllanguage::basicRemote() QFETCH(QString, type); QFETCH(QString, error); - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(dataDirectory()); + ThreadedTestHTTPServer server(dataDirectory()); url = server.baseUrl().resolved(url); @@ -2572,9 +2590,7 @@ void tst_qqmllanguage::importsRemote() QFETCH(QString, type); QFETCH(QString, error); - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(dataDirectory()); + ThreadedTestHTTPServer server(dataDirectory()); qml.replace(QStringLiteral("{{ServerBaseUrl}}"), server.baseUrl().toString()); @@ -2667,9 +2683,7 @@ void tst_qqmllanguage::importsInstalledRemote() QFETCH(QString, type); QFETCH(QString, error); - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(dataDirectory()); + ThreadedTestHTTPServer server(dataDirectory()); QString serverdir = server.urlString("/lib/"); engine.setImportPathList(QStringList(defaultImportPathList) << serverdir); @@ -2734,9 +2748,7 @@ void tst_qqmllanguage::importsPath() QFETCH(QString, qml); QFETCH(QString, value); - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(dataDirectory()); + ThreadedTestHTTPServer server(dataDirectory()); for (int i = 0; i < importPath.count(); ++i) importPath[i].replace(QStringLiteral("{{ServerBaseUrl}}"), server.baseUrl().toString()); @@ -3158,6 +3170,8 @@ void tst_qqmllanguage::initTestCase() qmlRegisterType(testFileUrl("CompositeType.qml"), "Test", 1, 0, "RegisteredCompositeType"); qmlRegisterType(testFileUrl("CompositeType.DoesNotExist.qml"), "Test", 1, 0, "RegisteredCompositeType2"); qmlRegisterType(testFileUrl("invalidRoot.1.qml"), "Test", 1, 0, "RegisteredCompositeType3"); + qmlRegisterType(testFileUrl("CompositeTypeWithEnum.qml"), "Test", 1, 0, "RegisteredCompositeTypeWithEnum"); + qmlRegisterType(testFileUrl("CompositeTypeWithAttachedProperty.qml"), "Test", 1, 0, "RegisteredCompositeTypeWithAttachedProperty"); // Registering the TestType class in other modules should have no adverse effects qmlRegisterType<TestType>("org.qtproject.TestPre", 1, 0, "Test"); @@ -3250,7 +3264,7 @@ void tst_qqmllanguage::registrationOrder() QObject *o = component.create(); QVERIFY(o != 0); - QVERIFY(o->metaObject() == &MyVersion2Class::staticMetaObject); + QCOMPARE(o->metaObject(), &MyVersion2Class::staticMetaObject); delete o; } @@ -3334,12 +3348,39 @@ void tst_qqmllanguage::registeredCompositeType() delete o; } +// QTBUG-43582 +void tst_qqmllanguage::registeredCompositeTypeWithEnum() +{ + QQmlComponent component(&engine, testFileUrl("registeredCompositeTypeWithEnum.qml")); + + VERIFY_ERRORS(0); + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("enumValue0").toInt(), static_cast<int>(MyCompositeBaseType::EnumValue0)); + QCOMPARE(o->property("enumValue42").toInt(), static_cast<int>(MyCompositeBaseType::EnumValue42)); + + delete o; +} + +// QTBUG-43581 +void tst_qqmllanguage::registeredCompositeTypeWithAttachedProperty() +{ + QQmlComponent component(&engine, testFileUrl("registeredCompositeTypeWithAttachedProperty.qml")); + + VERIFY_ERRORS(0); + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("attachedProperty").toString(), QStringLiteral("test")); + + delete o; +} + // QTBUG-18268 void tst_qqmllanguage::remoteLoadCrash() { - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(dataDirectory()); + ThreadedTestHTTPServer server(dataDirectory()); QQmlComponent component(&engine); component.setData("import QtQuick 2.0; Text {}", server.url("/remoteLoadCrash.qml")); @@ -3644,7 +3685,7 @@ void tst_qqmllanguage::compositeSingletonSameEngine() QVERIFY(s2 != 0); QCOMPARE(s2->property("testProp2"), QVariant(13)); - QVERIFY(s1 == s2); + QCOMPARE(s1, s2); } // Checks that the addresses of the composite singletons used in different @@ -3693,7 +3734,7 @@ void tst_qqmllanguage::compositeSingletonQualifiedNamespace() getSingletonInstance(engine, "singletonTest5a.qml", "singletonInstance", &s2); QVERIFY(s2 != 0); - QVERIFY(s1 == s2); + QCOMPARE(s1, s2); } // Loads a singleton from a module @@ -3719,7 +3760,7 @@ void tst_qqmllanguage::compositeSingletonModule() getSingletonInstance(engine, "singletonTest6a.qml", "singletonInstance", &s2); QVERIFY(s2 != 0); - QVERIFY(s1 == s2); + QCOMPARE(s1, s2); } // Loads a singleton from a module with a higher version @@ -3745,7 +3786,7 @@ void tst_qqmllanguage::compositeSingletonModuleVersioned() getSingletonInstance(engine, "singletonTest7a.qml", "singletonInstance", &s2); QVERIFY(s2 != 0); - QVERIFY(s1 == s2); + QCOMPARE(s1, s2); } // Loads a singleton from a module with a qualified namespace @@ -3771,7 +3812,7 @@ void tst_qqmllanguage::compositeSingletonModuleQualified() getSingletonInstance(engine, "singletonTest8a.qml", "singletonInstance", &s2); QVERIFY(s2 != 0); - QVERIFY(s1 == s2); + QCOMPARE(s1, s2); } // Tries to instantiate a type with a pragma Singleton and fails @@ -3828,9 +3869,7 @@ void tst_qqmllanguage::compositeSingletonQmlDirError() // Load a remote composite singleton type via qmldir that defines the type as a singleton void tst_qqmllanguage::compositeSingletonRemote() { - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(dataDirectory()); + ThreadedTestHTTPServer server(dataDirectory()); QFile f(testFile("singletonTest15.qml")); QVERIFY(f.open(QIODevice::ReadOnly)); @@ -3995,7 +4034,7 @@ void tst_qqmllanguage::propertyCacheInSync() QVERIFY(ddata); QVERIFY(ddata->propertyCache); // Those always have to be in sync and correct. - QVERIFY(ddata->propertyCache == vmemoCache); + QCOMPARE(ddata->propertyCache, vmemoCache); QCOMPARE(anchors->property("margins").toInt(), 50); } @@ -4042,6 +4081,14 @@ void tst_qqmllanguage::earlyIdObjectAccess() QVERIFY(o->property("success").toBool()); } +void tst_qqmllanguage::dataAlignment() +{ + QVERIFY(sizeof(QQmlVMEMetaData) % sizeof(int) == 0); + QVERIFY(sizeof(QQmlVMEMetaData::AliasData) % sizeof(int) == 0); + QVERIFY(sizeof(QQmlVMEMetaData::PropertyData) % sizeof(int) == 0); + QVERIFY(sizeof(QQmlVMEMetaData::MethodData) % sizeof(int) == 0); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp index 4d76fc4fba..d26c1c584b 100644 --- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp +++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp @@ -125,6 +125,7 @@ private slots: void datetime(); void datetime_data(); void about_to_be_signals(); + void modify_through_delegate(); }; bool tst_qqmllistmodel::compareVariantList(const QVariantList &testList, QVariant object) @@ -624,7 +625,7 @@ void tst_qqmllistmodel::enumerate() int expectedStringCount = sizeof(expectedStrings) / sizeof(expectedStrings[0]); - QStringList r = item->property("result").toString().split(":"); + QStringList r = item->property("result").toString().split(QLatin1Char(':')); int matchCount = 0; for (int i=0 ; i < expectedStringCount ; ++i) { @@ -642,7 +643,7 @@ void tst_qqmllistmodel::enumerate() } } - QVERIFY(matchCount == expectedStringCount); + QCOMPARE(matchCount, expectedStringCount); delete item; } @@ -1296,7 +1297,7 @@ void tst_qqmllistmodel::datetime() QQmlExpression e(engine.rootContext(), &model, qml); QVariant result = e.evaluate(); QDateTime dtResult = result.toDateTime(); - QVERIFY(expected == dtResult); + QCOMPARE(expected, dtResult); } class RowTester : public QObject @@ -1427,6 +1428,36 @@ void tst_qqmllistmodel::about_to_be_signals() QCOMPARE(tester.rowsRemovedCount, 0); } +void tst_qqmllistmodel::modify_through_delegate() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + " ListModel {\n" + " id: testModel\n" + " objectName: \"testModel\"\n" + " ListElement { name: \"Joe\"; age: 22 }\n" + " ListElement { name: \"Doe\"; age: 33 }\n" + " }\n" + " ListView {\n" + " model: testModel\n" + " delegate: Item {\n" + " Component.onCompleted: model.age = 18;\n" + " }\n" + " }\n" + "}\n", QUrl()); + + QObject *scene = component.create(); + QQmlListModel *model = scene->findChild<QQmlListModel*>("testModel"); + + const QHash<int, QByteArray> roleNames = model->roleNames(); + + QCOMPARE(model->data(model->index(0, 0, QModelIndex()), roleNames.key("age")).toInt(), 18); + QCOMPARE(model->data(model->index(1, 0, QModelIndex()), roleNames.key("age")).toInt(), 18); +} + QTEST_MAIN(tst_qqmllistmodel) #include "tst_qqmllistmodel.moc" diff --git a/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp b/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp index 5bf75d41d4..0ad2963265 100644 --- a/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp +++ b/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp @@ -647,15 +647,15 @@ void tst_qqmllistmodelworkerscript::worker_sync() QQuickItem *item = createWorkerTest(&eng, &component, &model); QVERIFY(item != 0); - QVERIFY(model.count() == 0); + QCOMPARE(model.count(), 0); QVERIFY(QMetaObject::invokeMethod(item, "addItem0")); - QVERIFY(model.count() == 2); + QCOMPARE(model.count(), 2); QVariant childData = model.data(0, 0); QQmlListModel *childModel = qobject_cast<QQmlListModel *>(childData.value<QObject *>()); QVERIFY(childModel); - QVERIFY(childModel->count() == 1); + QCOMPARE(childModel->count(), 1); QSignalSpy spyModelInserted(&model, SIGNAL(rowsInserted(QModelIndex,int,int))); QSignalSpy spyChildInserted(childModel, SIGNAL(rowsInserted(QModelIndex,int,int))); @@ -663,34 +663,34 @@ void tst_qqmllistmodelworkerscript::worker_sync() QVERIFY(QMetaObject::invokeMethod(item, "addItemViaWorker")); waitForWorker(item); - QVERIFY(model.count() == 2); - QVERIFY(childModel->count() == 1); - QVERIFY(spyModelInserted.count() == 0); - QVERIFY(spyChildInserted.count() == 0); + QCOMPARE(model.count(), 2); + QCOMPARE(childModel->count(), 1); + QCOMPARE(spyModelInserted.count(), 0); + QCOMPARE(spyChildInserted.count(), 0); QVERIFY(QMetaObject::invokeMethod(item, "doSync")); waitForWorker(item); - QVERIFY(model.count() == 2); - QVERIFY(childModel->count() == 2); - QVERIFY(spyModelInserted.count() == 0); - QVERIFY(spyChildInserted.count() == 1); + QCOMPARE(model.count(), 2); + QCOMPARE(childModel->count(), 2); + QCOMPARE(spyModelInserted.count(), 0); + QCOMPARE(spyChildInserted.count(), 1); QVERIFY(QMetaObject::invokeMethod(item, "addItemViaWorker")); waitForWorker(item); - QVERIFY(model.count() == 2); - QVERIFY(childModel->count() == 2); - QVERIFY(spyModelInserted.count() == 0); - QVERIFY(spyChildInserted.count() == 1); + QCOMPARE(model.count(), 2); + QCOMPARE(childModel->count(), 2); + QCOMPARE(spyModelInserted.count(), 0); + QCOMPARE(spyChildInserted.count(), 1); QVERIFY(QMetaObject::invokeMethod(item, "doSync")); waitForWorker(item); - QVERIFY(model.count() == 2); - QVERIFY(childModel->count() == 3); - QVERIFY(spyModelInserted.count() == 0); - QVERIFY(spyChildInserted.count() == 2); + QCOMPARE(model.count(), 2); + QCOMPARE(childModel->count(), 3); + QCOMPARE(spyModelInserted.count(), 0); + QCOMPARE(spyChildInserted.count(), 2); delete item; qApp->processEvents(); @@ -714,24 +714,24 @@ void tst_qqmllistmodelworkerscript::worker_remove_element() QSignalSpy spyModelRemoved(&model, SIGNAL(rowsRemoved(QModelIndex,int,int))); - QVERIFY(model.count() == 0); - QVERIFY(spyModelRemoved.count() == 0); + QCOMPARE(model.count(), 0); + QCOMPARE(spyModelRemoved.count(), 0); QVERIFY(QMetaObject::invokeMethod(item, "addItem")); - QVERIFY(model.count() == 1); + QCOMPARE(model.count(), 1); QVERIFY(QMetaObject::invokeMethod(item, "removeItemViaWorker")); waitForWorker(item); - QVERIFY(model.count() == 1); - QVERIFY(spyModelRemoved.count() == 0); + QCOMPARE(model.count(), 1); + QCOMPARE(spyModelRemoved.count(), 0); QVERIFY(QMetaObject::invokeMethod(item, "doSync")); waitForWorker(item); - QVERIFY(model.count() == 0); - QVERIFY(spyModelRemoved.count() == 1); + QCOMPARE(model.count(), 0); + QCOMPARE(spyModelRemoved.count(), 1); delete item; qApp->processEvents(); @@ -747,7 +747,7 @@ void tst_qqmllistmodelworkerscript::worker_remove_element() QVERIFY(QMetaObject::invokeMethod(item, "addItem")); - QVERIFY(model->count() == 1); + QCOMPARE(model->count(), 1); QVERIFY(QMetaObject::invokeMethod(item, "removeItemViaWorker")); QVERIFY(QMetaObject::invokeMethod(item, "doSync")); @@ -777,24 +777,24 @@ void tst_qqmllistmodelworkerscript::worker_remove_list() QSignalSpy spyModelRemoved(&model, SIGNAL(rowsRemoved(QModelIndex,int,int))); - QVERIFY(model.count() == 0); - QVERIFY(spyModelRemoved.count() == 0); + QCOMPARE(model.count(), 0); + QCOMPARE(spyModelRemoved.count(), 0); QVERIFY(QMetaObject::invokeMethod(item, "addList")); - QVERIFY(model.count() == 1); + QCOMPARE(model.count(), 1); QVERIFY(QMetaObject::invokeMethod(item, "removeListViaWorker")); waitForWorker(item); - QVERIFY(model.count() == 1); - QVERIFY(spyModelRemoved.count() == 0); + QCOMPARE(model.count(), 1); + QCOMPARE(spyModelRemoved.count(), 0); QVERIFY(QMetaObject::invokeMethod(item, "doSync")); waitForWorker(item); - QVERIFY(model.count() == 0); - QVERIFY(spyModelRemoved.count() == 1); + QCOMPARE(model.count(), 0); + QCOMPARE(spyModelRemoved.count(), 1); delete item; qApp->processEvents(); diff --git a/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp b/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp index b5963e2f71..274f292c38 100644 --- a/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp +++ b/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp @@ -98,7 +98,7 @@ void tst_qqmllistreference::qmllistreference() TestType tt; QQmlListReference r(&tt, "data"); - QVERIFY(r.isValid() == true); + QVERIFY(r.isValid()); QCOMPARE(r.count(), 0); tt.data.append(&tt); @@ -112,52 +112,52 @@ void tst_qqmllistreference::qmllistreference_invalid() // Invalid { QQmlListReference r; - QVERIFY(r.isValid() == false); - QVERIFY(r.object() == 0); - QVERIFY(r.listElementType() == 0); - QVERIFY(r.canAt() == false); - QVERIFY(r.canClear() == false); - QVERIFY(r.canCount() == false); - QVERIFY(r.append(0) == false); - QVERIFY(r.at(10) == 0); - QVERIFY(r.clear() == false); - QVERIFY(r.count() == 0); - QVERIFY(r.isReadable() == false); - QVERIFY(r.isManipulable() == false); + QVERIFY(!r.isValid()); + QVERIFY(!r.object()); + QVERIFY(!r.listElementType()); + QVERIFY(!r.canAt()); + QVERIFY(!r.canClear()); + QVERIFY(!r.canCount()); + QVERIFY(!r.append(0)); + QVERIFY(!r.at(10)); + QVERIFY(!r.clear()); + QCOMPARE(r.count(), 0); + QVERIFY(!r.isReadable()); + QVERIFY(!r.isManipulable()); } // Non-property { QQmlListReference r(&tt, "blah"); - QVERIFY(r.isValid() == false); - QVERIFY(r.object() == 0); - QVERIFY(r.listElementType() == 0); - QVERIFY(r.canAt() == false); - QVERIFY(r.canClear() == false); - QVERIFY(r.canCount() == false); - QVERIFY(r.append(0) == false); - QVERIFY(r.at(10) == 0); - QVERIFY(r.clear() == false); - QVERIFY(r.count() == 0); - QVERIFY(r.isReadable() == false); - QVERIFY(r.isManipulable() == false); + QVERIFY(!r.isValid()); + QVERIFY(!r.object()); + QVERIFY(!r.listElementType()); + QVERIFY(!r.canAt()); + QVERIFY(!r.canClear()); + QVERIFY(!r.canCount()); + QVERIFY(!r.append(0)); + QVERIFY(!r.at(10)); + QVERIFY(!r.clear()); + QCOMPARE(r.count(), 0); + QVERIFY(!r.isReadable()); + QVERIFY(!r.isManipulable()); } // Non-list property { QQmlListReference r(&tt, "intProperty"); - QVERIFY(r.isValid() == false); - QVERIFY(r.object() == 0); - QVERIFY(r.listElementType() == 0); - QVERIFY(r.canAt() == false); - QVERIFY(r.canClear() == false); - QVERIFY(r.canCount() == false); - QVERIFY(r.append(0) == false); - QVERIFY(r.at(10) == 0); - QVERIFY(r.clear() == false); - QVERIFY(r.count() == 0); - QVERIFY(r.isReadable() == false); - QVERIFY(r.isManipulable() == false); + QVERIFY(!r.isValid()); + QVERIFY(!r.object()); + QVERIFY(!r.listElementType()); + QVERIFY(!r.canAt()); + QVERIFY(!r.canClear()); + QVERIFY(!r.canCount()); + QVERIFY(!r.append(0)); + QVERIFY(!r.at(10)); + QVERIFY(!r.clear()); + QCOMPARE(r.count(), 0); + QVERIFY(!r.isReadable()); + QVERIFY(!r.isManipulable()); } } @@ -167,19 +167,19 @@ void tst_qqmllistreference::isValid() { QQmlListReference ref; - QVERIFY(ref.isValid() == false); + QVERIFY(!ref.isValid()); } { QQmlListReference ref(tt, "blah"); - QVERIFY(ref.isValid() == false); + QVERIFY(!ref.isValid()); } { QQmlListReference ref(tt, "data"); - QVERIFY(ref.isValid() == true); + QVERIFY(ref.isValid()); delete tt; - QVERIFY(ref.isValid() == false); + QVERIFY(!ref.isValid()); } } @@ -189,19 +189,19 @@ void tst_qqmllistreference::object() { QQmlListReference ref; - QVERIFY(ref.object() == 0); + QVERIFY(!ref.object()); } { QQmlListReference ref(tt, "blah"); - QVERIFY(ref.object() == 0); + QVERIFY(!ref.object()); } { QQmlListReference ref(tt, "data"); - QVERIFY(ref.object() == tt); + QCOMPARE(ref.object(), tt); delete tt; - QVERIFY(ref.object() == 0); + QVERIFY(!ref.object()); } } @@ -211,19 +211,19 @@ void tst_qqmllistreference::listElementType() { QQmlListReference ref; - QVERIFY(ref.listElementType() == 0); + QVERIFY(!ref.listElementType()); } { QQmlListReference ref(tt, "blah"); - QVERIFY(ref.listElementType() == 0); + QVERIFY(!ref.listElementType()); } { QQmlListReference ref(tt, "data"); - QVERIFY(ref.listElementType() == &TestType::staticMetaObject); + QCOMPARE(ref.listElementType(), &TestType::staticMetaObject); delete tt; - QVERIFY(ref.listElementType() == 0); + QVERIFY(!ref.listElementType()); } } @@ -233,26 +233,26 @@ void tst_qqmllistreference::canAppend() { QQmlListReference ref; - QVERIFY(ref.canAppend() == false); + QVERIFY(!ref.canAppend()); } { QQmlListReference ref(tt, "blah"); - QVERIFY(ref.canAppend() == false); + QVERIFY(!ref.canAppend()); } { QQmlListReference ref(tt, "data"); - QVERIFY(ref.canAppend() == true); + QVERIFY(ref.canAppend()); delete tt; - QVERIFY(ref.canAppend() == false); + QVERIFY(!ref.canAppend()); } { TestType tt; tt.property.append = 0; QQmlListReference ref(&tt, "data"); - QVERIFY(ref.canAppend() == false); + QVERIFY(!ref.canAppend()); } } @@ -262,26 +262,26 @@ void tst_qqmllistreference::canAt() { QQmlListReference ref; - QVERIFY(ref.canAt() == false); + QVERIFY(!ref.canAt()); } { QQmlListReference ref(tt, "blah"); - QVERIFY(ref.canAt() == false); + QVERIFY(!ref.canAt()); } { QQmlListReference ref(tt, "data"); - QVERIFY(ref.canAt() == true); + QVERIFY(ref.canAt()); delete tt; - QVERIFY(ref.canAt() == false); + QVERIFY(!ref.canAt()); } { TestType tt; tt.property.at = 0; QQmlListReference ref(&tt, "data"); - QVERIFY(ref.canAt() == false); + QVERIFY(!ref.canAt()); } } @@ -291,26 +291,26 @@ void tst_qqmllistreference::canClear() { QQmlListReference ref; - QVERIFY(ref.canClear() == false); + QVERIFY(!ref.canClear()); } { QQmlListReference ref(tt, "blah"); - QVERIFY(ref.canClear() == false); + QVERIFY(!ref.canClear()); } { QQmlListReference ref(tt, "data"); - QVERIFY(ref.canClear() == true); + QVERIFY(ref.canClear()); delete tt; - QVERIFY(ref.canClear() == false); + QVERIFY(!ref.canClear()); } { TestType tt; tt.property.clear = 0; QQmlListReference ref(&tt, "data"); - QVERIFY(ref.canClear() == false); + QVERIFY(!ref.canClear()); } } @@ -320,26 +320,26 @@ void tst_qqmllistreference::canCount() { QQmlListReference ref; - QVERIFY(ref.canCount() == false); + QVERIFY(!ref.canCount()); } { QQmlListReference ref(tt, "blah"); - QVERIFY(ref.canCount() == false); + QVERIFY(!ref.canCount()); } { QQmlListReference ref(tt, "data"); - QVERIFY(ref.canCount() == true); + QVERIFY(ref.canCount()); delete tt; - QVERIFY(ref.canCount() == false); + QVERIFY(!ref.canCount()); } { TestType tt; tt.property.count = 0; QQmlListReference ref(&tt, "data"); - QVERIFY(ref.canCount() == false); + QVERIFY(!ref.canCount()); } } @@ -349,26 +349,26 @@ void tst_qqmllistreference::isReadable() { QQmlListReference ref; - QVERIFY(ref.isReadable() == false); + QVERIFY(!ref.isReadable()); } { QQmlListReference ref(tt, "blah"); - QVERIFY(ref.isReadable() == false); + QVERIFY(!ref.isReadable()); } { QQmlListReference ref(tt, "data"); - QVERIFY(ref.isReadable() == true); + QVERIFY(ref.isReadable()); delete tt; - QVERIFY(ref.isReadable() == false); + QVERIFY(!ref.isReadable()); } { TestType tt; tt.property.count = 0; QQmlListReference ref(&tt, "data"); - QVERIFY(ref.isReadable() == false); + QVERIFY(!ref.isReadable()); } } @@ -378,26 +378,26 @@ void tst_qqmllistreference::isManipulable() { QQmlListReference ref; - QVERIFY(ref.isManipulable() == false); + QVERIFY(!ref.isManipulable()); } { QQmlListReference ref(tt, "blah"); - QVERIFY(ref.isManipulable() == false); + QVERIFY(!ref.isManipulable()); } { QQmlListReference ref(tt, "data"); - QVERIFY(ref.isManipulable() == true); + QVERIFY(ref.isManipulable()); delete tt; - QVERIFY(ref.isManipulable() == false); + QVERIFY(!ref.isManipulable()); } { TestType tt; tt.property.count = 0; QQmlListReference ref(&tt, "data"); - QVERIFY(ref.isManipulable() == false); + QVERIFY(!ref.isManipulable()); } } @@ -408,35 +408,35 @@ void tst_qqmllistreference::append() { QQmlListReference ref; - QVERIFY(ref.append(tt) == false); + QVERIFY(!ref.append(tt)); } { QQmlListReference ref(tt, "blah"); - QVERIFY(ref.append(tt) == false); + QVERIFY(!ref.append(tt)); } { QQmlListReference ref(tt, "data"); - QVERIFY(ref.append(tt) == true); - QVERIFY(tt->data.count() == 1); - QVERIFY(tt->data.at(0) == tt); - QVERIFY(ref.append(&object) == false); - QVERIFY(tt->data.count() == 1); - QVERIFY(tt->data.at(0) == tt); - QVERIFY(ref.append(0) == true); - QVERIFY(tt->data.count() == 2); - QVERIFY(tt->data.at(0) == tt); - QVERIFY(tt->data.at(1) == 0); + QVERIFY(ref.append(tt)); + QCOMPARE(tt->data.count(), 1); + QCOMPARE(tt->data.at(0), tt); + QVERIFY(!ref.append(&object)); + QCOMPARE(tt->data.count(), 1); + QCOMPARE(tt->data.at(0), tt); + QVERIFY(ref.append(0)); + QCOMPARE(tt->data.count(), 2); + QCOMPARE(tt->data.at(0), tt); + QVERIFY(!tt->data.at(1)); delete tt; - QVERIFY(ref.append(0) == false); + QVERIFY(!ref.append(0)); } { TestType tt; tt.property.append = 0; QQmlListReference ref(&tt, "data"); - QVERIFY(ref.append(&tt) == false); + QVERIFY(!ref.append(&tt)); } } @@ -449,21 +449,21 @@ void tst_qqmllistreference::at() { QQmlListReference ref; - QVERIFY(ref.at(0) == 0); + QVERIFY(!ref.at(0)); } { QQmlListReference ref(tt, "blah"); - QVERIFY(ref.at(0) == 0); + QVERIFY(!ref.at(0)); } { QQmlListReference ref(tt, "data"); - QVERIFY(ref.at(0) == tt); - QVERIFY(ref.at(1) == 0); - QVERIFY(ref.at(2) == tt); + QCOMPARE(ref.at(0), tt); + QVERIFY(!ref.at(1)); + QCOMPARE(ref.at(2), tt); delete tt; - QVERIFY(ref.at(0) == 0); + QVERIFY(!ref.at(0)); } { @@ -471,7 +471,7 @@ void tst_qqmllistreference::at() tt.data.append(&tt); tt.property.at = 0; QQmlListReference ref(&tt, "data"); - QVERIFY(ref.at(0) == 0); + QVERIFY(!ref.at(0)); } } @@ -484,27 +484,27 @@ void tst_qqmllistreference::clear() { QQmlListReference ref; - QVERIFY(ref.clear() == false); + QVERIFY(!ref.clear()); } { QQmlListReference ref(tt, "blah"); - QVERIFY(ref.clear() == false); + QVERIFY(!ref.clear()); } { QQmlListReference ref(tt, "data"); - QVERIFY(ref.clear() == true); - QVERIFY(tt->data.count() == 0); + QVERIFY(ref.clear()); + QCOMPARE(tt->data.count(), 0); delete tt; - QVERIFY(ref.clear() == false); + QVERIFY(!ref.clear()); } { TestType tt; tt.property.clear = 0; QQmlListReference ref(&tt, "data"); - QVERIFY(ref.clear() == false); + QVERIFY(!ref.clear()); } } @@ -517,21 +517,21 @@ void tst_qqmllistreference::count() { QQmlListReference ref; - QVERIFY(ref.count() == 0); + QCOMPARE(ref.count(), 0); } { QQmlListReference ref(tt, "blah"); - QVERIFY(ref.count() == 0); + QCOMPARE(ref.count(), 0); } { QQmlListReference ref(tt, "data"); - QVERIFY(ref.count() == 3); + QCOMPARE(ref.count(), 3); tt->data.removeAt(1); - QVERIFY(ref.count() == 2); + QCOMPARE(ref.count(), 2); delete tt; - QVERIFY(ref.count() == 0); + QCOMPARE(ref.count(), 0); } { @@ -539,7 +539,7 @@ void tst_qqmllistreference::count() tt.data.append(&tt); tt.property.count = 0; QQmlListReference ref(&tt, "data"); - QVERIFY(ref.count() == 0); + QCOMPARE(ref.count(), 0); } } @@ -551,24 +551,24 @@ void tst_qqmllistreference::copy() tt.data.append(&tt); QQmlListReference *r1 = new QQmlListReference(&tt, "data"); - QVERIFY(r1->count() == 3); + QCOMPARE(r1->count(), 3); QQmlListReference r2(*r1); QQmlListReference r3; r3 = *r1; - QVERIFY(r2.count() == 3); - QVERIFY(r3.count() == 3); + QCOMPARE(r2.count(), 3); + QCOMPARE(r3.count(), 3); delete r1; - QVERIFY(r2.count() == 3); - QVERIFY(r3.count() == 3); + QCOMPARE(r2.count(), 3); + QCOMPARE(r3.count(), 3); tt.data.removeAt(2); - QVERIFY(r2.count() == 2); - QVERIFY(r3.count() == 2); + QCOMPARE(r2.count(), 2); + QCOMPARE(r3.count(), 2); } void tst_qqmllistreference::qmlmetaproperty() @@ -580,10 +580,10 @@ void tst_qqmllistreference::qmlmetaproperty() QQmlProperty prop(&tt, QLatin1String("data")); QVariant v = prop.read(); - QVERIFY(v.userType() == qMetaTypeId<QQmlListReference>()); + QCOMPARE(v.userType(), qMetaTypeId<QQmlListReference>()); QQmlListReference ref = qvariant_cast<QQmlListReference>(v); - QVERIFY(ref.count() == 3); - QVERIFY(ref.listElementType() == &TestType::staticMetaObject); + QCOMPARE(ref.count(), 3); + QCOMPARE(ref.listElementType(), &TestType::staticMetaObject); } void tst_qqmllistreference::engineTypes() @@ -595,14 +595,14 @@ void tst_qqmllistreference::engineTypes() QVERIFY(o); QQmlProperty p1(o, QLatin1String("myList")); - QVERIFY(p1.propertyTypeCategory() == QQmlProperty::List); + QCOMPARE(p1.propertyTypeCategory(), QQmlProperty::List); QQmlProperty p2(o, QLatin1String("myList"), engine.rootContext()); - QVERIFY(p2.propertyTypeCategory() == QQmlProperty::List); + QCOMPARE(p2.propertyTypeCategory(), QQmlProperty::List); QVariant v = p2.read(); - QVERIFY(v.userType() == qMetaTypeId<QQmlListReference>()); + QCOMPARE(v.userType(), qMetaTypeId<QQmlListReference>()); QQmlListReference ref = qvariant_cast<QQmlListReference>(v); - QVERIFY(ref.count() == 2); + QCOMPARE(ref.count(), 2); QVERIFY(ref.listElementType()); QVERIFY(ref.listElementType() != &QObject::staticMetaObject); @@ -617,7 +617,7 @@ void tst_qqmllistreference::variantToList() QObject *o = component.create(); QVERIFY(o); - QVERIFY(o->property("value").userType() == qMetaTypeId<QQmlListReference>()); + QCOMPARE(o->property("value").userType(), qMetaTypeId<QQmlListReference>()); QCOMPARE(o->property("test").toInt(), 1); delete o; diff --git a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp index 011db7b363..030af07a70 100644 --- a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp +++ b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp @@ -451,7 +451,7 @@ void tst_qqmllocale::firstDayOfWeek() Q_ARG(QVariant, QVariant(locale))); QVariant val = obj->property("firstDayOfWeek"); - QVERIFY(val.type() == QVariant::Int); + QCOMPARE(val.type(), QVariant::Int); int day = int(QLocale(locale).firstDayOfWeek()); if (day == 7) // JS Date days in range 0(Sunday) to 6(Saturday) @@ -486,12 +486,12 @@ void tst_qqmllocale::weekDays() Q_ARG(QVariant, QVariant(locale))); QVariant val = obj->property("weekDays"); - QVERIFY(val.userType() == qMetaTypeId<QJSValue>()); + QCOMPARE(val.userType(), qMetaTypeId<QJSValue>()); QList<QVariant> qmlDays = val.toList(); QList<Qt::DayOfWeek> days = QLocale(locale).weekdays(); - QVERIFY(days.count() == qmlDays.count()); + QCOMPARE(days.count(), qmlDays.count()); for (int i = 0; i < days.count(); ++i) { int day = int(days.at(i)); @@ -528,12 +528,12 @@ void tst_qqmllocale::uiLanguages() Q_ARG(QVariant, QVariant(locale))); QVariant val = obj->property("uiLanguages"); - QVERIFY(val.userType() == qMetaTypeId<QJSValue>()); + QCOMPARE(val.userType(), qMetaTypeId<QJSValue>()); QList<QVariant> qmlLangs = val.toList(); QStringList langs = QLocale(locale).uiLanguages(); - QVERIFY(langs.count() == qmlLangs.count()); + QCOMPARE(langs.count(), qmlLangs.count()); for (int i = 0; i < langs.count(); ++i) { QCOMPARE(langs.at(i), qmlLangs.at(i).toString()); @@ -676,7 +676,7 @@ void tst_qqmllocale::addDateTimeFormatData(const QString &l) int i = 0; while (formats[i]) { QByteArray t(locale); - t += " "; + t += ' '; t += formats[i]; QTest::newRow(t.constData()) << l << QString(formats[i]); ++i; @@ -768,7 +768,7 @@ void tst_qqmllocale::addDateFormatData(const QString &l) int i = 0; while (formats[i]) { QByteArray t(locale); - t += " "; + t += ' '; t += formats[i]; QTest::newRow(t.constData()) << l << QString(formats[i]); ++i; @@ -860,7 +860,7 @@ void tst_qqmllocale::addTimeFormatData(const QString &l) int i = 0; while (formats[i]) { QByteArray t(locale); - t += " "; + t += ' '; t += formats[i]; QTest::newRow(t.constData()) << l << QString(formats[i]); ++i; diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp index f5423582b2..27e92f67a3 100644 --- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp +++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp @@ -126,7 +126,7 @@ void tst_qqmlmetatype::initTestCase() void tst_qqmlmetatype::qmlParserStatusCast() { - QVERIFY(QQmlMetaType::qmlType(QVariant::Int) == 0); + QVERIFY(!QQmlMetaType::qmlType(QVariant::Int)); QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()) != 0); QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>())->parserStatusCast(), -1); QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()) != 0); @@ -146,7 +146,7 @@ void tst_qqmlmetatype::qmlParserStatusCast() void tst_qqmlmetatype::qmlPropertyValueSourceCast() { - QVERIFY(QQmlMetaType::qmlType(QVariant::Int) == 0); + QVERIFY(!QQmlMetaType::qmlType(QVariant::Int)); QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()) != 0); QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>())->propertyValueSourceCast(), -1); QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()) != 0); @@ -166,7 +166,7 @@ void tst_qqmlmetatype::qmlPropertyValueSourceCast() void tst_qqmlmetatype::qmlPropertyValueInterceptorCast() { - QVERIFY(QQmlMetaType::qmlType(QVariant::Int) == 0); + QVERIFY(!QQmlMetaType::qmlType(QVariant::Int)); QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()) != 0); QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>())->propertyValueInterceptorCast(), -1); QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()) != 0); @@ -224,8 +224,8 @@ void tst_qqmlmetatype::isList() void tst_qqmlmetatype::defaultObject() { - QVERIFY(QQmlMetaType::defaultProperty(&QObject::staticMetaObject).name() == 0); - QVERIFY(QQmlMetaType::defaultProperty(&ParserStatusTestType::staticMetaObject).name() == 0); + QVERIFY(!QQmlMetaType::defaultProperty(&QObject::staticMetaObject).name()); + QVERIFY(!QQmlMetaType::defaultProperty(&ParserStatusTestType::staticMetaObject).name()); QCOMPARE(QString(QQmlMetaType::defaultProperty(&TestType::staticMetaObject).name()), QString("foo")); QObject o; @@ -233,8 +233,8 @@ void tst_qqmlmetatype::defaultObject() ParserStatusTestType p; QVERIFY(QQmlMetaType::defaultProperty((QObject *)0).name() == 0); - QVERIFY(QQmlMetaType::defaultProperty(&o).name() == 0); - QVERIFY(QQmlMetaType::defaultProperty(&p).name() == 0); + QVERIFY(!QQmlMetaType::defaultProperty(&o).name()); + QVERIFY(!QQmlMetaType::defaultProperty(&p).name()); QCOMPARE(QString(QQmlMetaType::defaultProperty(&t).name()), QString("foo")); } @@ -270,8 +270,8 @@ void tst_qqmlmetatype::compositeType() QQmlType *type = QQmlMetaType::qmlType(QString("ImplicitType"), QString(""), 1, 0); QVERIFY(type); - QVERIFY(type->module() == QLatin1String("")); - QVERIFY(type->elementName() == QLatin1String("ImplicitType")); + QVERIFY(type->module().isEmpty()); + QCOMPARE(type->elementName(), QLatin1String("ImplicitType")); QCOMPARE(type->qmlTypeName(), QLatin1String("ImplicitType")); QCOMPARE(type->sourceUrl(), testFileUrl("ImplicitType.qml")); } diff --git a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp index 0e326abad9..89477609ca 100644 --- a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp +++ b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp @@ -110,8 +110,8 @@ void tst_qqmlmoduleplugin::initTestCase() QList<QByteArray> actual; \ for (int ii = 0; ii < errors.count(); ++ii) { \ const QQmlError &error = errors.at(ii); \ - QByteArray errorStr = QByteArray::number(error.line()) + ":" + \ - QByteArray::number(error.column()) + ":" + \ + QByteArray errorStr = QByteArray::number(error.line()) + ':' + \ + QByteArray::number(error.column()) + ':' + \ error.description().toUtf8(); \ actual << errorStr; \ } \ @@ -202,8 +202,11 @@ void tst_qqmlmoduleplugin::incorrectPluginCase() caseSensitive = false; QString libname = "PluGin.dll"; #endif - if (!caseSensitive) - expectedError = QLatin1String("plugin cannot be loaded for module \"org.qtproject.WrongCase\": File name case mismatch for \"") + QDir(m_importsDirectory).filePath("org/qtproject/WrongCase/" + libname) + QLatin1String("\""); + if (!caseSensitive) { + expectedError = QLatin1String("plugin cannot be loaded for module \"org.qtproject.WrongCase\": File name case mismatch for \"") + + QDir(m_importsDirectory).filePath("org/qtproject/WrongCase/" + libname) + + QLatin1Char('"'); + } #endif QCOMPARE(errors.at(0).description(), expectedError); @@ -236,9 +239,7 @@ void tst_qqmlmoduleplugin::importPluginWithQmlFile() void tst_qqmlmoduleplugin::remoteImportWithQuotedUrl() { - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(m_dataImportsDirectory); + ThreadedTestHTTPServer server(m_dataImportsDirectory); QQmlEngine engine; QQmlComponent component(&engine); diff --git a/tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro b/tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro new file mode 100644 index 0000000000..f8232f8854 --- /dev/null +++ b/tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro @@ -0,0 +1,10 @@ +CONFIG += testcase +TARGET = tst_qqmlobjectmodel +osx:CONFIG -= app_bundle + +SOURCES += tst_qqmlobjectmodel.cpp + +CONFIG += parallel_test + +QT += qml testlib +QT += core-private qml-private diff --git a/tests/auto/qml/qqmlobjectmodel/tst_qqmlobjectmodel.cpp b/tests/auto/qml/qqmlobjectmodel/tst_qqmlobjectmodel.cpp new file mode 100644 index 0000000000..001739e38d --- /dev/null +++ b/tests/auto/qml/qqmlobjectmodel/tst_qqmlobjectmodel.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtQml/private/qqmlobjectmodel_p.h> +#include <QtTest/qsignalspy.h> +#include <QtTest/qtest.h> + +class tst_QQmlObjectModel : public QObject +{ + Q_OBJECT + +private slots: + void changes(); +}; + +static bool compareItems(QQmlObjectModel *model, const QObjectList &items) +{ + for (int i = 0; i < items.count(); ++i) { + if (model->get(i) != items.at(i)) + return false; + } + return true; +} + +void tst_QQmlObjectModel::changes() +{ + QQmlObjectModel model; + + QSignalSpy countSpy(&model, SIGNAL(countChanged())); + QSignalSpy childrenSpy(&model, SIGNAL(childrenChanged())); + + int count = 0; + int countSignals = 0; + int childrenSignals = 0; + + QObjectList items; + QObject item0, item1, item2, item3; + + // append(item0) -> [item0] + model.append(&item0); items.append(&item0); + QCOMPARE(model.count(), ++count); + QVERIFY(compareItems(&model, items)); + QCOMPARE(countSpy.count(), ++countSignals); + QCOMPARE(childrenSpy.count(), ++childrenSignals); + + // insert(0, item1) -> [item1, item0] + model.insert(0, &item1); items.insert(0, &item1); + QCOMPARE(model.count(), ++count); + QVERIFY(compareItems(&model, items)); + QCOMPARE(countSpy.count(), ++countSignals); + QCOMPARE(childrenSpy.count(), ++childrenSignals); + + // append(item2) -> [item1, item0, item2] + model.append(&item2); items.append(&item2); + QCOMPARE(model.count(), ++count); + QVERIFY(compareItems(&model, items)); + QCOMPARE(countSpy.count(), ++countSignals); + QCOMPARE(childrenSpy.count(), ++childrenSignals); + + // insert(2, item3) -> [item1, item0, item3, item2] + model.insert(2, &item3); items.insert(2, &item3); + QCOMPARE(model.count(), ++count); + QVERIFY(compareItems(&model, items)); + QCOMPARE(countSpy.count(), ++countSignals); + QCOMPARE(childrenSpy.count(), ++childrenSignals); + + // move(0, 1) -> [item0, item1, item3, item2] + model.move(0, 1); items.move(0, 1); + QCOMPARE(model.count(), count); + QVERIFY(compareItems(&model, items)); + QCOMPARE(countSpy.count(), countSignals); + QCOMPARE(childrenSpy.count(), ++childrenSignals); + + // move(3, 2) -> [item0, item1, item2, item3] + model.move(3, 2); items.move(3, 2); + QCOMPARE(model.count(), count); + QVERIFY(compareItems(&model, items)); + QCOMPARE(countSpy.count(), countSignals); + QCOMPARE(childrenSpy.count(), ++childrenSignals); + + // remove(0) -> [item1, item2, item3] + model.remove(0); items.removeAt(0); + QCOMPARE(model.count(), --count); + QVERIFY(compareItems(&model, items)); + QCOMPARE(countSpy.count(), ++countSignals); + QCOMPARE(childrenSpy.count(), ++childrenSignals); + + // remove(2) -> [item1, item2] + model.remove(2); items.removeAt(2); + QCOMPARE(model.count(), --count); + QVERIFY(compareItems(&model, items)); + QCOMPARE(countSpy.count(), ++countSignals); + QCOMPARE(childrenSpy.count(), ++childrenSignals); + + // clear() -> [] + model.clear(); items.clear(); + QCOMPARE(model.count(), 0); + QVERIFY(compareItems(&model, items)); + QCOMPARE(countSpy.count(), ++countSignals); + QCOMPARE(childrenSpy.count(), ++childrenSignals); +} + +QTEST_MAIN(tst_QQmlObjectModel) + +#include "tst_qqmlobjectmodel.moc" diff --git a/tests/auto/qml/qqmlopenmetaobject/qqmlopenmetaobject.pro b/tests/auto/qml/qqmlopenmetaobject/qqmlopenmetaobject.pro new file mode 100644 index 0000000000..c81394e77e --- /dev/null +++ b/tests/auto/qml/qqmlopenmetaobject/qqmlopenmetaobject.pro @@ -0,0 +1,9 @@ +CONFIG += testcase +TARGET = tst_qqmlopenmetaobject +osx:CONFIG -= app_bundle + +SOURCES += tst_qqmlopenmetaobject.cpp + +CONFIG += parallel_test +QT += core-private gui-private qml-private testlib +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlopenmetaobject/tst_qqmlopenmetaobject.cpp b/tests/auto/qml/qqmlopenmetaobject/tst_qqmlopenmetaobject.cpp new file mode 100644 index 0000000000..429f45b875 --- /dev/null +++ b/tests/auto/qml/qqmlopenmetaobject/tst_qqmlopenmetaobject.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include <private/qqmlopenmetaobject_p.h> +#include <QtQml/qqmlengine.h> + +class tst_qqmlopenmetaobject : public QObject +{ + Q_OBJECT +public: + tst_qqmlopenmetaobject() {} + +private slots: + void createProperties(); +}; + +class CustomObject: public QObject +{ + Q_OBJECT +public: + CustomObject(QObject *parent = 0) + : QObject(parent) {} +}; + +void tst_qqmlopenmetaobject::createProperties() +{ + QQmlEngine engine; + CustomObject object; + const QQmlRefPointer<QQmlOpenMetaObjectType> mot = new QQmlOpenMetaObjectType(object.metaObject(), &engine); + QQmlOpenMetaObject *const mo = new QQmlOpenMetaObject(&object, mot); + mo->setCached(true); + mot->createProperty("customProperty"); + QVERIFY(true); +} + +QTEST_MAIN(tst_qqmlopenmetaobject) + +#include "tst_qqmlopenmetaobject.moc" diff --git a/tests/auto/qml/qqmlproperty/data/floatToStringPrecision.qml b/tests/auto/qml/qqmlproperty/data/floatToStringPrecision.qml new file mode 100644 index 0000000000..a0429e0cc8 --- /dev/null +++ b/tests/auto/qml/qqmlproperty/data/floatToStringPrecision.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +QtObject { + property double a: 3.4 + property string b: a + + property double c: 0.035003945 + property string d: c +} + diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index a8b06ffa71..6ada14ce79 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -147,6 +147,7 @@ private slots: void registeredCompositeTypeProperty(); void deeplyNestedObject(); void readOnlyDynamicProperties(); + void floatToStringPrecision(); void copy(); private: @@ -159,10 +160,10 @@ void tst_qqmlproperty::qmlmetaproperty() QObject *obj = new QObject; - QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); - QVERIFY(binding != 0); + QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); + QVERIFY(binding); QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(obj, QObjectPrivate::get(obj)->signalIndex("destroyed()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1); - QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr); + QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr); QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted()); QCOMPARE(prop.name(), QString()); @@ -188,12 +189,12 @@ void tst_qqmlproperty::qmlmetaproperty() QCOMPARE(prop.propertyTypeCategory(), QQmlProperty::InvalidCategory); QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); - QVERIFY(prop.property().name() == 0); - QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); - QVERIFY(binding == 0); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); + QVERIFY(!prop.property().name()); + QVERIFY(!QQmlPropertyPrivate::binding(prop)); + QQmlPropertyPrivate::setBinding(prop, binding.data()); + QVERIFY(binding->ref == 1); + QVERIFY(!QQmlPropertyPrivate::signalExpression(prop)); + QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QVERIFY(sigExprWatcher.wasDeleted()); QCOMPARE(prop.index(), -1); QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -255,7 +256,7 @@ void tst_qqmlproperty::registeredCompositeTypeProperty() QQmlProperty p1e(obj, "first", &engine); QQmlProperty p2e(obj, "second", &engine); QQmlProperty p3e(obj, "third", &engine); - QVERIFY(p1.propertyType() == p2.propertyType()); + QCOMPARE(p1.propertyType(), p2.propertyType()); QVERIFY(p1.propertyType() != p3.propertyType()); // check that the values are retrievable from CPP @@ -293,7 +294,7 @@ void tst_qqmlproperty::registeredCompositeTypeProperty() QQmlProperty lp2e(obj, "sclistOne", &engine); QQmlProperty lp3e(obj, "sclistTwo", &engine); QVERIFY(lp1e.propertyType() != lp2e.propertyType()); - QVERIFY(lp2e.propertyType() == lp3e.propertyType()); + QCOMPARE(lp2e.propertyType(), lp3e.propertyType()); // check that the list values are retrievable from CPP QVariant firstList = obj->property("fclist"); @@ -408,10 +409,10 @@ void tst_qqmlproperty::qmlmetaproperty_object() { QQmlProperty prop(&object); - QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); - QVERIFY(binding != 0); + QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); + QVERIFY(binding); QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&object, QObjectPrivate::get(&object)->signalIndex("destroyed()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1); - QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr); + QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr); QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted()); QObject *obj = new QObject; @@ -439,12 +440,12 @@ void tst_qqmlproperty::qmlmetaproperty_object() QCOMPARE(prop.propertyTypeCategory(), QQmlProperty::InvalidCategory); QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); - QVERIFY(prop.property().name() == 0); - QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); - QVERIFY(binding == 0); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); + QVERIFY(!prop.property().name()); + QVERIFY(!QQmlPropertyPrivate::binding(prop)); + QQmlPropertyPrivate::setBinding(prop, binding.data()); + QVERIFY(binding->ref == 1); + QVERIFY(!QQmlPropertyPrivate::signalExpression(prop)); + QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QVERIFY(sigExprWatcher.wasDeleted()); QCOMPARE(prop.index(), -1); QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -455,11 +456,11 @@ void tst_qqmlproperty::qmlmetaproperty_object() { QQmlProperty prop(&dobject); - QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); static_cast<QQmlBinding *>(binding.data())->setTarget(prop); - QVERIFY(binding != 0); + QVERIFY(binding); QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QObjectPrivate::get(&dobject)->signalIndex("clicked()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1); - QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr); + QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr); QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted()); QObject *obj = new QObject; @@ -488,13 +489,13 @@ void tst_qqmlproperty::qmlmetaproperty_object() QCOMPARE(prop.propertyType(), (int)QVariant::Int); QCOMPARE(prop.propertyTypeName(), "int"); QCOMPARE(QString(prop.property().name()), QString("defaultProperty")); - QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); + QVERIFY(!QQmlPropertyPrivate::binding(prop)); QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: Unable to assign null to int"); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); - QVERIFY(binding != 0); - QVERIFY(QQmlPropertyPrivate::binding(prop) == binding.data()); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); + QVERIFY(binding); + QCOMPARE(QQmlPropertyPrivate::binding(prop), binding.data()); + QVERIFY(!QQmlPropertyPrivate::signalExpression(prop)); + QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QVERIFY(sigExprWatcher.wasDeleted()); QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty")); QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -511,10 +512,10 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() { QQmlProperty prop(&object, QString("defaultProperty")); - QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); - QVERIFY(binding != 0); + QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); + QVERIFY(binding); QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&object, QObjectPrivate::get(&object)->signalIndex("destroyed()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1); - QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr); + QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr); QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted()); QObject *obj = new QObject; @@ -542,12 +543,12 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() QCOMPARE(prop.propertyTypeCategory(), QQmlProperty::InvalidCategory); QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); - QVERIFY(prop.property().name() == 0); - QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); - QVERIFY(binding == 0); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); + QVERIFY(!prop.property().name()); + QVERIFY(!QQmlPropertyPrivate::binding(prop)); + QQmlPropertyPrivate::setBinding(prop, binding.data()); + QVERIFY(binding->ref == 1); + QVERIFY(!QQmlPropertyPrivate::signalExpression(prop)); + QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QVERIFY(sigExprWatcher.wasDeleted()); QCOMPARE(prop.index(), -1); QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -558,11 +559,11 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() { QQmlProperty prop(&dobject, QString("defaultProperty")); - QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); static_cast<QQmlBinding *>(binding.data())->setTarget(prop); - QVERIFY(binding != 0); + QVERIFY(binding); QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QObjectPrivate::get(&dobject)->signalIndex("clicked()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1); - QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr); + QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr); QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted()); QObject *obj = new QObject; @@ -591,13 +592,13 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() QCOMPARE(prop.propertyType(), (int)QVariant::Int); QCOMPARE(prop.propertyTypeName(), "int"); QCOMPARE(QString(prop.property().name()), QString("defaultProperty")); - QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); + QVERIFY(!QQmlPropertyPrivate::binding(prop)); QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: Unable to assign null to int"); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); - QVERIFY(binding != 0); - QVERIFY(QQmlPropertyPrivate::binding(prop) == binding.data()); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); + QVERIFY(binding); + QCOMPARE(QQmlPropertyPrivate::binding(prop), binding.data()); + QVERIFY(!QQmlPropertyPrivate::signalExpression(prop)); + QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QVERIFY(sigExprWatcher.wasDeleted()); QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty")); QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -608,11 +609,11 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() { QQmlProperty prop(&dobject, QString("onClicked")); - QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); static_cast<QQmlBinding *>(binding.data())->setTarget(prop); - QVERIFY(binding != 0); + QVERIFY(binding); QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QQmlPropertyPrivate::get(prop)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1); - QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr); + QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr); QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted()); QObject *obj = new QObject; @@ -641,13 +642,13 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); QCOMPARE(prop.property().name(), (const char *)0); - QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); - QVERIFY(binding == 0); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); + QVERIFY(!QQmlPropertyPrivate::binding(prop)); + QQmlPropertyPrivate::setBinding(prop, binding.data()); + QVERIFY(binding->ref == 1); + QVERIFY(!QQmlPropertyPrivate::signalExpression(prop)); + QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QVERIFY(!sigExprWatcher.wasDeleted()); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == sigExpr); + QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr); QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("clicked()")); QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -657,11 +658,11 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() { QQmlProperty prop(&dobject, QString("onPropertyWithNotifyChanged")); - QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); static_cast<QQmlBinding *>(binding.data())->setTarget(prop); - QVERIFY(binding != 0); + QVERIFY(binding); QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QQmlPropertyPrivate::get(prop)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1); - QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr); + QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr); QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted()); QObject *obj = new QObject; @@ -690,13 +691,13 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); QCOMPARE(prop.property().name(), (const char *)0); - QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); - QVERIFY(binding == 0); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); + QVERIFY(!QQmlPropertyPrivate::binding(prop)); + QQmlPropertyPrivate::setBinding(prop, binding.data()); + QVERIFY(binding->ref == 1); + QVERIFY(!QQmlPropertyPrivate::signalExpression(prop)); + QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QVERIFY(!sigExprWatcher.wasDeleted()); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == sigExpr); + QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr); QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()")); QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -712,10 +713,10 @@ void tst_qqmlproperty::qmlmetaproperty_object_context() { QQmlProperty prop(&object, engine.rootContext()); - QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); - QVERIFY(binding != 0); + QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); + QVERIFY(binding); QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&object, QObjectPrivate::get(&object)->signalIndex("destroyed()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1); - QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr); + QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr); QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted()); QObject *obj = new QObject; @@ -743,12 +744,12 @@ void tst_qqmlproperty::qmlmetaproperty_object_context() QCOMPARE(prop.propertyTypeCategory(), QQmlProperty::InvalidCategory); QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); - QVERIFY(prop.property().name() == 0); - QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); - QVERIFY(binding == 0); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); + QVERIFY(!prop.property().name()); + QVERIFY(!QQmlPropertyPrivate::binding(prop)); + QQmlPropertyPrivate::setBinding(prop, binding.data()); + QVERIFY(binding->ref == 1); + QVERIFY(!QQmlPropertyPrivate::signalExpression(prop)); + QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QVERIFY(sigExprWatcher.wasDeleted()); QCOMPARE(prop.index(), -1); QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -759,11 +760,11 @@ void tst_qqmlproperty::qmlmetaproperty_object_context() { QQmlProperty prop(&dobject, engine.rootContext()); - QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); static_cast<QQmlBinding *>(binding.data())->setTarget(prop); - QVERIFY(binding != 0); + QVERIFY(binding); QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QObjectPrivate::get(&dobject)->signalIndex("clicked()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1); - QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr); + QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr); QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted()); QObject *obj = new QObject; @@ -792,13 +793,13 @@ void tst_qqmlproperty::qmlmetaproperty_object_context() QCOMPARE(prop.propertyType(), (int)QVariant::Int); QCOMPARE(prop.propertyTypeName(), "int"); QCOMPARE(QString(prop.property().name()), QString("defaultProperty")); - QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); + QVERIFY(!QQmlPropertyPrivate::binding(prop)); QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: Unable to assign null to int"); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); - QVERIFY(binding != 0); - QVERIFY(QQmlPropertyPrivate::binding(prop) == binding.data()); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); + QVERIFY(binding); + QCOMPARE(QQmlPropertyPrivate::binding(prop), binding.data()); + QVERIFY(!QQmlPropertyPrivate::signalExpression(prop)); + QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QVERIFY(sigExprWatcher.wasDeleted()); QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty")); QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -815,10 +816,10 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() { QQmlProperty prop(&object, QString("defaultProperty"), engine.rootContext()); - QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); - QVERIFY(binding != 0); + QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); + QVERIFY(binding); QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&object, QObjectPrivate::get(&object)->signalIndex("destroyed()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1); - QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr); + QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr); QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted()); QObject *obj = new QObject; @@ -846,12 +847,12 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.propertyTypeCategory(), QQmlProperty::InvalidCategory); QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); - QVERIFY(prop.property().name() == 0); - QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); - QVERIFY(binding == 0); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); + QVERIFY(!prop.property().name()); + QVERIFY(!QQmlPropertyPrivate::binding(prop)); + QQmlPropertyPrivate::setBinding(prop, binding.data()); + QVERIFY(binding->ref == 1); + QVERIFY(!QQmlPropertyPrivate::signalExpression(prop)); + QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QVERIFY(sigExprWatcher.wasDeleted()); QCOMPARE(prop.index(), -1); QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -862,11 +863,11 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() { QQmlProperty prop(&dobject, QString("defaultProperty"), engine.rootContext()); - QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); static_cast<QQmlBinding *>(binding.data())->setTarget(prop); - QVERIFY(binding != 0); + QVERIFY(binding); QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QObjectPrivate::get(&dobject)->signalIndex("clicked()"), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1); - QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr); + QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr); QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted()); QObject *obj = new QObject; @@ -895,13 +896,13 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.propertyType(), (int)QVariant::Int); QCOMPARE(prop.propertyTypeName(), "int"); QCOMPARE(QString(prop.property().name()), QString("defaultProperty")); - QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); + QVERIFY(!QQmlPropertyPrivate::binding(prop)); QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: Unable to assign null to int"); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); - QVERIFY(binding != 0); - QVERIFY(QQmlPropertyPrivate::binding(prop) == binding.data()); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); + QVERIFY(binding); + QCOMPARE(QQmlPropertyPrivate::binding(prop), binding.data()); + QVERIFY(!QQmlPropertyPrivate::signalExpression(prop)); + QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QVERIFY(sigExprWatcher.wasDeleted()); QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty")); QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -912,11 +913,11 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() { QQmlProperty prop(&dobject, QString("onClicked"), engine.rootContext()); - QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); static_cast<QQmlBinding *>(binding.data())->setTarget(prop); - QVERIFY(binding != 0); + QVERIFY(binding); QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QQmlPropertyPrivate::get(prop)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1); - QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr); + QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr); QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted()); QObject *obj = new QObject; @@ -945,13 +946,13 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); QCOMPARE(prop.property().name(), (const char *)0); - QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); - QVERIFY(binding == 0); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); + QVERIFY(!QQmlPropertyPrivate::binding(prop)); + QQmlPropertyPrivate::setBinding(prop, binding.data()); + QVERIFY(binding->ref == 1); + QVERIFY(!QQmlPropertyPrivate::signalExpression(prop)); + QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QVERIFY(!sigExprWatcher.wasDeleted()); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == sigExpr); + QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr); QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("clicked()")); QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -961,11 +962,11 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() { QQmlProperty prop(&dobject, QString("onPropertyWithNotifyChanged"), engine.rootContext()); - QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + QQmlAbstractBinding::Ptr binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); static_cast<QQmlBinding *>(binding.data())->setTarget(prop); - QVERIFY(binding != 0); + QVERIFY(binding); QQmlBoundSignalExpression *sigExpr = new QQmlBoundSignalExpression(&dobject, QQmlPropertyPrivate::get(prop)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1); - QQmlAbstractExpression::DeleteWatcher sigExprWatcher(sigExpr); + QQmlJavaScriptExpression::DeleteWatcher sigExprWatcher(sigExpr); QVERIFY(sigExpr != 0 && !sigExprWatcher.wasDeleted()); QObject *obj = new QObject; @@ -994,13 +995,13 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); QCOMPARE(prop.property().name(), (const char *)0); - QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); - QVERIFY(binding == 0); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); - QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); + QVERIFY(!QQmlPropertyPrivate::binding(prop)); + QQmlPropertyPrivate::setBinding(prop, binding.data()); + QVERIFY(binding->ref == 1); + QVERIFY(!QQmlPropertyPrivate::signalExpression(prop)); + QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr); QVERIFY(!sigExprWatcher.wasDeleted()); - QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == sigExpr); + QCOMPARE(QQmlPropertyPrivate::signalExpression(prop), sigExpr); QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()")); QCOMPARE(QQmlPropertyPrivate::valueTypeCoreIndex(prop), -1); @@ -1146,7 +1147,7 @@ void tst_qqmlproperty::read() QQmlProperty p(&o, "onClicked"); QCOMPARE(p.read(), QVariant()); - QVERIFY(0 == QQmlPropertyPrivate::takeSignalExpression(p, new QQmlBoundSignalExpression(&o, QQmlPropertyPrivate::get(p)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1))); + QQmlPropertyPrivate::takeSignalExpression(p, new QQmlBoundSignalExpression(&o, QQmlPropertyPrivate::get(p)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1)); QVERIFY(0 != QQmlPropertyPrivate::signalExpression(p)); QCOMPARE(p.read(), QVariant()); @@ -1158,7 +1159,7 @@ void tst_qqmlproperty::read() QQmlProperty p(&o, "onPropertyWithNotifyChanged"); QCOMPARE(p.read(), QVariant()); - QVERIFY(0 == QQmlPropertyPrivate::takeSignalExpression(p, new QQmlBoundSignalExpression(&o, QQmlPropertyPrivate::get(p)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1))); + QQmlPropertyPrivate::takeSignalExpression(p, new QQmlBoundSignalExpression(&o, QQmlPropertyPrivate::get(p)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1)); QVERIFY(0 != QQmlPropertyPrivate::signalExpression(p)); QCOMPARE(p.read(), QVariant()); @@ -1203,7 +1204,7 @@ void tst_qqmlproperty::read() QCOMPARE(p.propertyTypeCategory(), QQmlProperty::Object); QCOMPARE(p.propertyType(), qMetaTypeId<MyQmlObject*>()); QVariant v = p.read(); - QVERIFY(v.userType() == QMetaType::QObjectStar); + QCOMPARE(v.userType(), int(QMetaType::QObjectStar)); QVERIFY(qvariant_cast<QObject *>(v) == o.qmlObject()); } { @@ -1217,7 +1218,7 @@ void tst_qqmlproperty::read() QVERIFY(p.propertyType() != QMetaType::QObjectStar); QVariant v = p.read(); - QVERIFY(v.userType() == QMetaType::QObjectStar); + QCOMPARE(v.userType(), int(QMetaType::QObjectStar)); QCOMPARE(qvariant_cast<QObject *>(v)->property("a").toInt(), 10); QCOMPARE(qvariant_cast<QObject *>(v)->property("b").toInt(), 19); } @@ -1227,7 +1228,7 @@ void tst_qqmlproperty::read() QVERIFY(object != 0); QVariant v = QQmlProperty::read(object, "test", &engine); - QVERIFY(v.userType() == QMetaType::QObjectStar); + QCOMPARE(v.userType(), int(QMetaType::QObjectStar)); QCOMPARE(qvariant_cast<QObject *>(v)->property("a").toInt(), 10); QCOMPARE(qvariant_cast<QObject *>(v)->property("b").toInt(), 19); } @@ -1337,7 +1338,7 @@ void tst_qqmlproperty::write() QQmlProperty p(&o, "onClicked"); QCOMPARE(p.write(QVariant("console.log(1921)")), false); - QVERIFY(0 == QQmlPropertyPrivate::takeSignalExpression(p, new QQmlBoundSignalExpression(&o, QQmlPropertyPrivate::get(p)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1))); + QQmlPropertyPrivate::takeSignalExpression(p, new QQmlBoundSignalExpression(&o, QQmlPropertyPrivate::get(p)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1)); QVERIFY(0 != QQmlPropertyPrivate::signalExpression(p)); QCOMPARE(p.write(QVariant("console.log(1921)")), false); @@ -1351,7 +1352,7 @@ void tst_qqmlproperty::write() QQmlProperty p(&o, "onPropertyWithNotifyChanged"); QCOMPARE(p.write(QVariant("console.log(1921)")), false); - QVERIFY(0 == QQmlPropertyPrivate::takeSignalExpression(p, new QQmlBoundSignalExpression(&o, QQmlPropertyPrivate::get(p)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1))); + QQmlPropertyPrivate::takeSignalExpression(p, new QQmlBoundSignalExpression(&o, QQmlPropertyPrivate::get(p)->signalIndex(), QQmlContextData::get(engine.rootContext()), 0, QLatin1String("null"), QString(), -1, -1)); QVERIFY(0 != QQmlPropertyPrivate::signalExpression(p)); QCOMPARE(p.write(QVariant("console.log(1921)")), false); @@ -1643,7 +1644,7 @@ void tst_qqmlproperty::writeObjectToList() MyContainer *container = qobject_cast<MyContainer*>(containerComponent.create()); QVERIFY(container != 0); QQmlListReference list(container, "children"); - QVERIFY(list.count() == 1); + QCOMPARE(list.count(), 1); MyQmlObject *object = new MyQmlObject; QQmlProperty prop(container, "children"); @@ -1659,7 +1660,7 @@ void tst_qqmlproperty::writeListToList() MyContainer *container = qobject_cast<MyContainer*>(containerComponent.create()); QVERIFY(container != 0); QQmlListReference list(container, "children"); - QVERIFY(list.count() == 1); + QCOMPARE(list.count(), 1); QList<QObject*> objList; objList << new MyQmlObject() << new MyQmlObject() << new MyQmlObject() << new MyQmlObject(); @@ -2054,6 +2055,27 @@ void tst_qqmlproperty::readOnlyDynamicProperties() delete obj; } +void tst_qqmlproperty::floatToStringPrecision() +{ + QQmlComponent comp(&engine, testFileUrl("floatToStringPrecision.qml")); + QObject *obj = comp.create(); + QVERIFY(obj != 0); + + QCOMPARE(obj->property("a").toDouble(), 3.4); + QEXPECT_FAIL("", "QVariant's double-to-string conversion is worse than V4's.", Continue); + QCOMPARE(obj->property("a").toString(), QLatin1String("3.4")); + QCOMPARE(obj->property("b").toDouble(), 3.4); + QCOMPARE(obj->property("b").toString(), QLatin1String("3.4")); + + QCOMPARE(obj->property("c").toDouble(), 0.035003945); + QEXPECT_FAIL("", "QVariant's double-to-string conversion is worse than V4's.", Continue); + QCOMPARE(obj->property("c").toString(), QLatin1String("0.035003945")); + QCOMPARE(obj->property("d").toDouble(), 0.035003945); + QCOMPARE(obj->property("d").toString(), QLatin1String("0.035003945")); + + delete obj; +} + void tst_qqmlproperty::initTestCase() { QQmlDataTest::initTestCase(); diff --git a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp index ce2aab49c3..a5ae27d446 100644 --- a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp +++ b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp @@ -34,6 +34,7 @@ #include <qtest.h> #include <private/qqmlpropertycache_p.h> #include <QtQml/qqmlengine.h> +#include <private/qv8engine_p.h> #include "../../shared/util.h" class tst_qqmlpropertycache : public QObject @@ -102,10 +103,11 @@ QQmlPropertyData *cacheProperty(QQmlPropertyCache *cache, const char *name) void tst_qqmlpropertycache::properties() { QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(&engine, metaObject)); + QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(v4, metaObject)); QQmlPropertyData *data; QVERIFY(data = cacheProperty(cache, "propertyA")); @@ -124,10 +126,11 @@ void tst_qqmlpropertycache::properties() void tst_qqmlpropertycache::propertiesDerived() { QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(&engine, &BaseObject::staticMetaObject)); + QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(v4, &BaseObject::staticMetaObject)); QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject())); QQmlPropertyData *data; @@ -147,10 +150,11 @@ void tst_qqmlpropertycache::propertiesDerived() void tst_qqmlpropertycache::methods() { QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(&engine, metaObject)); + QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(v4, metaObject)); QQmlPropertyData *data; QVERIFY(data = cacheProperty(cache, "slotA")); @@ -181,10 +185,11 @@ void tst_qqmlpropertycache::methods() void tst_qqmlpropertycache::methodsDerived() { QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(&engine, &BaseObject::staticMetaObject)); + QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(v4, &BaseObject::staticMetaObject)); QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject())); QQmlPropertyData *data; @@ -216,10 +221,11 @@ void tst_qqmlpropertycache::methodsDerived() void tst_qqmlpropertycache::signalHandlers() { QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(&engine, metaObject)); + QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(v4, metaObject)); QQmlPropertyData *data; QVERIFY(data = cacheProperty(cache, "onSignalA")); @@ -244,10 +250,11 @@ void tst_qqmlpropertycache::signalHandlers() void tst_qqmlpropertycache::signalHandlersDerived() { QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(&engine, &BaseObject::staticMetaObject)); + QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(v4, &BaseObject::staticMetaObject)); QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject())); QQmlPropertyData *data; diff --git a/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp b/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp index 4860602a45..2f3754e42d 100644 --- a/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp +++ b/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp @@ -104,7 +104,7 @@ void tst_QQmlPropertyMap::insert() QQmlPropertyMap map; map.insert(QLatin1String("key1"),100); map.insert(QLatin1String("key2"),200); - QVERIFY(map.keys().count() == 2); + QCOMPARE(map.keys().count(), 2); QVERIFY(map.contains(QLatin1String("key1"))); QCOMPARE(map.value(QLatin1String("key1")), QVariant(100)); @@ -117,33 +117,33 @@ void tst_QQmlPropertyMap::insert() //QQmlPropertyMap has an invokable keys() method QTest::ignoreMessage(QtWarningMsg, "Creating property with name \"keys\" is not permitted, conflicts with internal symbols."); map.insert(QLatin1String("keys"), 1); - QVERIFY(map.keys().count() == 2); + QCOMPARE(map.keys().count(), 2); QVERIFY(!map.contains(QLatin1String("keys"))); QVERIFY(map.value(QLatin1String("keys")).isNull()); //QQmlPropertyMap has a deleteLater() slot QTest::ignoreMessage(QtWarningMsg, "Creating property with name \"deleteLater\" is not permitted, conflicts with internal symbols."); map.insert(QLatin1String("deleteLater"), 1); - QVERIFY(map.keys().count() == 2); + QCOMPARE(map.keys().count(), 2); QVERIFY(!map.contains(QLatin1String("deleteLater"))); QVERIFY(map.value(QLatin1String("deleteLater")).isNull()); //QQmlPropertyMap has an valueChanged() signal QTest::ignoreMessage(QtWarningMsg, "Creating property with name \"valueChanged\" is not permitted, conflicts with internal symbols."); map.insert(QLatin1String("valueChanged"), 1); - QVERIFY(map.keys().count() == 2); + QCOMPARE(map.keys().count(), 2); QVERIFY(!map.contains(QLatin1String("valueChanged"))); QVERIFY(map.value(QLatin1String("valueChanged")).isNull()); //but 'valueChange' should be ok map.insert(QLatin1String("valueChange"), 1); - QVERIFY(map.keys().count() == 3); + QCOMPARE(map.keys().count(), 3); QVERIFY(map.contains(QLatin1String("valueChange"))); QCOMPARE(map.value(QLatin1String("valueChange")), QVariant(1)); //'valueCHANGED' should be ok, too map.insert(QLatin1String("valueCHANGED"), 1); - QVERIFY(map.keys().count() == 4); + QCOMPARE(map.keys().count(), 4); QVERIFY(map.contains(QLatin1String("valueCHANGED"))); QCOMPARE(map.value(QLatin1String("valueCHANGED")), QVariant(1)); } @@ -153,7 +153,7 @@ void tst_QQmlPropertyMap::operatorInsert() QQmlPropertyMap map; map[QLatin1String("key1")] = 100; map[QLatin1String("key2")] = 200; - QVERIFY(map.keys().count() == 2); + QCOMPARE(map.keys().count(), 2); QCOMPARE(map.value(QLatin1String("key1")), QVariant(100)); QCOMPARE(map.value(QLatin1String("key2")), QVariant(200)); @@ -167,7 +167,7 @@ void tst_QQmlPropertyMap::operatorValue() QQmlPropertyMap map; map.insert(QLatin1String("key1"),100); map.insert(QLatin1String("key2"),200); - QVERIFY(map.count() == 2); + QCOMPARE(map.count(), 2); QVERIFY(map.contains(QLatin1String("key1"))); const QQmlPropertyMap &constMap = map; @@ -182,12 +182,12 @@ void tst_QQmlPropertyMap::clear() { QQmlPropertyMap map; map.insert(QLatin1String("key1"),100); - QVERIFY(map.keys().count() == 1); + QCOMPARE(map.keys().count(), 1); QCOMPARE(map.value(QLatin1String("key1")), QVariant(100)); map.clear(QLatin1String("key1")); - QVERIFY(map.keys().count() == 1); + QCOMPARE(map.keys().count(), 1); QVERIFY(map.contains(QLatin1String("key1"))); QCOMPARE(map.value(QLatin1String("key1")), QVariant()); } @@ -463,7 +463,7 @@ void tst_QQmlPropertyMap::QTBUG_35906() QScopedPointer<QObject> obj(component.create()); QVERIFY(!obj.isNull()); QVariant value = obj->property("testValue"); - QVERIFY(value.type() == QVariant::Int); + QCOMPARE(value.type(), QVariant::Int); QCOMPARE(value.toInt(), 42); } diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp index 671f7b5e73..b5bdc3a3b9 100644 --- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp +++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp @@ -651,7 +651,7 @@ void tst_qqmlqt::createQmlObject() QQuickItem *item = qobject_cast<QQuickItem *>(object); QVERIFY(item != 0); - QVERIFY(item->childItems().count() == 1); + QCOMPARE(item->childItems().count(), 1); delete object; } diff --git a/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp b/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp index 17083a4c6a..5a98a6bed8 100644 --- a/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp +++ b/tests/auto/qml/qqmltimer/tst_qqmltimer.cpp @@ -134,7 +134,7 @@ void tst_qqmltimer::notRepeating() QCOMPARE(helper.count, 1); consistentWait(200); QCOMPARE(helper.count, 1); - QVERIFY(timer->isRunning() == false); + QVERIFY(!timer->isRunning()); } void tst_qqmltimer::notRepeatingStart() @@ -157,7 +157,7 @@ void tst_qqmltimer::notRepeatingStart() QCOMPARE(helper.count, 1); consistentWait(200); QCOMPARE(helper.count, 1); - QVERIFY(timer->isRunning() == false); + QVERIFY(!timer->isRunning()); delete timer; } @@ -186,8 +186,8 @@ void tst_qqmltimer::repeat() timer->stop(); consistentWait(200); - QVERIFY(helper.count == oldCount); - QVERIFY(timer->isRunning() == false); + QCOMPARE(helper.count, oldCount); + QVERIFY(!timer->isRunning()); QSignalSpy spy(timer, SIGNAL(repeatChanged())); @@ -221,7 +221,7 @@ void tst_qqmltimer::triggeredOnStart() QCOMPARE(helper.count, 2); consistentWait(200); QCOMPARE(helper.count, 2); - QVERIFY(timer->isRunning() == false); + QVERIFY(!timer->isRunning()); QSignalSpy spy(timer, SIGNAL(triggeredOnStartChanged())); diff --git a/tests/auto/qml/qqmltypeloader/data/load_synchronous.qml b/tests/auto/qml/qqmltypeloader/data/load_synchronous.qml new file mode 100644 index 0000000000..5e9c4c2bdc --- /dev/null +++ b/tests/auto/qml/qqmltypeloader/data/load_synchronous.qml @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQml 2.2 + +QtObject { + id: top + + Component.onCompleted: { + Qt.createQmlObject('QtObject {}', top, 'nonprotocol:'); + } +} diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp index 77cdaae9f0..4c5b1f7e63 100644 --- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp +++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp @@ -43,6 +43,7 @@ class tst_QQMLTypeLoader : public QQmlDataTest private slots: void testLoadComplete(); + void loadComponentSynchronously(); }; void tst_QQMLTypeLoader::testLoadComplete() @@ -62,6 +63,16 @@ void tst_QQMLTypeLoader::testLoadComplete() delete window; } +void tst_QQMLTypeLoader::loadComponentSynchronously() +{ + QQmlEngine engine; + QTest::ignoreMessage(QtWarningMsg, QRegularExpression( + QLatin1String(".*nonprotocol::1:1: QtObject is not a type.*"))); + QQmlComponent component(&engine, testFileUrl("load_synchronous.qml")); + QObject *o = component.create(); + QVERIFY(o); +} + QTEST_MAIN(tst_QQMLTypeLoader) #include "tst_qqmltypeloader.moc" diff --git a/tests/auto/qml/qqmlvaluetypeproviders/data/changedSignal.qml b/tests/auto/qml/qqmlvaluetypeproviders/data/changedSignal.qml new file mode 100644 index 0000000000..fed4cf4cbc --- /dev/null +++ b/tests/auto/qml/qqmlvaluetypeproviders/data/changedSignal.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2016 basysKom GmbH, opensource@basyskom.com. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + property bool success: false + property bool complete: false + + property vector2d v2: Qt.vector2d(-2, 0) + property vector3d v3: Qt.vector3d(-2, 0, 0) + property vector4d v4: Qt.vector4d(-2, 0, 0, 0) + + property int v2ChangedSignalCount; + property int v3ChangedSignalCount; + property int v4ChangedSignalCount; + + onV2Changed: v2ChangedSignalCount++ + onV3Changed: v3ChangedSignalCount++ + onV4Changed: v4ChangedSignalCount++ + + Component.onCompleted: { + complete = false; + success = true; + + // storing the initial value causes a signal emission + if (v2ChangedSignalCount !== 1) success = false + v2 = Qt.vector2d(-2, 0); + // setting the same value again must not emit a signal + if (v2ChangedSignalCount !== 1) success = false + v2.x++ + if (v2ChangedSignalCount !== 2) success = false + v2.x++ // cycle through 0, 0 which is the default value + if (v2ChangedSignalCount !== 3) success = false + v2.x++ + if (v2ChangedSignalCount !== 4) success = false + + // storing the initial value causes a signal emission + if (v3ChangedSignalCount !== 1) success = false + v3 = Qt.vector3d(-2, 0, 0); + // setting the same value again must not emit a signal + if (v3ChangedSignalCount !== 1) success = false + v3.x++ + if (v3ChangedSignalCount !== 2) success = false + v3.x++ // cycle through 0, 0, 0 which is the default value + if (v3ChangedSignalCount !== 3) success = false + v3.x++ + if (v3ChangedSignalCount !== 4) success = false + + // storing the initial value causes a signal emission + if (v4ChangedSignalCount !== 1) success = false + v4 = Qt.vector4d(-2, 0, 0, 0); + // setting the same value again must not emit a signal + if (v4ChangedSignalCount !== 1) success = false + v4.x++ + if (v4ChangedSignalCount !== 2) success = false + v4.x++ // cycle through 0, 0, 0 which is the default value + if (v4ChangedSignalCount !== 3) success = false + v4.x++ + if (v4ChangedSignalCount !== 4) success = false + + complete = true; + } +} diff --git a/tests/auto/qml/qqmlvaluetypeproviders/data/qtquickValueTypes.qml b/tests/auto/qml/qqmlvaluetypeproviders/data/qtquickValueTypes.qml index f723dc3e2e..d35ec84e23 100644 --- a/tests/auto/qml/qqmlvaluetypeproviders/data/qtquickValueTypes.qml +++ b/tests/auto/qml/qqmlvaluetypeproviders/data/qtquickValueTypes.qml @@ -112,7 +112,7 @@ QtObject { if (m != Qt.matrix4x4(4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7)) qtquickTypeSuccess = false; if (m.toString() != "QMatrix4x4(4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7)") qtquickTypeSuccess = false; c = "blue"; - if (c.toString() != Qt.rgba(0,0,1,0).toString()) qtquickTypeSuccess = false; + if (c.toString() != Qt.rgba(0,0,1,1).toString()) qtquickTypeSuccess = false; if (c.toString() != "#0000FF" && c.toString() != "#0000ff") qtquickTypeSuccess = false; // color string converter is special // no string converter for fonts. } diff --git a/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp b/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp index 58fca2d9d9..a38dff21fa 100644 --- a/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp +++ b/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp @@ -36,6 +36,7 @@ #include <QQmlComponent> #include <QQmlContext> #include <QDebug> +#include <QScopedPointer> #include <private/qqmlglobal_p.h> #include <private/qquickvaluetypes_p.h> #include "../../shared/util.h" @@ -66,6 +67,7 @@ private slots: void jsObjectConversion(); void invokableFunctions(); void userType(); + void changedSignal(); }; void tst_qqmlvaluetypeproviders::initTestCase() @@ -291,6 +293,18 @@ void tst_qqmlvaluetypeproviders::userType() QCOMPARE(obj->property("success").toBool(), true); } +void tst_qqmlvaluetypeproviders::changedSignal() +{ + QQmlEngine e; + QQmlComponent component(&e, testFileUrl("changedSignal.qml")); + QVERIFY(!component.isError()); + QVERIFY(component.errors().isEmpty()); + QScopedPointer<QObject> object(component.create()); + QVERIFY(object != 0); + QVERIFY(object->property("complete").toBool()); + QVERIFY(object->property("success").toBool()); +} + QTEST_MAIN(tst_qqmlvaluetypeproviders) #include "tst_qqmlvaluetypeproviders.moc" diff --git a/tests/auto/qml/qqmlvaluetypes/data/color_compare.qml b/tests/auto/qml/qqmlvaluetypes/data/color_compare.qml index 8701dae612..141404b067 100644 --- a/tests/auto/qml/qqmlvaluetypes/data/color_compare.qml +++ b/tests/auto/qml/qqmlvaluetypes/data/color_compare.qml @@ -15,12 +15,12 @@ MyTypeObject { // compare different color.toString()s property bool colorToStringEqualsColorString: (color.toString() == colorToString) // true - property bool colorToStringEqualsDifferentAlphaString: (color.toString() == Qt.rgba(0.2, 0.88, 0.6, 0.44).toString()) // true + property bool colorToStringEqualsDifferentAlphaString: (color.toString() == Qt.rgba(0.2, 0.88, 0.6, 0.34).toString()) // true property bool colorToStringEqualsDifferentRgbaString: (color.toString() == Qt.rgba(0.3, 0.98, 0.7, 0.44).toString()) // false // compare colors to strings property bool colorEqualsColorString: (color == colorToString) // false - property bool colorEqualsDifferentAlphaString: (color == Qt.rgba(0.2, 0.88, 0.6, 0.44).toString()) // false + property bool colorEqualsDifferentAlphaString: (color == Qt.rgba(0.2, 0.88, 0.6, 0.34).toString()) // false property bool colorEqualsDifferentRgbaString: (color == Qt.rgba(0.3, 0.98, 0.7, 0.44).toString()) // false // compare colors to various value types diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp index f93190cab6..58755927b5 100644 --- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp +++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp @@ -937,7 +937,7 @@ void tst_qqmlvaluetypes::color() QQmlComponent component(&engine, testFileUrl("color_compare.qml")); MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); QVERIFY(object != 0); - QString colorString("#33e199"); + QString colorString("#5733e199"); QCOMPARE(object->property("colorToString").toString(), colorString); QCOMPARE(object->property("colorEqualsIdenticalRgba").toBool(), true); QCOMPARE(object->property("colorEqualsDifferentAlpha").toBool(), false); @@ -1221,7 +1221,7 @@ void tst_qqmlvaluetypes::enums() QQmlComponent component(&engine, testFileUrl("enums.1.qml")); MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); QVERIFY(object != 0); - QVERIFY(object->font().capitalization() == QFont::AllUppercase); + QCOMPARE(object->font().capitalization(), QFont::AllUppercase); delete object; } @@ -1229,7 +1229,7 @@ void tst_qqmlvaluetypes::enums() QQmlComponent component(&engine, testFileUrl("enums.2.qml")); MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); QVERIFY(object != 0); - QVERIFY(object->font().capitalization() == QFont::AllUppercase); + QCOMPARE(object->font().capitalization(), QFont::AllUppercase); delete object; } @@ -1237,7 +1237,7 @@ void tst_qqmlvaluetypes::enums() QQmlComponent component(&engine, testFileUrl("enums.3.qml")); MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); QVERIFY(object != 0); - QVERIFY(object->font().capitalization() == QFont::AllUppercase); + QCOMPARE(object->font().capitalization(), QFont::AllUppercase); delete object; } @@ -1245,7 +1245,7 @@ void tst_qqmlvaluetypes::enums() QQmlComponent component(&engine, testFileUrl("enums.4.qml")); MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); QVERIFY(object != 0); - QVERIFY(object->font().capitalization() == QFont::AllUppercase); + QCOMPARE(object->font().capitalization(), QFont::AllUppercase); delete object; } @@ -1253,7 +1253,7 @@ void tst_qqmlvaluetypes::enums() QQmlComponent component(&engine, testFileUrl("enums.5.qml")); MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); QVERIFY(object != 0); - QVERIFY(object->font().capitalization() == QFont::AllUppercase); + QCOMPARE(object->font().capitalization(), QFont::AllUppercase); delete object; } } diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.collection.allprop.expect b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.collection.allprop.expect new file mode 100644 index 0000000000..f0dc8ed3fd --- /dev/null +++ b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.collection.allprop.expect @@ -0,0 +1,14 @@ +PROPFIND /container/ HTTP/1.1 +Depth: 1 +Content-Length: 95 +Connection: Keep-Alive +Accept-Encoding: gzip, deflate +Accept-Language: en-US,* +Content-type:i application/xml; charset="utf-8" +User-Agent: Mozilla/5.0 +Host: {{ServerHostUrl}} + +<?xml version="1.0" encoding="utf-8" ?> +<D:propfind xmlns:D="DAV:"> +<D:allprop/> +</D:propfind> diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.collection.allprop.reply.body b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.collection.allprop.reply.body new file mode 100644 index 0000000000..ef0c38956c --- /dev/null +++ b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.collection.allprop.reply.body @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +<D:multistatus xmlns:D="DAV:"> + <D:response> + <D:href>/container/</D:href> + <D:propstat> + <D:prop xmlns:R="http://ns.example.com/boxschema/"> + <R:bigbox><R:BoxType>Box type A</R:BoxType></R:bigbox> + <R:author><R:Name>Hadrian</R:Name></R:author> + <D:creationdate>1997-12-01T17:42:21-08:00</D:creationdate> + <D:displayname>Example collection</D:displayname> + <D:resourcetype><D:collection/></D:resourcetype> + <D:supportedlock> + <D:lockentry> + <D:lockscope><D:exclusive/></D:lockscope> + <D:locktype><D:write/></D:locktype> + </D:lockentry> + <D:lockentry> + <D:lockscope><D:shared/></D:lockscope> + <D:locktype><D:write/></D:locktype> + </D:lockentry> + </D:supportedlock> + </D:prop> + <D:status>HTTP/1.1 200 OK</D:status> + </D:propstat> + </D:response> +/D:multistatus> +--> +<D:multistatus xmlns:D="DAV:"><D:response><D:href>/container/</D:href><D:propstat><D:prop xmlns:R="http://ns.example.com/boxschema/"><R:bigbox><R:BoxType>Box type A</R:BoxType></R:bigbox><R:author><R:Name>Hadrian</R:Name></R:author><D:creationdate>1997-12-01T17:42:21-08:00</D:creationdate><D:displayname>Example collection</D:displayname><D:resourcetype><D:collection/></D:resourcetype><D:supportedlock><D:lockentry><D:lockscope><D:exclusive/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry><D:lockentry><D:lockscope><D:shared/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry></D:supportedlock></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response></D:multistatus> diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.file.expect b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.file.expect new file mode 100644 index 0000000000..2d14de634d --- /dev/null +++ b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.file.expect @@ -0,0 +1,18 @@ +PROPFIND /file HTTP/1.1 +Content-Length: 192 +Connection: Keep-Alive +Accept-Encoding: gzip, deflate +Accept-Language: en-US,* +Content-type: text/xml; charset="utf-8" +User-Agent: Mozilla/5.0 +Host: {{ServerHostUrl}} + +<?xml version="1.0" encoding="utf-8" ?> +<D:propfind xmlns:D="DAV:"> +<D:prop xmlns:R="http://www.foo.bar/boxschema/"> +<R:bigbox/> +<R:author/> +<R:DingALing/> +<R:Random/> +</D:prop> +</D:propfind> diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.file.reply.body b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.file.reply.body new file mode 100644 index 0000000000..9e5028fe01 --- /dev/null +++ b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.file.reply.body @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +<D:multistatus xmlns:D="DAV:"> + <D:response xmlns:R="http://ns.example.com/boxschema/"> + <D:href>http://www.example.com/file</D:href> + <D:propstat> + <D:prop> + <R:bigbox> + <R:BoxType>Box type A</R:BoxType> + </R:bigbox> + <R:author> + <R:Name>J.J. Johnson</R:Name> + </R:author> + </D:prop> + <D:status>HTTP/1.1 200 OK</D:status> + </D:propstat> + <D:propstat> + <D:prop> + <R:DingALing/> + <R:Random/> + </D:prop> + <D:status>HTTP/1.1 403 Forbidden</D:status> + <D:responsedescription>The user does not have access to the DingALing property.</D:responsedescription> + </D:propstat> + </D:response> + <D:responsedescription>There has been an access violation error.</D:responsedescription> +</D:multistatus> +--> +<D:multistatus xmlns:D="DAV:"><D:response xmlns:R="http://ns.example.com/boxschema/"><D:href>http://www.example.com/file</D:href><D:propstat><D:prop><R:bigbox><R:BoxType>Box type A</R:BoxType></R:bigbox><R:author><R:Name>J.J. Johnson</R:Name></R:author></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat><D:propstat><D:prop><R:DingALing/><R:Random/></D:prop><D:status>HTTP/1.1 403 Forbidden</D:status><D:responsedescription>The user does not have access to the DingALing property.</D:responsedescription></D:propstat></D:response><D:responsedescription>There has been an access violation error.</D:responsedescription></D:multistatus> diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.file.reply.header b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.file.reply.header new file mode 100644 index 0000000000..50fa080ad2 --- /dev/null +++ b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.file.reply.header @@ -0,0 +1,2 @@ +HTTP/1.1 207 Multi-Status +Content-Type: text/xml; charset="utf-8" diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/sendPropfind.collection.allprop.qml b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/sendPropfind.collection.allprop.qml new file mode 100644 index 0000000000..2f47a5e62c --- /dev/null +++ b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/sendPropfind.collection.allprop.qml @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +QtObject { + property string url + property bool xmlTest: false + property bool typeTest: false + + function checkXML(document) + { + if (document.xmlVersion != "1.0") + return; + + if (document.xmlEncoding != "utf-8") + return; + + if (document.documentElement == null) + return; + + var multistatus = document.documentElement; + if (multistatus.nodeName != "multistatus") + return; + + if (multistatus.namespaceUri != "DAV:") + return; + + var multistatusChildTags = [ "response" ]; + for (var node = 0; node < multistatus.childNodes.length; ++node) { + if (multistatus.childNodes[node].nodeName != multistatusChildTags[node]) + return; + } + + var response = multistatus.childNodes[0]; + var responseChildTags = [ "href", "propstat" ]; + for (var node = 0; node < response.childNodes.length; ++node) { + var nodeName = response.childNodes[node].nodeName; + if (nodeName != responseChildTags[node]) + return; + + var nodeValue = response.childNodes[node].childNodes[0].nodeValue; + if ((nodeName == "href") && (nodeValue != "/container/")) + return; + } + + var propstat = response.childNodes[1]; + var propstatChildTags = ["prop", "status"]; + for (var node = 0; node < propstat.childNodes.length; ++node) { + var nodeName = propstat.childNodes[node].nodeName; + if (nodeName != propstatChildTags[node]) + return; + + var nodeValue = propstat.childNodes[node].childNodes[0].nodeValue; + if ((nodeName == "status") && (nodeValue != "HTTP/1.1 200 OK")) + return; + } + + var prop = propstat.childNodes[0]; + var propChildTags = [ "bigbox", "author", "creationdate", "displayname", "resourcetype", "supportedlock" ]; + for (var node = 0; node < prop.childNodes.length; ++node) { + var nodeName = prop.childNodes[node].nodeName; + if (nodeName != propChildTags[node]) + return; + + if (nodeName == "bigbox") { + if (prop.childNodes[node].childNodes.length != 1) + return; + + var boxType = prop.childNodes[node].childNodes[0]; + if (boxType.nodeName != "BoxType") + return; + if (boxType.childNodes[0].nodeValue != "Box type A") + return; + } + + if (nodeName == "author") { + if (prop.childNodes[node].childNodes.length != 1) + return; + + var boxType = prop.childNodes[node].childNodes[0]; + if (boxType.nodeName != "Name") + return; + if (boxType.childNodes[0].nodeValue != "Hadrian") + return; + } + + if (nodeName == "creationdate") { + if (prop.childNodes[node].childNodes.length != 1) + return; + + if (prop.childNodes[node].childNodes[0].nodeValue != "1997-12-01T17:42:21-08:00") + return; + } + + if (nodeName == "displayname") { + if (prop.childNodes[node].childNodes.length != 1) + return; + + if (prop.childNodes[node].childNodes[0].nodeValue != "Example collection") + return; + } + + if (nodeName == "resourcetpye") { + if (prop.childNodes[node].childNodes.length != 1) + return; + + if (prop.childNodes[node].childNodes[0].nodeValue != "collection") + return; + } + + if (nodeName == "supportedlock") { + if (prop.childNodes[node].childNodes.length != 2) + return; + + var lockEntry1 = prop.childNodes[node].childNodes[0]; + if (lockEntry1.nodeName != "lockentry") + return; + if (lockEntry1.childNodes.length != 2) + return; + if (lockEntry1.childNodes[0].nodeName != "lockscope") + return; + if (lockEntry1.childNodes[0].childNodes[0].nodeName != "exclusive") + return; + if (lockEntry1.childNodes[1].nodeName != "locktype") + return; + if (lockEntry1.childNodes[1].childNodes[0].nodeName != "write") + return; + + var lockEntry2 = prop.childNodes[node].childNodes[1]; + if (lockEntry2.nodeName != "lockentry") + return; + if (lockEntry2.childNodes.length != 2) + return; + if (lockEntry2.childNodes[0].nodeName != "lockscope") + return; + if (lockEntry2.childNodes[0].childNodes[0].nodeName != "shared") + return; + if (lockEntry2.childNodes[1].nodeName != "locktype") + return; + if (lockEntry2.childNodes[1].childNodes[0].nodeName != "write") + return; + } + } + + xmlTest = true; + } + + Component.onCompleted: { + + var request = new XMLHttpRequest(); + request.open("PROPFIND", url); + request.responseType = "document"; + request.setRequestHeader("Depth", "1"); + + request.onreadystatechange = function() { + if (request.readyState == XMLHttpRequest.DONE) { + checkXML(request.response); + typeTest = (request.responseType == "document"); + } + } + + var requestBody = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" + + "<D:propfind xmlns:D=\"DAV:\">\n" + + "<D:allprop/>\n" + + "</D:propfind>\n" + request.send(requestBody); + } +} + diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/sendPropfind.response.qml b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/sendPropfind.response.qml new file mode 100644 index 0000000000..01353e5e95 --- /dev/null +++ b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/sendPropfind.response.qml @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +QtObject { + property string url + property bool xmlTest: false + property bool typeTest: false + + function checkXML(document) + { + if (document.xmlVersion != "1.0") + return; + + if (document.xmlEncoding != "utf-8") + return; + + if (document.documentElement == null) + return; + + var multistatus = document.documentElement; + if (multistatus.nodeName != "multistatus") + return; + + if (multistatus.namespaceUri != "DAV:") + return; + + var multistatusChildTags = [ "response", "responsedescription" ]; + for (var node = 0; node < multistatus.childNodes.length; ++node) { + if (multistatus.childNodes[node].nodeName != multistatusChildTags[node]) + return; + } + + var response = multistatus.childNodes[0]; + var responseChildTags = [ "href", "propstat", "propstat" ]; + for (var node = 0; node < response.childNodes.length; ++node) { + var nodeName = response.childNodes[node].nodeName; + if (nodeName != responseChildTags[node]) + return; + + var nodeValue = response.childNodes[node].childNodes[0].nodeValue; + if ((nodeName == "href") && (nodeValue != "http://www.example.com/file")) + return; + } + + if (multistatus.childNodes[1].childNodes[0].nodeValue != "There has been an access violation error.") + return; + + var propstat1 = response.childNodes[1]; + var propstat1ChildTags = ["prop", "status"]; + for (var node = 0; node < propstat1.childNodes.length; ++node) { + var nodeName = propstat1.childNodes[node].nodeName; + if (nodeName != propstat1ChildTags[node]) + return; + + var nodeValue = propstat1.childNodes[node].childNodes[0].nodeValue; + if ((nodeName == "status") && (nodeValue != "HTTP/1.1 200 OK")) + return; + } + + var prop1 = propstat1.childNodes[0]; + var prop1ChildTags = [ "bigbox", "author" ]; + for (var node = 0; node < prop1.childNodes.length; ++node) { + var nodeName = prop1.childNodes[node].nodeName; + if (nodeName != prop1ChildTags[node]) + return; + + if (nodeName == "bigbox") { + if (prop1.childNodes[node].childNodes.length != 1) + return; + + var boxType = prop1.childNodes[node].childNodes[0]; + if (boxType.nodeName != "BoxType") + return; + if (boxType.childNodes[0].nodeValue != "Box type A") + return; + } + } + + var propstat2 = response.childNodes[2]; + var propstat2ChildTags = ["prop", "status", "responsedescription" ]; + for (var node = 0; node < propstat2.childNodes.length; ++node) { + var nodeName = propstat2.childNodes[node].nodeName; + if (nodeName != propstat2ChildTags[node]) + return; + + var nodeValue = propstat2.childNodes[node].childNodes[0].nodeValue; + if ((nodeName == "status") && (nodeValue != "HTTP/1.1 403 Forbidden")) + return; + if ((nodeName == "responsedescription") && (nodeValue != "The user does not have access to the DingALing property.")) + return; + } + + var prop2 = propstat2.childNodes[0]; + var prop2ChildTags = [ "DingALing", "Random" ]; + for (var node = 0; node < prop2.childNodes.length; ++node) { + var nodeName = prop2.childNodes[node].nodeName; + if (nodeName != prop2ChildTags[node]) + return; + } + + xmlTest = true; + } + + Component.onCompleted: { + + var request = new XMLHttpRequest(); + request.open("PROPFIND", url); + request.responseType = "document"; + + request.onreadystatechange = function() { + if (request.readyState == XMLHttpRequest.DONE) { + checkXML(request.response); + typeTest = (request.responseType == "document"); + } + } + + var requestBody = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" + + "<D:propfind xmlns:D=\"DAV:\">\n" + + "<D:prop xmlns:R=\"http://www.foo.bar/boxschema/\">\n" + + "<R:bigbox/>\n" + + "<R:author/>\n" + + "<R:DingALing/>\n" + + "<R:Random/>\n" + + "</D:prop>\n" + + "</D:propfind>\n" + request.send(requestBody); + } +} + diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/sendPropfind.responseXML.qml b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/sendPropfind.responseXML.qml new file mode 100644 index 0000000000..3b4d1e2c1e --- /dev/null +++ b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/sendPropfind.responseXML.qml @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +QtObject { + property string url + property bool xmlTest: false + property bool typeTest: false + + function checkXML(document) + { + if (document.xmlVersion != "1.0") + return; + + if (document.xmlEncoding != "utf-8") + return; + + if (document.documentElement == null) + return; + + var multistatus = document.documentElement; + if (multistatus.nodeName != "multistatus") + return; + + if (multistatus.namespaceUri != "DAV:") + return; + + var multistatusChildTags = [ "response", "responsedescription" ]; + for (var node = 0; node < multistatus.childNodes.length; ++node) { + if (multistatus.childNodes[node].nodeName != multistatusChildTags[node]) + return; + } + + var response = multistatus.childNodes[0]; + var responseChildTags = [ "href", "propstat", "propstat" ]; + for (var node = 0; node < response.childNodes.length; ++node) { + var nodeName = response.childNodes[node].nodeName; + if (nodeName != responseChildTags[node]) + return; + + var nodeValue = response.childNodes[node].childNodes[0].nodeValue; + if ((nodeName == "href") && (nodeValue != "http://www.example.com/file")) + return; + } + + if (multistatus.childNodes[1].childNodes[0].nodeValue != "There has been an access violation error.") + return; + + var propstat1 = response.childNodes[1]; + var propstat1ChildTags = ["prop", "status"]; + for (var node = 0; node < propstat1.childNodes.length; ++node) { + var nodeName = propstat1.childNodes[node].nodeName; + if (nodeName != propstat1ChildTags[node]) + return; + + var nodeValue = propstat1.childNodes[node].childNodes[0].nodeValue; + if ((nodeName == "status") && (nodeValue != "HTTP/1.1 200 OK")) + return; + } + + var prop1 = propstat1.childNodes[0]; + var prop1ChildTags = [ "bigbox", "author" ]; + for (var node = 0; node < prop1.childNodes.length; ++node) { + var nodeName = prop1.childNodes[node].nodeName; + if (nodeName != prop1ChildTags[node]) + return; + + if (nodeName == "bigbox") { + if (prop1.childNodes[node].childNodes.length != 1) + return; + + var boxType = prop1.childNodes[node].childNodes[0]; + if (boxType.nodeName != "BoxType") + return; + if (boxType.childNodes[0].nodeValue != "Box type A") + return; + } + } + + var propstat2 = response.childNodes[2]; + var propstat2ChildTags = ["prop", "status", "responsedescription" ]; + for (var node = 0; node < propstat2.childNodes.length; ++node) { + var nodeName = propstat2.childNodes[node].nodeName; + if (nodeName != propstat2ChildTags[node]) + return; + + var nodeValue = propstat2.childNodes[node].childNodes[0].nodeValue; + if ((nodeName == "status") && (nodeValue != "HTTP/1.1 403 Forbidden")) + return; + if ((nodeName == "responsedescription") && (nodeValue != "The user does not have access to the DingALing property.")) + return; + } + + var prop2 = propstat2.childNodes[0]; + var prop2ChildTags = [ "DingALing", "Random" ]; + for (var node = 0; node < prop2.childNodes.length; ++node) { + var nodeName = prop2.childNodes[node].nodeName; + if (nodeName != prop2ChildTags[node]) + return; + } + + xmlTest = true; + } + + Component.onCompleted: { + + var request = new XMLHttpRequest(); + request.open("PROPFIND", url); + + request.onreadystatechange = function() { + if (request.readyState == XMLHttpRequest.DONE) { + checkXML(request.responseXML); + typeTest = (request.responseType == "document"); + } + } + + var requestBody = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" + + "<D:propfind xmlns:D=\"DAV:\">\n" + + "<D:prop xmlns:R=\"http://www.foo.bar/boxschema/\">\n" + + "<R:bigbox/>\n" + + "<R:author/>\n" + + "<R:DingALing/>\n" + + "<R:Random/>\n" + + "</D:prop>\n" + + "</D:propfind>\n" + request.send(requestBody); + } +} + diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/cdata.qml b/tests/auto/qml/qqmlxmlhttprequest/data/cdata.qml index f558fdadc6..e1b690dbf3 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/cdata.qml +++ b/tests/auto/qml/qqmlxmlhttprequest/data/cdata.qml @@ -3,6 +3,7 @@ import QtQuick 2.0 QtObject { property bool xmlTest: false property bool dataOK: false + property int status: 0 function checkCData(text, whitespacetext) { @@ -114,12 +115,11 @@ QtObject { // Test to the end x.onreadystatechange = function() { if (x.readyState == XMLHttpRequest.DONE) { - dataOK = true; + status = x.status; if (x.responseXML != null) checkXML(x.responseXML); - } } diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/json.data b/tests/auto/qml/qqmlxmlhttprequest/data/json.data new file mode 100644 index 0000000000..7925375293 --- /dev/null +++ b/tests/auto/qml/qqmlxmlhttprequest/data/json.data @@ -0,0 +1,6 @@ +{"widget": { + "debug": "on", + "window": { + "name": "main_window", + "width": 500 +}}} diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/receiveBinaryData.qml b/tests/auto/qml/qqmlxmlhttprequest/data/receiveBinaryData.qml index 234d759284..b9f0ab6e66 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/receiveBinaryData.qml +++ b/tests/auto/qml/qqmlxmlhttprequest/data/receiveBinaryData.qml @@ -3,6 +3,7 @@ import QtQuick 2.0 QtObject { property string url property int readSize: 0 + property int status: 0 Component.onCompleted: { @@ -12,6 +13,7 @@ QtObject { request.onreadystatechange = function() { if (request.readyState == XMLHttpRequest.DONE) { + status = request.status; var arrayBuffer = request.response; if (arrayBuffer) { var byteArray = new Uint8Array(arrayBuffer); diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/receiveJsonData.qml b/tests/auto/qml/qqmlxmlhttprequest/data/receiveJsonData.qml new file mode 100644 index 0000000000..3fc116e675 --- /dev/null +++ b/tests/auto/qml/qqmlxmlhttprequest/data/receiveJsonData.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 + +QtObject { + property string url; + property bool result: false + property string correctjsondata : "{\"widget\":{\"debug\":\"on\",\"window\":{\"name\":\"main_window\",\"width\":500}}}" + + Component.onCompleted: { + var request = new XMLHttpRequest(); + request.open("GET", url, true); + request.responseType = "json"; + + request.onreadystatechange = function() { + if (request.readyState == XMLHttpRequest.DONE) { + var jsonData = JSON.stringify(request.response); + result = (correctjsondata == jsonData); + } + } + + request.send(null); + } +} diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/receive_json_data.expect b/tests/auto/qml/qqmlxmlhttprequest/data/receive_json_data.expect new file mode 100644 index 0000000000..97b016f50a --- /dev/null +++ b/tests/auto/qml/qqmlxmlhttprequest/data/receive_json_data.expect @@ -0,0 +1,7 @@ +GET /json.data HTTP/1.1 +Accept-Language: en-US,* +Content-Type: application/jsonrequest +Connection: Keep-Alive +Accept-Encoding: gzip, deflate +User-Agent: Mozilla/5.0 +Host: {{ServerHostUrl}} diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/receive_json_data.reply b/tests/auto/qml/qqmlxmlhttprequest/data/receive_json_data.reply new file mode 100644 index 0000000000..f1ee73d623 --- /dev/null +++ b/tests/auto/qml/qqmlxmlhttprequest/data/receive_json_data.reply @@ -0,0 +1,3 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/jsonrequest diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/status.500.reply b/tests/auto/qml/qqmlxmlhttprequest/data/status.500.reply new file mode 100644 index 0000000000..cbe2424f34 --- /dev/null +++ b/tests/auto/qml/qqmlxmlhttprequest/data/status.500.reply @@ -0,0 +1,3 @@ +HTTP/1.0 500 Internal Server Error +Connection: close +Content-type: text/html; charset=UTF-8 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/text.qml b/tests/auto/qml/qqmlxmlhttprequest/data/text.qml index b79e0bc7b1..972557358b 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/text.qml +++ b/tests/auto/qml/qqmlxmlhttprequest/data/text.qml @@ -3,6 +3,7 @@ import QtQuick 2.0 QtObject { property bool xmlTest: false property bool dataOK: false + property int status: 0 function checkText(text, whitespacetext) { @@ -111,12 +112,11 @@ QtObject { // Test to the end x.onreadystatechange = function() { if (x.readyState == XMLHttpRequest.DONE) { - dataOK = true; + status = x.status; if (x.responseXML != null) checkXML(x.responseXML); - } } diff --git a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp index c159dc8420..68f85daacd 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp +++ b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp @@ -88,6 +88,7 @@ private slots: void getAllResponseHeaders_sent(); void getAllResponseHeaders_args(); void getBinaryData(); + void getJsonData(); void status(); void status_data(); void statusText(); @@ -100,6 +101,10 @@ private slots: void nonUtf8(); void nonUtf8_data(); + // WebDAV + void sendPropfind(); + void sendPropfind_data(); + // Attributes void document(); void element(); @@ -172,7 +177,7 @@ void tst_qqmlxmlhttprequest::callbackException() object->setProperty("which", which); component.completeCreate(); - QTRY_VERIFY(object->property("threw").toBool() == true); + QTRY_VERIFY(object->property("threw").toBool()); } // Test that the state value properties on the XMLHttpRequest constructor have the correct values. @@ -258,7 +263,7 @@ void tst_qqmlxmlhttprequest::open() QCOMPARE(object->property("responseText").toBool(), true); QCOMPARE(object->property("responseXML").toBool(), true); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); } void tst_qqmlxmlhttprequest::open_data() @@ -371,7 +376,7 @@ void tst_qqmlxmlhttprequest::setRequestHeader() object->setProperty("url", server.urlString("/testdocument.html")); component.completeCreate(); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); } // Test valid setRequestHeader() calls with different header cases @@ -389,7 +394,7 @@ void tst_qqmlxmlhttprequest::setRequestHeader_caseInsensitive() object->setProperty("url", server.urlString("/testdocument.html")); component.completeCreate(); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); } // Test setting headers before open() throws exception void tst_qqmlxmlhttprequest::setRequestHeader_unsent() @@ -454,7 +459,7 @@ void tst_qqmlxmlhttprequest::setRequestHeader_illegalName() QCOMPARE(object->property("responseText").toBool(), true); QCOMPARE(object->property("responseXML").toBool(), true); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); } // Test that attempting to set a header after a request is sent throws an exception @@ -474,7 +479,7 @@ void tst_qqmlxmlhttprequest::setRequestHeader_sent() QCOMPARE(object->property("test").toBool(), true); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); } // Invalid arg count throws exception @@ -505,7 +510,7 @@ void tst_qqmlxmlhttprequest::send_alreadySent() QVERIFY(!object.isNull()); QCOMPARE(object->property("test").toBool(), true); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); } // Test that sends for GET, HEAD and DELETE ignore data @@ -525,7 +530,7 @@ void tst_qqmlxmlhttprequest::send_ignoreData() object->setProperty("url", server.urlString("/testdocument.html")); component.completeCreate(); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); } { @@ -542,7 +547,7 @@ void tst_qqmlxmlhttprequest::send_ignoreData() object->setProperty("url", server.urlString("/testdocument.html")); component.completeCreate(); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); } { @@ -559,7 +564,7 @@ void tst_qqmlxmlhttprequest::send_ignoreData() object->setProperty("url", server.urlString("/testdocument.html")); component.completeCreate(); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); } } @@ -581,7 +586,7 @@ void tst_qqmlxmlhttprequest::send_withdata() object->setProperty("url", server.urlString("/testdocument.html")); component.completeCreate(); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); } void tst_qqmlxmlhttprequest::send_withdata_data() @@ -616,7 +621,7 @@ void tst_qqmlxmlhttprequest::send_options() QVERIFY(!object.isNull()); QString url = server.baseUrl().toString(); if (url_suffix != "/") - url.append("/"); + url.append(QLatin1Char('/')); if (!url_suffix.isEmpty()) url.append(url_suffix); object->setProperty("url", url); @@ -655,7 +660,7 @@ void tst_qqmlxmlhttprequest::abort_unsent() QCOMPARE(object->property("responseText").toBool(), true); QCOMPARE(object->property("responseXML").toBool(), true); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); } // Test abort() cancels an open (but unsent) request @@ -674,7 +679,7 @@ void tst_qqmlxmlhttprequest::abort_opened() QCOMPARE(object->property("responseText").toBool(), true); QCOMPARE(object->property("responseXML").toBool(), true); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); } // Test abort() aborts in progress send @@ -700,7 +705,7 @@ void tst_qqmlxmlhttprequest::abort() QCOMPARE(object->property("didNotSeeUnsent").toBool(), true); QCOMPARE(object->property("endStateUnsent").toBool(), true); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); } void tst_qqmlxmlhttprequest::getResponseHeader() @@ -725,7 +730,7 @@ void tst_qqmlxmlhttprequest::getResponseHeader() QCOMPARE(object->property("readyState").toBool(), true); QCOMPARE(object->property("openedState").toBool(), true); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); QCOMPARE(object->property("headersReceivedState").toBool(), true); QCOMPARE(object->property("headersReceivedNullHeader").toBool(), true); @@ -767,7 +772,7 @@ void tst_qqmlxmlhttprequest::getResponseHeader_args() QScopedPointer<QObject> object(component.create()); QVERIFY(!object.isNull()); - QTRY_VERIFY(object->property("exceptionThrown").toBool() == true); + QTRY_VERIFY(object->property("exceptionThrown").toBool()); } void tst_qqmlxmlhttprequest::getAllResponseHeaders() @@ -791,7 +796,7 @@ void tst_qqmlxmlhttprequest::getAllResponseHeaders() QCOMPARE(object->property("readyState").toBool(), true); QCOMPARE(object->property("openedState").toBool(), true); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); QCOMPARE(object->property("headersReceivedState").toBool(), true); QCOMPARE(object->property("headersReceivedHeader").toBool(), true); @@ -827,7 +832,7 @@ void tst_qqmlxmlhttprequest::getAllResponseHeaders_args() QScopedPointer<QObject> object(component.create()); QVERIFY(!object.isNull()); - QTRY_VERIFY(object->property("exceptionThrown").toBool() == true); + QTRY_VERIFY(object->property("exceptionThrown").toBool()); } void tst_qqmlxmlhttprequest::getBinaryData() @@ -845,7 +850,25 @@ void tst_qqmlxmlhttprequest::getBinaryData() component.completeCreate(); QFileInfo fileInfo("data/qml_logo.png"); - QTRY_VERIFY(object->property("readSize").toInt() == fileInfo.size()); + QTRY_COMPARE(object->property("readSize").toInt(), fileInfo.size()); + QCOMPARE(object->property("status").toInt(), 200); +} + +void tst_qqmlxmlhttprequest::getJsonData() +{ + TestHTTPServer server; + QVERIFY2(server.listen(), qPrintable(server.errorString())); + QVERIFY(server.wait(testFileUrl("receive_json_data.expect"), + testFileUrl("receive_binary_data.reply"), + testFileUrl("json.data"))); + + QQmlComponent component(&engine, testFileUrl("receiveJsonData.qml")); + QScopedPointer<QObject> object(component.beginCreate(engine.rootContext())); + QVERIFY(!object.isNull()); + object->setProperty("url", server.urlString("/json.data")); + component.completeCreate(); + + QTRY_VERIFY(object->property("result").toBool()); } void tst_qqmlxmlhttprequest::status() @@ -866,7 +889,7 @@ void tst_qqmlxmlhttprequest::status() object->setProperty("expectedStatus", status); component.completeCreate(); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); QCOMPARE(object->property("unsentException").toBool(), true); QCOMPARE(object->property("openedException").toBool(), true); @@ -905,7 +928,7 @@ void tst_qqmlxmlhttprequest::statusText() object->setProperty("expectedStatus", statusText); component.completeCreate(); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); QCOMPARE(object->property("unsentException").toBool(), true); QCOMPARE(object->property("openedException").toBool(), true); @@ -945,7 +968,7 @@ void tst_qqmlxmlhttprequest::responseText() object->setProperty("expectedText", responseText); component.completeCreate(); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); QCOMPARE(object->property("unsent").toBool(), true); QCOMPARE(object->property("opened").toBool(), true); @@ -966,6 +989,7 @@ void tst_qqmlxmlhttprequest::responseText_data() QTest::newRow("empty body") << testFileUrl("status.200.reply") << QUrl() << ""; QTest::newRow("Not Found") << testFileUrl("status.404.reply") << testFileUrl("testdocument.html") << "QML Rocks!\n"; QTest::newRow("Bad Request") << testFileUrl("status.400.reply") << testFileUrl("testdocument.html") << "QML Rocks!\n"; + QTest::newRow("Internal server error") << testFileUrl("status.500.reply") << testFileUrl("testdocument.html") << "QML Rocks!\n"; } void tst_qqmlxmlhttprequest::nonUtf8() @@ -981,7 +1005,7 @@ void tst_qqmlxmlhttprequest::nonUtf8() object->setProperty("fileName", fileName); QMetaObject::invokeMethod(object.data(), "startRequest"); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); QCOMPARE(object->property("responseText").toString(), responseText); @@ -1007,6 +1031,46 @@ void tst_qqmlxmlhttprequest::nonUtf8_data() QTest::newRow("responseXML") << "utf16.xml" << "<?xml version=\"1.0\" encoding=\"UTF-16\" standalone='yes'?>\n<root>\n" + uc + "\n</root>\n" << QString('\n' + uc + '\n'); } +void tst_qqmlxmlhttprequest::sendPropfind() +{ + const QString prefix = "WebDAV//"; + + QFETCH(QString, qml); + QFETCH(QString, resource); + QFETCH(QString, expectedFile); + QFETCH(QString, replyHeader); + QFETCH(QString, replyBody); + + TestHTTPServer server; + QVERIFY2(server.listen(), qPrintable(server.errorString())); + + QVERIFY(server.wait(testFileUrl(prefix + expectedFile), + testFileUrl(prefix + replyHeader), + testFileUrl(prefix + replyBody))); + + QQmlComponent component(&engine, testFileUrl(prefix + qml)); + QScopedPointer<QObject> object(component.beginCreate(engine.rootContext())); + QVERIFY(!object.isNull()); + object->setProperty("url", server.urlString(resource)); + component.completeCreate(); + + QTRY_VERIFY(object->property("xmlTest").toBool()); + QCOMPARE(object->property("typeTest").toBool(), true); +} + +void tst_qqmlxmlhttprequest::sendPropfind_data() +{ + QTest::addColumn<QString>("qml"); + QTest::addColumn<QString>("resource"); + QTest::addColumn<QString>("expectedFile"); + QTest::addColumn<QString>("replyHeader"); + QTest::addColumn<QString>("replyBody"); + + QTest::newRow("Send PROPFIND for file (bigbox, author, DingALing, Random properties). Get response with responseXML.") << "sendPropfind.responseXML.qml" << "/file" << "propfind.file.expect" << "propfind.file.reply.header" << "propfind.file.reply.body"; + QTest::newRow("Send PROPFIND for file (bigbox, author, DingALing, Random properties). Get response with response.") << "sendPropfind.response.qml" << "/file" << "propfind.file.expect" << "propfind.file.reply.header" << "propfind.file.reply.body"; + QTest::newRow("Send PROPFIND \"allprop\" request for collection.") << "sendPropfind.collection.allprop.qml" << "/container/" << "propfind.collection.allprop.expect" << "propfind.file.reply.header" << "propfind.collection.allprop.reply.body"; +} + // Test that calling hte XMLHttpRequest methods on a non-XMLHttpRequest object // throws an exception void tst_qqmlxmlhttprequest::invalidMethodUsage() @@ -1045,7 +1109,7 @@ void tst_qqmlxmlhttprequest::redirects() object->setProperty("expectedText", ""); component.completeCreate(); - QTRY_VERIFY(object->property("done").toBool() == true); + QTRY_VERIFY(object->property("done").toBool()); QCOMPARE(object->property("dataOK").toBool(), true); } @@ -1062,7 +1126,7 @@ void tst_qqmlxmlhttprequest::redirects() object->setProperty("expectedText", ""); component.completeCreate(); - QTRY_VERIFY(object->property("done").toBool() == true); + QTRY_VERIFY(object->property("done").toBool()); QCOMPARE(object->property("dataOK").toBool(), true); } @@ -1083,7 +1147,7 @@ void tst_qqmlxmlhttprequest::redirects() if (object->property("done").toBool()) break; QTest::qWait(50); } - QVERIFY(object->property("done").toBool() == true); + QVERIFY(object->property("done").toBool()); QCOMPARE(object->property("dataOK").toBool(), true); } @@ -1095,7 +1159,7 @@ void tst_qqmlxmlhttprequest::responseXML_invalid() QScopedPointer<QObject> object(component.create()); QVERIFY(!object.isNull()); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); QCOMPARE(object->property("xmlNull").toBool(), true); } @@ -1107,7 +1171,7 @@ void tst_qqmlxmlhttprequest::document() QScopedPointer<QObject> object(component.create()); QVERIFY(!object.isNull()); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); QCOMPARE(object->property("xmlTest").toBool(), true); } @@ -1119,7 +1183,7 @@ void tst_qqmlxmlhttprequest::element() QScopedPointer<QObject> object(component.create()); QVERIFY(!object.isNull()); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); QCOMPARE(object->property("xmlTest").toBool(), true); } @@ -1131,7 +1195,7 @@ void tst_qqmlxmlhttprequest::attr() QScopedPointer<QObject> object(component.create()); QVERIFY(!object.isNull()); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); QCOMPARE(object->property("xmlTest").toBool(), true); } @@ -1143,9 +1207,10 @@ void tst_qqmlxmlhttprequest::text() QScopedPointer<QObject> object(component.create()); QVERIFY(!object.isNull()); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); QCOMPARE(object->property("xmlTest").toBool(), true); + QCOMPARE(object->property("status").toInt(), 200); } // Test the CDataSection DOM element @@ -1155,9 +1220,10 @@ void tst_qqmlxmlhttprequest::cdata() QScopedPointer<QObject> object(component.create()); QVERIFY(!object.isNull()); - QTRY_VERIFY(object->property("dataOK").toBool() == true); + QTRY_VERIFY(object->property("dataOK").toBool()); QCOMPARE(object->property("xmlTest").toBool(), true); + QCOMPARE(object->property("status").toInt(), 200); } void tst_qqmlxmlhttprequest::stateChangeCallingContext() @@ -1179,7 +1245,7 @@ void tst_qqmlxmlhttprequest::stateChangeCallingContext() object->setProperty("serverBaseUrl", server.baseUrl().toString()); component.completeCreate(); server.sendDelayedItem(); - QTRY_VERIFY(object->property("success").toBool() == true); + QTRY_VERIFY(object->property("success").toBool()); } QTEST_MAIN(tst_qqmlxmlhttprequest) diff --git a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp index 59be469d5b..aca809a137 100644 --- a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp +++ b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp @@ -93,8 +93,8 @@ void tst_qquickfolderlistmodel::checkNoErrors(const QQmlComponent& component) QList<QQmlError> errors = component.errors(); for (int ii = 0; ii < errors.count(); ++ii) { const QQmlError &error = errors.at(ii); - QByteArray errorStr = QByteArray::number(error.line()) + ":" + - QByteArray::number(error.column()) + ":" + + QByteArray errorStr = QByteArray::number(error.line()) + ':' + + QByteArray::number(error.column()) + ':' + error.description().toUtf8(); qWarning() << errorStr; } @@ -295,11 +295,11 @@ void tst_qquickfolderlistmodel::changeDrive() flm->setProperty("folder",QUrl::fromLocalFile(dataDir)); QCOMPARE(flm->property("folder").toUrl(), QUrl::fromLocalFile(dataDir)); - QTRY_VERIFY(folderChangeSpy.count() == 1); + QTRY_COMPARE(folderChangeSpy.count(), 1); flm->setProperty("folder",QUrl::fromLocalFile("X:/resetfiltering/")); QCOMPARE(flm->property("folder").toUrl(), QUrl::fromLocalFile("X:/resetfiltering/")); - QTRY_VERIFY(folderChangeSpy.count() == 2); + QTRY_COMPARE(folderChangeSpy.count(), 2); } #endif diff --git a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp index f4765d0e8d..8ad2b6ba2b 100644 --- a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp +++ b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp @@ -338,19 +338,17 @@ void tst_QQuickWorkerScript::script_global() delete worker; } + qquickworkerscript_lastWarning = QString(); + { + QtMessageHandler previousMsgHandler = qInstallMessageHandler(qquickworkerscript_warningsHandler); + QQmlComponent component(&m_engine, testFileUrl("worker_global2.qml")); QQuickWorkerScript *worker = qobject_cast<QQuickWorkerScript*>(component.create()); QVERIFY(worker != 0); - QString value("Hello"); - - QtMessageHandler previousMsgHandler = qInstallMessageHandler(qquickworkerscript_warningsHandler); - - QVERIFY(QMetaObject::invokeMethod(worker, "testSend", Q_ARG(QVariant, value))); - QTRY_COMPARE(qquickworkerscript_lastWarning, - testFileUrl("script_global.js").toString() + QLatin1String(":2: Invalid write to global property \"world\"")); + testFileUrl("script_global2.js").toString() + QLatin1String(":1: Invalid write to global property \"world\"")); qInstallMessageHandler(previousMsgHandler); diff --git a/tests/auto/qml/qv4debugger/qv4debugger.pro b/tests/auto/qml/qv4debugger/qv4debugger.pro index 2a318955f3..540cab70e6 100644 --- a/tests/auto/qml/qv4debugger/qv4debugger.pro +++ b/tests/auto/qml/qv4debugger/qv4debugger.pro @@ -2,6 +2,14 @@ CONFIG += testcase TARGET = tst_qv4debugger macx:CONFIG -= app_bundle -SOURCES += tst_qv4debugger.cpp +SOURCES += \ + $$PWD/tst_qv4debugger.cpp \ + $$PWD/../../../../src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp + +HEADERS += \ + $$PWD/../../../../src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h + +INCLUDEPATH += \ + $$PWD/../../../../src/plugins/qmltooling/qmldbg_debugger QT += core-private gui-private qml-private network testlib diff --git a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp index 056b24d167..39a1fbc173 100644 --- a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp +++ b/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp @@ -32,12 +32,16 @@ ****************************************************************************/ #include <QtTest/QtTest> +#include "qv4datacollector.h" + #include <QJSEngine> #include <QQmlEngine> #include <QQmlComponent> #include <private/qv4engine_p.h> #include <private/qv4debugging_p.h> #include <private/qv8engine_p.h> +#include <private/qv4objectiterator_p.h> +#include <private/qv4isel_moth_p.h> using namespace QV4; using namespace QV4::Debugging; @@ -85,99 +89,93 @@ public: QV4::ScopedString name(scope, v4->newString(functionName)); QV4::ScopedContext ctx(scope, v4->rootContext()); QV4::ScopedValue function(scope, BuiltinFunction::create(ctx, name, injectedFunction)); - v4->globalObject()->put(name, function); + v4->globalObject->put(name, function); } signals: void evaluateFinished(); }; - -namespace { -class TestCollector: public QV4::Debugging::Debugger::Collector +class TestAgent : public QObject { + Q_OBJECT public: - TestCollector(QV4::ExecutionEngine *engine) - : Collector(engine) - , destination(0) - {} - - virtual ~TestCollector() {} - - void setDestination(QVariantMap *dest) - { destination = dest; } - -protected: - virtual void addUndefined(const QString &name) - { - destination->insert(name, QStringLiteral("undefined")); // TODO: add a user-defined type for this - } - - virtual void addNull(const QString &name) - { - destination->insert(name, QStringLiteral("null")); // TODO: add a user-defined type for this - } - - virtual void addBoolean(const QString &name, bool value) - { - destination->insert(name, value); - } + typedef QV4DataCollector::Refs Refs; + typedef QV4DataCollector::Ref Ref; + struct NamedRefs { + NamedRefs(QV4DataCollector *collector = 0): collector(collector) {} + + QStringList names; + Refs refs; + QV4DataCollector *collector; + + int size() const { + Q_ASSERT(names.size() == refs.size()); + return names.size(); + } - virtual void addString(const QString &name, const QString &value) - { - destination->insert(name, value); - } + bool contains(const QString &name) const { + return names.contains(name); + } - virtual void addObject(const QString &name, const QV4::Value &value) - { - QV4::Scope scope(engine()); - QV4::ScopedObject obj(scope, value.asObject()); +#define DUMP_JSON(x) {\ + QJsonDocument doc(x);\ + qDebug() << #x << "=" << doc.toJson(QJsonDocument::Indented);\ +} - QVariantMap props, *prev = &props; - qSwap(destination, prev); - collect(obj); - qSwap(destination, prev); + QJsonObject rawValue(const QString &name) const { + Q_ASSERT(contains(name)); + return collector->lookupRef(refs.at(names.indexOf(name))); + } - destination->insert(name, props); - } + QJsonValue value(const QString &name) const { + return rawValue(name).value(QStringLiteral("value")); + } - virtual void addInteger(const QString &name, int value) - { - destination->insert(name, QVariant::fromValue<double>(static_cast<double>(value))); - } + QString type(const QString &name) const { + return rawValue(name).value(QStringLiteral("type")).toString(); + } - virtual void addDouble(const QString &name, double value) - { - destination->insert(name, QVariant::fromValue<double>(value)); - } + void dump(const QString &name) const { + if (!contains(name)) { + qDebug() << "no" << name; + return; + } -private: - QVariantMap *destination; -}; -} + QJsonObject o = collector->lookupRef(refs.at(names.indexOf(name))); + QJsonDocument d; + d.setObject(o); + qDebug() << name << "=" << d.toJson(QJsonDocument::Indented); + } + }; -class TestAgent : public QV4::Debugging::DebuggerAgent -{ - Q_OBJECT -public: - TestAgent() + TestAgent(QV4::ExecutionEngine *engine) : m_wasPaused(false) , m_captureContextInfo(false) + , m_thrownValue(-1) + , collector(engine) + , m_debugger(0) { } - virtual void debuggerPaused(Debugger *debugger, PauseReason reason) +public slots: + void debuggerPaused(V4Debugger *debugger, QV4::Debugging::PauseReason reason) { - Q_ASSERT(m_debuggers.count() == 1 && m_debuggers.first() == debugger); + Q_ASSERT(debugger == m_debugger); + Q_ASSERT(debugger->engine() == collector.engine()); m_wasPaused = true; m_pauseReason = reason; m_statesWhenPaused << debugger->currentExecutionState(); - TestCollector collector(debugger->engine()); - QVariantMap tmp; - collector.setDestination(&tmp); - debugger->collectThrownValue(&collector); - m_thrownValue = tmp["exception"]; + if (debugger->state() == V4Debugger::Paused && + debugger->engine()->hasException) { + Refs refs; + RefHolder holder(&collector, &refs); + ExceptionCollectJob job(debugger->engine(), &collector); + debugger->runInEngine(&job); + Q_ASSERT(refs.size() > 0); + m_thrownValue = refs.first(); + } foreach (const TestBreakPoint &bp, m_breakPointsToAddWhenPaused) debugger->addBreakPoint(bp.fileName, bp.lineNumber); @@ -186,28 +184,22 @@ public: m_stackTrace = debugger->stackTrace(); while (!m_expressionRequests.isEmpty()) { + Q_ASSERT(debugger->state() == V4Debugger::Paused); ExpressionRequest request = m_expressionRequests.takeFirst(); - QVariantMap result; - collector.setDestination(&result); - debugger->evaluateExpression(request.frameNr, request.expression, &collector); - m_expressionResults << result[QString::fromLatin1("body")]; + m_expressionResults << Refs(); + RefHolder holder(&collector, &m_expressionResults.last()); + ExpressionEvalJob job(debugger->engine(), request.frameNr, request.expression, + &collector); + debugger->runInEngine(&job); } if (m_captureContextInfo) captureContextInfo(debugger); - debugger->resume(Debugger::FullThrottle); + debugger->resume(V4Debugger::FullThrottle); } - virtual void sourcesCollected(Debugger *debugger, QStringList sources, int requestSequenceNr) - { - Q_UNUSED(debugger); - Q_UNUSED(sources); - Q_UNUSED(requestSequenceNr); - } - - int debuggerCount() const { return m_debuggers.count(); } - +public: struct TestBreakPoint { TestBreakPoint() : lineNumber(-1) {} @@ -217,39 +209,49 @@ public: int lineNumber; }; - void captureContextInfo(Debugger *debugger) + void captureContextInfo(V4Debugger *debugger) { - TestCollector collector(debugger->engine()); - for (int i = 0, ei = m_stackTrace.size(); i != ei; ++i) { - QVariantMap args; - collector.setDestination(&args); - debugger->collectArgumentsInContext(&collector, i); - m_capturedArguments.append(args); - - QVariantMap locals; - collector.setDestination(&locals); - debugger->collectLocalsInContext(&collector, i); - m_capturedLocals.append(locals); + m_capturedArguments.append(NamedRefs(&collector)); + RefHolder argHolder(&collector, &m_capturedArguments.last().refs); + ArgumentCollectJob argumentsJob(debugger->engine(), &collector, + &m_capturedArguments.last().names, i, 0); + debugger->runInEngine(&argumentsJob); + + m_capturedLocals.append(NamedRefs(&collector)); + RefHolder localHolder(&collector, &m_capturedLocals.last().refs); + LocalCollectJob localsJob(debugger->engine(), &collector, + &m_capturedLocals.last().names, i, 0); + debugger->runInEngine(&localsJob); } } + void addDebugger(V4Debugger *debugger) + { + Q_ASSERT(!m_debugger); + m_debugger = debugger; + connect(m_debugger, &V4Debugger::debuggerPaused, + this, &TestAgent::debuggerPaused); + } + bool m_wasPaused; PauseReason m_pauseReason; bool m_captureContextInfo; - QList<Debugger::ExecutionState> m_statesWhenPaused; + QList<V4Debugger::ExecutionState> m_statesWhenPaused; QList<TestBreakPoint> m_breakPointsToAddWhenPaused; QVector<QV4::StackFrame> m_stackTrace; - QList<QVariantMap> m_capturedArguments; - QList<QVariantMap> m_capturedLocals; - QVariant m_thrownValue; + QVector<NamedRefs> m_capturedArguments; + QVector<NamedRefs> m_capturedLocals; + qint64 m_thrownValue; + QV4DataCollector collector; struct ExpressionRequest { QString expression; int frameNr; }; QVector<ExpressionRequest> m_expressionRequests; - QVector<QVariant> m_expressionResults; + QVector<Refs> m_expressionResults; + V4Debugger *m_debugger; // Utility methods: void dumpStackTrace() const @@ -293,6 +295,10 @@ private slots: void evaluateExpression(); private: + V4Debugger *debugger() const + { + return static_cast<V4Debugger *>(m_v4->debugger); + } void evaluateJavaScript(const QString &script, const QString &fileName, int lineNumber = 1) { QMetaObject::invokeMethod(m_engine, "evaluate", Qt::QueuedConnection, @@ -312,11 +318,12 @@ void tst_qv4debugger::init() m_javaScriptThread = new QThread; m_engine = new TestEngine; m_v4 = m_engine->v4Engine(); - m_v4->enableDebugger(); + m_v4->iselFactory.reset(new QV4::Moth::ISelFactory); + m_v4->setDebugger(new V4Debugger(m_v4)); m_engine->moveToThread(m_javaScriptThread); m_javaScriptThread->start(); - m_debuggerAgent = new TestAgent; - m_debuggerAgent->addDebugger(m_v4->debugger); + m_debuggerAgent = new TestAgent(m_v4); + m_debuggerAgent->addDebugger(debugger()); } void tst_qv4debugger::cleanup() @@ -327,7 +334,6 @@ void tst_qv4debugger::cleanup() delete m_javaScriptThread; m_engine = 0; m_v4 = 0; - QCOMPARE(m_debuggerAgent->debuggerCount(), 0); delete m_debuggerAgent; m_debuggerAgent = 0; } @@ -338,7 +344,7 @@ void tst_qv4debugger::breakAnywhere() "var i = 42;\n" "var j = i + 1\n" "var k = i\n"; - m_debuggerAgent->pauseAll(); + debugger()->pause(); evaluateJavaScript(script, "testFile"); QVERIFY(m_debuggerAgent->m_wasPaused); } @@ -349,11 +355,11 @@ void tst_qv4debugger::pendingBreakpoint() "var i = 42;\n" "var j = i + 1\n" "var k = i\n"; - m_debuggerAgent->addBreakPoint("testfile", 2); + debugger()->addBreakPoint("testfile", 2); evaluateJavaScript(script, "testfile"); QVERIFY(m_debuggerAgent->m_wasPaused); QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 1); - QV4::Debugging::Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); + V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); QCOMPARE(state.fileName, QString("testfile")); QCOMPARE(state.lineNumber, 2); } @@ -365,11 +371,11 @@ void tst_qv4debugger::liveBreakPoint() "var j = i + 1\n" "var k = i\n"; m_debuggerAgent->m_breakPointsToAddWhenPaused << TestAgent::TestBreakPoint("liveBreakPoint", 3); - m_debuggerAgent->pauseAll(); + debugger()->pause(); evaluateJavaScript(script, "liveBreakPoint"); QVERIFY(m_debuggerAgent->m_wasPaused); QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 2); - QV4::Debugging::Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.at(1); + V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.at(1); QCOMPARE(state.fileName, QString("liveBreakPoint")); QCOMPARE(state.lineNumber, 3); } @@ -380,8 +386,8 @@ void tst_qv4debugger::removePendingBreakPoint() "var i = 42;\n" "var j = i + 1\n" "var k = i\n"; - int id = m_debuggerAgent->addBreakPoint("removePendingBreakPoint", 2); - m_debuggerAgent->removeBreakPoint(id); + debugger()->addBreakPoint("removePendingBreakPoint", 2); + debugger()->removeBreakPoint("removePendingBreakPoint", 2); evaluateJavaScript(script, "removePendingBreakPoint"); QVERIFY(!m_debuggerAgent->m_wasPaused); } @@ -392,13 +398,13 @@ void tst_qv4debugger::addBreakPointWhilePaused() "var i = 42;\n" "var j = i + 1\n" "var k = i\n"; - m_debuggerAgent->addBreakPoint("addBreakPointWhilePaused", 1); + debugger()->addBreakPoint("addBreakPointWhilePaused", 1); m_debuggerAgent->m_breakPointsToAddWhenPaused << TestAgent::TestBreakPoint("addBreakPointWhilePaused", 2); evaluateJavaScript(script, "addBreakPointWhilePaused"); QVERIFY(m_debuggerAgent->m_wasPaused); QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 2); - QV4::Debugging::Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.at(0); + V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.at(0); QCOMPARE(state.fileName, QString("addBreakPointWhilePaused")); QCOMPARE(state.lineNumber, 1); @@ -409,7 +415,8 @@ void tst_qv4debugger::addBreakPointWhilePaused() static QV4::ReturnedValue someCall(QV4::CallContext *ctx) { - ctx->d()->engine->debugger->removeBreakPoint("removeBreakPointForNextInstruction", 2); + static_cast<V4Debugger *>(ctx->d()->engine->debugger) + ->removeBreakPoint("removeBreakPointForNextInstruction", 2); return QV4::Encode::undefined(); } @@ -422,7 +429,7 @@ void tst_qv4debugger::removeBreakPointForNextInstruction() QMetaObject::invokeMethod(m_engine, "injectFunction", Qt::BlockingQueuedConnection, Q_ARG(QString, "someCall"), Q_ARG(InjectedFunction, someCall)); - m_debuggerAgent->addBreakPoint("removeBreakPointForNextInstruction", 2); + debugger()->addBreakPoint("removeBreakPointForNextInstruction", 2); evaluateJavaScript(script, "removeBreakPointForNextInstruction"); QVERIFY(!m_debuggerAgent->m_wasPaused); @@ -439,28 +446,33 @@ void tst_qv4debugger::conditionalBreakPoint() "}\n" "test()\n"; - m_debuggerAgent->addBreakPoint("conditionalBreakPoint", 3, /*enabled*/true, QStringLiteral("i > 10")); + debugger()->addBreakPoint("conditionalBreakPoint", 3, QStringLiteral("i > 10")); evaluateJavaScript(script, "conditionalBreakPoint"); QVERIFY(m_debuggerAgent->m_wasPaused); QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 4); - QV4::Debugging::Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); + V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); QCOMPARE(state.fileName, QString("conditionalBreakPoint")); QCOMPARE(state.lineNumber, 3); - QCOMPARE(m_debuggerAgent->m_capturedLocals[0].size(), 2); - QVERIFY(m_debuggerAgent->m_capturedLocals[0].contains(QStringLiteral("i"))); - QCOMPARE(m_debuggerAgent->m_capturedLocals[0]["i"].toInt(), 11); + + QVERIFY(m_debuggerAgent->m_capturedLocals.size() > 1); + const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedLocals.at(0); + QCOMPARE(frame0.size(), 2); + QVERIFY(frame0.contains("i")); + QCOMPARE(frame0.value("i").toInt(), 11); } void tst_qv4debugger::conditionalBreakPointInQml() { QQmlEngine engine; QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); - v4->enableDebugger(); + V4Debugger *v4Debugger = new V4Debugger(v4); + v4->iselFactory.reset(new QV4::Moth::ISelFactory); + v4->setDebugger(v4Debugger); QScopedPointer<QThread> debugThread(new QThread); debugThread->start(); - QScopedPointer<TestAgent> debuggerAgent(new TestAgent); - debuggerAgent->addDebugger(v4->debugger); + QScopedPointer<TestAgent> debuggerAgent(new TestAgent(v4)); + debuggerAgent->addDebugger(v4Debugger); debuggerAgent->moveToThread(debugThread.data()); QQmlComponent component(&engine); @@ -474,7 +486,7 @@ void tst_qv4debugger::conditionalBreakPointInQml() " }\n" "}\n", QUrl("test.qml")); - debuggerAgent->addBreakPoint("test.qml", 7, /*enabled*/true, "root.foo == 42"); + v4Debugger->addBreakPoint("test.qml", 7, "root.foo == 42"); QScopedPointer<QObject> obj(component.create()); QCOMPARE(obj->property("success").toBool(), true); @@ -496,16 +508,18 @@ void tst_qv4debugger::readArguments() "}\n" "var four;\n" "f(1, 'two', null, four);\n"; - m_debuggerAgent->addBreakPoint("readArguments", 2); + debugger()->addBreakPoint("readArguments", 2); evaluateJavaScript(script, "readArguments"); QVERIFY(m_debuggerAgent->m_wasPaused); - QCOMPARE(m_debuggerAgent->m_capturedArguments[0].size(), 4); - QVERIFY(m_debuggerAgent->m_capturedArguments[0].contains(QStringLiteral("a"))); - QCOMPARE(m_debuggerAgent->m_capturedArguments[0]["a"].type(), QVariant::Double); - QCOMPARE(m_debuggerAgent->m_capturedArguments[0]["a"].toDouble(), 1.0); - QVERIFY(m_debuggerAgent->m_capturedArguments[0].contains("b")); - QCOMPARE(m_debuggerAgent->m_capturedArguments[0]["b"].type(), QVariant::String); - QCOMPARE(m_debuggerAgent->m_capturedArguments[0]["b"].toString(), QLatin1String("two")); + QVERIFY(m_debuggerAgent->m_capturedArguments.size() > 1); + const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedArguments.at(0); + QCOMPARE(frame0.size(), 4); + QVERIFY(frame0.contains(QStringLiteral("a"))); + QCOMPARE(frame0.type(QStringLiteral("a")), QStringLiteral("number")); + QCOMPARE(frame0.value(QStringLiteral("a")).toDouble(), 1.0); + QVERIFY(frame0.names.contains("b")); + QCOMPARE(frame0.type(QStringLiteral("b")), QStringLiteral("string")); + QCOMPARE(frame0.value(QStringLiteral("b")).toString(), QStringLiteral("two")); } void tst_qv4debugger::readLocals() @@ -518,15 +532,17 @@ void tst_qv4debugger::readLocals() " return c === d\n" "}\n" "f(1, 2, 3);\n"; - m_debuggerAgent->addBreakPoint("readLocals", 3); + debugger()->addBreakPoint("readLocals", 3); evaluateJavaScript(script, "readLocals"); QVERIFY(m_debuggerAgent->m_wasPaused); - QCOMPARE(m_debuggerAgent->m_capturedLocals[0].size(), 2); - QVERIFY(m_debuggerAgent->m_capturedLocals[0].contains("c")); - QCOMPARE(m_debuggerAgent->m_capturedLocals[0]["c"].type(), QVariant::Double); - QCOMPARE(m_debuggerAgent->m_capturedLocals[0]["c"].toDouble(), 3.0); - QVERIFY(m_debuggerAgent->m_capturedLocals[0].contains("d")); - QCOMPARE(m_debuggerAgent->m_capturedLocals[0]["d"].toString(), QString("undefined")); + QVERIFY(m_debuggerAgent->m_capturedLocals.size() > 1); + const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedLocals.at(0); + QCOMPARE(frame0.size(), 2); + QVERIFY(frame0.contains("c")); + QCOMPARE(frame0.type("c"), QStringLiteral("number")); + QCOMPARE(frame0.value("c").toDouble(), 3.0); + QVERIFY(frame0.contains("d")); + QCOMPARE(frame0.type("d"), QStringLiteral("undefined")); } void tst_qv4debugger::readObject() @@ -538,26 +554,43 @@ void tst_qv4debugger::readObject() " return b\n" "}\n" "f({head: 1, tail: { head: 'asdf', tail: null }});\n"; - m_debuggerAgent->addBreakPoint("readObject", 3); + debugger()->addBreakPoint("readObject", 3); evaluateJavaScript(script, "readObject"); QVERIFY(m_debuggerAgent->m_wasPaused); - QCOMPARE(m_debuggerAgent->m_capturedLocals[0].size(), 1); - QVERIFY(m_debuggerAgent->m_capturedLocals[0].contains("b")); - QCOMPARE(m_debuggerAgent->m_capturedLocals[0]["b"].type(), QVariant::Map); - - QVariantMap b = m_debuggerAgent->m_capturedLocals[0]["b"].toMap(); - QCOMPARE(b.size(), 2); - QVERIFY(b.contains("head")); - QCOMPARE(b["head"].type(), QVariant::Double); - QCOMPARE(b["head"].toDouble(), 1.0); - QVERIFY(b.contains("tail")); - QCOMPARE(b["tail"].type(), QVariant::Map); - - QVariantMap b_tail = b["tail"].toMap(); - QCOMPARE(b_tail.size(), 2); - QVERIFY(b_tail.contains("head")); - QCOMPARE(b_tail["head"].type(), QVariant::String); - QCOMPARE(b_tail["head"].toString(), QString("asdf")); + QVERIFY(m_debuggerAgent->m_capturedLocals.size() > 1); + const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedLocals.at(0); + QCOMPARE(frame0.size(), 1); + QVERIFY(frame0.contains("b")); + QCOMPARE(frame0.type("b"), QStringLiteral("object")); + QJsonObject b = frame0.rawValue("b"); + QVERIFY(b.contains(QStringLiteral("properties"))); + QVERIFY(b.value("properties").isArray()); + QJsonArray b_props = b.value("properties").toArray(); + QCOMPARE(b_props.size(), 2); + + QVERIFY(b_props.at(0).isObject()); + QJsonObject b_head = b_props.at(0).toObject(); + QCOMPARE(b_head.value("name").toString(), QStringLiteral("head")); + QCOMPARE(b_head.value("type").toString(), QStringLiteral("number")); + QCOMPARE(b_head.value("value").toDouble(), 1.0); + QVERIFY(b_props.at(1).isObject()); + QJsonObject b_tail = b_props.at(1).toObject(); + QCOMPARE(b_tail.value("name").toString(), QStringLiteral("tail")); + QVERIFY(b_tail.contains("ref")); + + QJsonObject b_tail_value = frame0.collector->lookupRef(b_tail.value("ref").toInt()); + QCOMPARE(b_tail_value.value("type").toString(), QStringLiteral("object")); + QVERIFY(b_tail_value.contains("properties")); + QJsonArray b_tail_props = b_tail_value.value("properties").toArray(); + QCOMPARE(b_tail_props.size(), 2); + QJsonObject b_tail_head = b_tail_props.at(0).toObject(); + QCOMPARE(b_tail_head.value("name").toString(), QStringLiteral("head")); + QCOMPARE(b_tail_head.value("type").toString(), QStringLiteral("string")); + QCOMPARE(b_tail_head.value("value").toString(), QStringLiteral("asdf")); + QJsonObject b_tail_tail = b_tail_props.at(1).toObject(); + QCOMPARE(b_tail_tail.value("name").toString(), QStringLiteral("tail")); + QCOMPARE(b_tail_tail.value("type").toString(), QStringLiteral("null")); + QVERIFY(b_tail_tail.value("value").isNull()); } void tst_qv4debugger::readContextInAllFrames() @@ -573,7 +606,7 @@ void tst_qv4debugger::readContextInAllFrames() " return 1;\n" // breakpoint "}\n" "fact(12);\n"; - m_debuggerAgent->addBreakPoint("readFormalsInAllFrames", 7); + debugger()->addBreakPoint("readFormalsInAllFrames", 7); evaluateJavaScript(script, "readFormalsInAllFrames"); QVERIFY(m_debuggerAgent->m_wasPaused); QCOMPARE(m_debuggerAgent->m_stackTrace.size(), 13); @@ -581,18 +614,20 @@ void tst_qv4debugger::readContextInAllFrames() QCOMPARE(m_debuggerAgent->m_capturedLocals.size(), 13); for (int i = 0; i < 12; ++i) { - QCOMPARE(m_debuggerAgent->m_capturedArguments[i].size(), 1); - QVERIFY(m_debuggerAgent->m_capturedArguments[i].contains("n")); - QCOMPARE(m_debuggerAgent->m_capturedArguments[i]["n"].type(), QVariant::Double); - QCOMPARE(m_debuggerAgent->m_capturedArguments[i]["n"].toDouble(), i + 1.0); - - QCOMPARE(m_debuggerAgent->m_capturedLocals[i].size(), 1); - QVERIFY(m_debuggerAgent->m_capturedLocals[i].contains("n_1")); + const TestAgent::NamedRefs &args = m_debuggerAgent->m_capturedArguments.at(i); + QCOMPARE(args.size(), 1); + QVERIFY(args.contains("n")); + QCOMPARE(args.type("n"), QStringLiteral("number")); + QCOMPARE(args.value("n").toDouble(), i + 1.0); + + const TestAgent::NamedRefs &locals = m_debuggerAgent->m_capturedLocals.at(i); + QCOMPARE(locals.size(), 1); + QVERIFY(locals.contains("n_1")); if (i == 0) { - QCOMPARE(m_debuggerAgent->m_capturedLocals[i]["n_1"].toString(), QString("undefined")); + QCOMPARE(locals.type("n_1"), QStringLiteral("undefined")); } else { - QCOMPARE(m_debuggerAgent->m_capturedLocals[i]["n_1"].type(), QVariant::Double); - QCOMPARE(m_debuggerAgent->m_capturedLocals[i]["n_1"].toInt(), i); + QCOMPARE(locals.type("n_1"), QStringLiteral("number")); + QCOMPARE(locals.value("n_1").toInt(), i); } } QCOMPARE(m_debuggerAgent->m_capturedArguments[12].size(), 0); @@ -606,13 +641,16 @@ void tst_qv4debugger::pauseOnThrow() " throw n\n" "}\n" "die('hard');\n"; - m_debuggerAgent->setBreakOnThrow(true); + debugger()->setBreakOnThrow(true); evaluateJavaScript(script, "pauseOnThrow"); QVERIFY(m_debuggerAgent->m_wasPaused); QCOMPARE(m_debuggerAgent->m_pauseReason, Throwing); QCOMPARE(m_debuggerAgent->m_stackTrace.size(), 2); - QCOMPARE(m_debuggerAgent->m_thrownValue.type(), QVariant::String); - QCOMPARE(m_debuggerAgent->m_thrownValue.toString(), QString("hard")); + QVERIFY(m_debuggerAgent->m_thrownValue >= qint64(0)); + QJsonObject exception = m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_thrownValue); +// DUMP_JSON(exception); + QCOMPARE(exception.value("type").toString(), QStringLiteral("string")); + QCOMPARE(exception.value("value").toString(), QStringLiteral("hard")); } void tst_qv4debugger::breakInCatch() @@ -624,12 +662,12 @@ void tst_qv4debugger::breakInCatch() " console.log(e, 'me');\n" "}\n"; - m_debuggerAgent->addBreakPoint("breakInCatch", 4); + debugger()->addBreakPoint("breakInCatch", 4); evaluateJavaScript(script, "breakInCatch"); QVERIFY(m_debuggerAgent->m_wasPaused); QCOMPARE(m_debuggerAgent->m_pauseReason, BreakPoint); QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 1); - QV4::Debugging::Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); + V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); QCOMPARE(state.fileName, QString("breakInCatch")); QCOMPARE(state.lineNumber, 4); } @@ -641,12 +679,12 @@ void tst_qv4debugger::breakInWith() " console.log('give the answer');\n" "}\n"; - m_debuggerAgent->addBreakPoint("breakInWith", 2); + debugger()->addBreakPoint("breakInWith", 2); evaluateJavaScript(script, "breakInWith"); QVERIFY(m_debuggerAgent->m_wasPaused); QCOMPARE(m_debuggerAgent->m_pauseReason, BreakPoint); QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 1); - QV4::Debugging::Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); + V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); QCOMPARE(state.fileName, QString("breakInWith")); QCOMPARE(state.lineNumber, 2); } @@ -669,13 +707,21 @@ void tst_qv4debugger::evaluateExpression() request.frameNr = 1; m_debuggerAgent->m_expressionRequests << request; - m_debuggerAgent->addBreakPoint("evaluateExpression", 3); + debugger()->addBreakPoint("evaluateExpression", 3); evaluateJavaScript(script, "evaluateExpression"); QCOMPARE(m_debuggerAgent->m_expressionResults.count(), 2); - QCOMPARE(m_debuggerAgent->m_expressionResults[0].toInt(), 10); - QCOMPARE(m_debuggerAgent->m_expressionResults[1].toInt(), 20); + QCOMPARE(m_debuggerAgent->m_expressionResults[0].size(), 1); + QJsonObject result0 = + m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_expressionResults[0].first()); + QCOMPARE(result0.value("type").toString(), QStringLiteral("number")); + QCOMPARE(result0.value("value").toInt(), 10); + QCOMPARE(m_debuggerAgent->m_expressionResults[1].size(), 1); + QJsonObject result1 = + m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_expressionResults[1].first()); + QCOMPARE(result1.value("type").toString(), QStringLiteral("number")); + QCOMPARE(result1.value("value").toInt(), 20); } QTEST_MAIN(tst_qv4debugger) diff --git a/tests/auto/qmldevtools/compile/tst_compile.cpp b/tests/auto/qmldevtools/compile/tst_compile.cpp index b19260779c..4637f14739 100644 --- a/tests/auto/qmldevtools/compile/tst_compile.cpp +++ b/tests/auto/qmldevtools/compile/tst_compile.cpp @@ -37,7 +37,6 @@ #include <private/qqmljsastvisitor_p.h> #include <private/qqmljsast_p.h> #include <private/qqmlirbuilder_p.h> -#include <private/qv4value_inl_p.h> #include <private/qv4codegen_p.h> int main() diff --git a/tests/auto/qmltest/BLACKLIST b/tests/auto/qmltest/BLACKLIST new file mode 100644 index 0000000000..cd8b1181e0 --- /dev/null +++ b/tests/auto/qmltest/BLACKLIST @@ -0,0 +1,5 @@ +# Blacklist for testing +[SelfTests::test_blacklisted_fail] +* +[SelfTests::test_blacklistWithData:test2] +* diff --git a/tests/auto/qmltest/objectmodel/tst_objectmodel.qml b/tests/auto/qmltest/objectmodel/tst_objectmodel.qml new file mode 100644 index 0000000000..e8205a1486 --- /dev/null +++ b/tests/auto/qmltest/objectmodel/tst_objectmodel.qml @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** 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 The Qt Company Ltd 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 QtQml 2.1 +import QtQml.Models 2.3 +import QtTest 1.1 + +TestCase { + name: "ObjectModel" + + ObjectModel { + id: model + QtObject { id: static0 } + QtObject { id: static1 } + QtObject { id: static2 } + } + + Component { id: object; QtObject { } } + + function test_attached_index() { + compare(model.count, 3) + compare(static0.ObjectModel.index, 0) + compare(static1.ObjectModel.index, 1) + compare(static2.ObjectModel.index, 2) + + var dynamic0 = object.createObject(model, {objectName: "dynamic0"}) + compare(dynamic0.ObjectModel.index, -1) + model.append(dynamic0) // -> [static0, static1, static2, dynamic0] + compare(model.count, 4) + for (var i = 0; i < model.count; ++i) + compare(model.get(i).ObjectModel.index, i) + + var dynamic1 = object.createObject(model, {objectName: "dynamic1"}) + compare(dynamic1.ObjectModel.index, -1) + model.insert(0, dynamic1) // -> [dynamic1, static0, static1, static2, dynamic0] + compare(model.count, 5) + for (i = 0; i < model.count; ++i) + compare(model.get(i).ObjectModel.index, i) + + model.move(1, 3) // -> [dynamic1, static1, static2, static0, dynamic0] + compare(model.count, 5) + for (i = 0; i < model.count; ++i) + compare(model.get(i).ObjectModel.index, i) + + model.move(4, 0) // -> [dynamic0, dynamic1, static1, static2, static0] + compare(model.count, 5) + for (i = 0; i < model.count; ++i) + compare(model.get(i).ObjectModel.index, i) + + model.remove(1) // -> [dynamic0, static1, static2, static0] + compare(model.count, 4) + compare(dynamic1.ObjectModel.index, -1) + for (i = 0; i < model.count; ++i) + compare(model.get(i).ObjectModel.index, i) + + model.clear() + compare(static0.ObjectModel.index, -1) + compare(static1.ObjectModel.index, -1) + compare(static2.ObjectModel.index, -1) + compare(dynamic0.ObjectModel.index, -1) + compare(dynamic1.ObjectModel.index, -1) + } +} diff --git a/tests/auto/qmltest/qtbug46798/tst_qtbug46798.qml b/tests/auto/qmltest/qtbug46798/tst_qtbug46798.qml new file mode 100644 index 0000000000..9de9a621f6 --- /dev/null +++ b/tests/auto/qmltest/qtbug46798/tst_qtbug46798.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** 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 The Qt Company Ltd 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.2 +import QtQml.Models 2.3 +import QtTest 1.1 + +Item { + id: top + + ListView { + id: listViewWithObjectModel // QTBUG-46798 + anchors.fill: parent + model: ObjectModel { + id: objectModel + Rectangle { width: 160; height: 160; color: "red" } + Rectangle { width: 160; height: 160; color: "green" } + Rectangle { width: 160; height: 160; color: "blue" } + } + } + + TestCase { + name: "QTBUG-46798" + when: windowShown + + function test_bug46798() { + var item = objectModel.get(0) + if (item) { + objectModel.remove(0) + item.destroy() + } + } + } +} diff --git a/tests/auto/qmltest/selftests/tst_grabImage.qml b/tests/auto/qmltest/selftests/tst_grabImage.qml new file mode 100644 index 0000000000..7a758ae8fc --- /dev/null +++ b/tests/auto/qmltest/selftests/tst_grabImage.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtTest 1.1 + +TestCase { + id: testCase + name: "tst_grabImage" + when: windowShown + + function test_equals() { + var rect = Qt.createQmlObject("import QtQuick 2.0; Rectangle { color: 'red'; width: 10; height: 10; }", testCase); + verify(rect); + var oldImage = grabImage(rect); + rect.width += 10; + var newImage = grabImage(rect); + verify(!newImage.equals(oldImage)); + + oldImage = grabImage(rect); + // Don't change anything... + newImage = grabImage(rect); + verify(newImage.equals(oldImage)); + + verify(!newImage.equals(null)); + verify(!newImage.equals(undefined)); + } +} diff --git a/tests/auto/qmltest/selftests/tst_selftests.qml b/tests/auto/qmltest/selftests/tst_selftests.qml index 0d09f9536a..a372107e26 100644 --- a/tests/auto/qmltest/selftests/tst_selftests.qml +++ b/tests/auto/qmltest/selftests/tst_selftests.qml @@ -278,4 +278,30 @@ TestCase { } verify(caught) } + + function test_blacklisted_fail() + { + verify(false) + } + + function test_blacklistWithData_data() { + return [ + { + tag: "test1", + success: true + }, + { + tag: "test2", + success: false + }, + { + tag: "test3", + success: true + } + ] + } + + function test_blacklistWithData(row) { + verify(row.success) + } } diff --git a/tests/auto/qmltest/textedit/tst_textedit_editingfinished.qml b/tests/auto/qmltest/textedit/tst_textedit_editingfinished.qml new file mode 100644 index 0000000000..c9eadde373 --- /dev/null +++ b/tests/auto/qmltest/textedit/tst_textedit_editingfinished.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** 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 The Qt Company Ltd 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.6 +import QtTest 1.1 + +Row { + width: 100 + height: 50 + spacing: 10 + + property alias control1: _control1 + property alias control2: _control2 + TextEdit { + id: _control1 + text: 'A' + property bool myeditingfinished: false + onEditingFinished: myeditingfinished = true + activeFocusOnTab: true + } + TextEdit { + id: _control2 + text: 'B' + property bool myeditingfinished: false + onEditingFinished: myeditingfinished = true + activeFocusOnTab: true + } + + TestCase { + name: "TextEdit_editingFinished" + when: windowShown + + function test_editingFinished() { + control1.forceActiveFocus() + verify(control1.activeFocus) + verify(!control2.activeFocus) + + verify(control1.myeditingfinished === false) + verify(control2.myeditingfinished === false) + + keyClick(Qt.Key_Backtab) + verify(!control1.activeFocus) + verify(control2.activeFocus) + verify(control1.myeditingfinished === true) + + keyClick(Qt.Key_Backtab) + verify(control1.activeFocus) + verify(!control2.activeFocus) + verify(control2.myeditingfinished === true) + } + } +} diff --git a/tests/auto/qmltest/window/tst_clickwindow.qml b/tests/auto/qmltest/window/tst_clickwindow.qml new file mode 100644 index 0000000000..bbe091990c --- /dev/null +++ b/tests/auto/qmltest/window/tst_clickwindow.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** 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 The Qt Company Ltd 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 QtQuick.Window 2.0 +import QtTest 1.1 + +Item { + width: height + height: 40 + MouseArea { + id: ma + anchors.fill: parent + + property bool everClicked: false + + onClicked: everClicked = true; + } + + Window { + id: ma2Window + width: height + height: 40 + MouseArea { + id: ma2 + anchors.fill: parent + + property bool everClicked: false + + onClicked: everClicked = true; + } + + Component.onCompleted: ma2Window.show(); + } + + TestCase { + name: "ClickWindow" + when: windowShown + + function test_clickBothWindows() { + mouseClick(ma, 20, 20); + verify(ma.everClicked); + mouseClick(ma2, 20, 20); + verify(ma2.everClicked); + } + } +} diff --git a/tests/auto/quick/geometry/tst_geometry.cpp b/tests/auto/quick/geometry/tst_geometry.cpp index 1cc9b112cc..bdd6f1a394 100644 --- a/tests/auto/quick/geometry/tst_geometry.cpp +++ b/tests/auto/quick/geometry/tst_geometry.cpp @@ -58,7 +58,7 @@ void GeometryTest::testPoint2D() QCOMPARE(geometry.sizeOfVertex(), (int) sizeof(float) * 2); QCOMPARE(geometry.vertexCount(), 4); QCOMPARE(geometry.indexCount(), 0); - QVERIFY(geometry.indexData() == 0); + QVERIFY(!geometry.indexData()); QSGGeometry::updateRectGeometry(&geometry, QRectF(1, 2, 3, 4)); @@ -91,7 +91,7 @@ void GeometryTest::testTexturedPoint2D() QCOMPARE(geometry.sizeOfVertex(), (int) sizeof(float) * 4); QCOMPARE(geometry.vertexCount(), 4); QCOMPARE(geometry.indexCount(), 0); - QVERIFY(geometry.indexData() == 0); + QVERIFY(!geometry.indexData()); QSGGeometry::updateTexturedRectGeometry(&geometry, QRectF(1, 2, 3, 4), QRectF(5, 6, 7, 8)); @@ -163,7 +163,7 @@ void GeometryTest::testCustomGeometry() for (int i=0; i<4000; ++i) QCOMPARE(ii[i], (quint16) i); for (int i=0; i<1000; ++i) - QVERIFY(v[i].v1 == 6); + QCOMPARE(v[i].v1, float(6)); } diff --git a/tests/auto/quick/nokeywords/tst_nokeywords.cpp b/tests/auto/quick/nokeywords/tst_nokeywords.cpp index 378af7ea90..58746447f0 100644 --- a/tests/auto/quick/nokeywords/tst_nokeywords.cpp +++ b/tests/auto/quick/nokeywords/tst_nokeywords.cpp @@ -67,7 +67,6 @@ #include <QtQuick/private/qsgrenderer_p.h> #include <QtQuick/private/qsgrenderloop_p.h> #include <QtQuick/private/qsgrendernode_p.h> -#include <QtQuick/private/qsgshareddistancefieldglyphcache_p.h> #include <QtQuick/private/qsgtexturematerial_p.h> #include <QtQuick/private/qsgtexture_p.h> #include <QtQuick/private/qsgthreadedrenderloop_p.h> diff --git a/tests/auto/quick/qquickanchors/tst_qquickanchors.cpp b/tests/auto/quick/qquickanchors/tst_qquickanchors.cpp index 6591d84504..597ea87feb 100644 --- a/tests/auto/quick/qquickanchors/tst_qquickanchors.cpp +++ b/tests/auto/quick/qquickanchors/tst_qquickanchors.cpp @@ -405,15 +405,15 @@ void tst_qquickanchors::resetConvenience() //fill itemPrivate->anchors()->setFill(baseItem); - QVERIFY(itemPrivate->anchors()->fill() == baseItem); + QCOMPARE(itemPrivate->anchors()->fill(), baseItem); itemPrivate->anchors()->resetFill(); - QVERIFY(itemPrivate->anchors()->fill() == 0); + QVERIFY(!itemPrivate->anchors()->fill()); //centerIn itemPrivate->anchors()->setCenterIn(baseItem); - QVERIFY(itemPrivate->anchors()->centerIn() == baseItem); + QCOMPARE(itemPrivate->anchors()->centerIn(), baseItem); itemPrivate->anchors()->resetCenterIn(); - QVERIFY(itemPrivate->anchors()->centerIn() == 0); + QVERIFY(!itemPrivate->anchors()->centerIn()); delete item; delete baseItem; diff --git a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp index a0accfcd58..f4c37b4d66 100644 --- a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp +++ b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp @@ -252,9 +252,7 @@ void tst_qquickanimatedimage::remote() QFETCH(QString, fileName); QFETCH(bool, paused); - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(dataDirectory()); + ThreadedTestHTTPServer server(dataDirectory()); QQmlEngine engine; QQmlComponent component(&engine, server.url(fileName)); @@ -335,48 +333,48 @@ void tst_qquickanimatedimage::sourceSizeChanges() // Local ctxt->setContextProperty("srcImage", QUrl("")); QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Null); - QTRY_VERIFY(sourceSizeSpy.count() == 0); + QTRY_COMPARE(sourceSizeSpy.count(), 0); ctxt->setContextProperty("srcImage", testFileUrl("hearts.gif")); QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready); - QTRY_VERIFY(sourceSizeSpy.count() == 1); + QTRY_COMPARE(sourceSizeSpy.count(), 1); ctxt->setContextProperty("srcImage", testFileUrl("hearts.gif")); QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready); - QTRY_VERIFY(sourceSizeSpy.count() == 1); + QTRY_COMPARE(sourceSizeSpy.count(), 1); ctxt->setContextProperty("srcImage", testFileUrl("hearts_copy.gif")); QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready); - QTRY_VERIFY(sourceSizeSpy.count() == 1); + QTRY_COMPARE(sourceSizeSpy.count(), 1); ctxt->setContextProperty("srcImage", testFileUrl("colors.gif")); QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready); - QTRY_VERIFY(sourceSizeSpy.count() == 2); + QTRY_COMPARE(sourceSizeSpy.count(), 2); ctxt->setContextProperty("srcImage", QUrl("")); QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Null); - QTRY_VERIFY(sourceSizeSpy.count() == 3); + QTRY_COMPARE(sourceSizeSpy.count(), 3); // Remote ctxt->setContextProperty("srcImage", server.url("/hearts.gif")); QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready); - QTRY_VERIFY(sourceSizeSpy.count() == 4); + QTRY_COMPARE(sourceSizeSpy.count(), 4); ctxt->setContextProperty("srcImage", server.url("/hearts.gif")); QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready); - QTRY_VERIFY(sourceSizeSpy.count() == 4); + QTRY_COMPARE(sourceSizeSpy.count(), 4); ctxt->setContextProperty("srcImage", server.url("/hearts_copy.gif")); QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready); - QTRY_VERIFY(sourceSizeSpy.count() == 4); + QTRY_COMPARE(sourceSizeSpy.count(), 4); ctxt->setContextProperty("srcImage", server.url("/colors.gif")); QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready); - QTRY_VERIFY(sourceSizeSpy.count() == 5); + QTRY_COMPARE(sourceSizeSpy.count(), 5); ctxt->setContextProperty("srcImage", QUrl("")); QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Null); - QTRY_VERIFY(sourceSizeSpy.count() == 6); + QTRY_COMPARE(sourceSizeSpy.count(), 6); delete anim; } @@ -397,8 +395,8 @@ void tst_qquickanimatedimage::qtbug_16520() QVERIFY(anim != 0); anim->setProperty("source", server.urlString("/stickman.gif")); - QTRY_VERIFY(anim->opacity() == 0); - QTRY_VERIFY(anim->opacity() == 1); + QTRY_COMPARE(anim->opacity(), qreal(0)); + QTRY_COMPARE(anim->opacity(), qreal(1)); delete anim; delete root; @@ -418,8 +416,8 @@ void tst_qquickanimatedimage::progressAndStatusChanges() component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QQuickImage *obj = qobject_cast<QQuickImage*>(component.create()); QVERIFY(obj != 0); - QVERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QCOMPARE(obj->status(), QQuickImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); qRegisterMetaType<QQuickImageBase::Status>(); QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(QUrl))); @@ -428,33 +426,33 @@ void tst_qquickanimatedimage::progressAndStatusChanges() // Same image ctxt->setContextProperty("srcImage", testFileUrl("stickman.gif")); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(obj->status(), QQuickImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); QTRY_COMPARE(sourceSpy.count(), 0); QTRY_COMPARE(progressSpy.count(), 0); QTRY_COMPARE(statusSpy.count(), 0); // Loading local file ctxt->setContextProperty("srcImage", testFileUrl("colors.gif")); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(obj->status(), QQuickImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); QTRY_COMPARE(sourceSpy.count(), 1); QTRY_COMPARE(progressSpy.count(), 0); QTRY_COMPARE(statusSpy.count(), 1); // Loading remote file ctxt->setContextProperty("srcImage", server.url("/stickman.gif")); - QTRY_VERIFY(obj->status() == QQuickImage::Loading); - QTRY_VERIFY(obj->progress() == 0.0); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(obj->status(), QQuickImage::Loading); + QTRY_COMPARE(obj->progress(), 0.0); + QTRY_COMPARE(obj->status(), QQuickImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); QTRY_COMPARE(sourceSpy.count(), 2); QTRY_VERIFY(progressSpy.count() > 1); QTRY_COMPARE(statusSpy.count(), 3); ctxt->setContextProperty("srcImage", ""); - QTRY_VERIFY(obj->status() == QQuickImage::Null); - QTRY_VERIFY(obj->progress() == 0.0); + QTRY_COMPARE(obj->status(), QQuickImage::Null); + QTRY_COMPARE(obj->progress(), 0.0); QTRY_COMPARE(sourceSpy.count(), 3); QTRY_VERIFY(progressSpy.count() > 2); QTRY_COMPARE(statusSpy.count(), 4); @@ -472,7 +470,7 @@ void tst_qquickanimatedimage::playingAndPausedChanges() component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QQuickAnimatedImage *obj = qobject_cast<QQuickAnimatedImage*>(component.create()); QVERIFY(obj != 0); - QVERIFY(obj->status() == QQuickAnimatedImage::Null); + QCOMPARE(obj->status(), QQuickAnimatedImage::Null); QTRY_VERIFY(obj->isPlaying()); QTRY_VERIFY(!obj->isPaused()); QSignalSpy playingSpy(obj, SIGNAL(playingChanged())); diff --git a/tests/auto/quick/qquickanimationcontroller/data/tst_coloranimation.qml b/tests/auto/quick/qquickanimationcontroller/data/tst_coloranimation.qml index 8374552974..8374552974 100755..100644 --- a/tests/auto/quick/qquickanimationcontroller/data/tst_coloranimation.qml +++ b/tests/auto/quick/qquickanimationcontroller/data/tst_coloranimation.qml diff --git a/tests/auto/quick/qquickanimationcontroller/data/tst_completion.qml b/tests/auto/quick/qquickanimationcontroller/data/tst_completion.qml index 1a8ca81ba0..1a8ca81ba0 100755..100644 --- a/tests/auto/quick/qquickanimationcontroller/data/tst_completion.qml +++ b/tests/auto/quick/qquickanimationcontroller/data/tst_completion.qml diff --git a/tests/auto/quick/qquickanimations/data/animatorInvalidTargetCrash.qml b/tests/auto/quick/qquickanimations/data/animatorInvalidTargetCrash.qml new file mode 100644 index 0000000000..f2c378e4b5 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/animatorInvalidTargetCrash.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.3 +import QtQuick.Window 2.2 + +Window { + visible: true + width: 100 + height: 100 + + OpacityAnimator { + id: anim + from: 1 + to:0 + duration: 5000 + running: false + } + + Loader { + id: loader + sourceComponent: Text { + text: "Hello World" + anchors.centerIn: parent + } + } + + Component.onCompleted: { + anim.target = loader.item; + anim.start(); + loader.active = false; + } +} diff --git a/tests/auto/quick/qquickanimations/data/defaultRotationAnimation.qml b/tests/auto/quick/qquickanimations/data/defaultRotationAnimation.qml new file mode 100644 index 0000000000..94692add60 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/defaultRotationAnimation.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + id: rect + + RotationAnimation { + target: rect + from: 0 + to: 360 + running: true + duration: 1000 + loops: Animation.Infinite + } +} diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp index 45cfe4f334..5cad68b275 100644 --- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp +++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp @@ -104,6 +104,8 @@ private slots: void scriptActionBug(); void groupAnimationNullChildBug(); void scriptActionCrash(); + void animatorInvalidTargetCrash(); + void defaultPropertyWarning(); }; #define QTIMED_COMPARE(lhs, rhs) do { \ @@ -122,9 +124,9 @@ void tst_qquickanimations::simpleProperty() animation.setTargetObject(&rect); animation.setProperty("x"); animation.setTo(200); - QVERIFY(animation.target() == &rect); - QVERIFY(animation.property() == "x"); - QVERIFY(animation.to().toReal() == 200.0); + QCOMPARE(animation.target(), &rect); + QCOMPARE(animation.property(), QLatin1String("x")); + QCOMPARE(animation.to().toReal(), 200.0); animation.start(); QVERIFY(animation.isRunning()); QTest::qWait(animation.duration()); @@ -136,7 +138,7 @@ void tst_qquickanimations::simpleProperty() animation.pause(); QVERIFY(animation.isPaused()); animation.setCurrentTime(125); - QVERIFY(animation.currentTime() == 125); + QCOMPARE(animation.currentTime(), 125); QCOMPARE(rect.x(),100.0); } @@ -147,9 +149,9 @@ void tst_qquickanimations::simpleNumber() animation.setTargetObject(&rect); animation.setProperty("x"); animation.setTo(200); - QVERIFY(animation.target() == &rect); - QVERIFY(animation.property() == "x"); - QVERIFY(animation.to() == 200); + QCOMPARE(animation.target(), &rect); + QCOMPARE(animation.property(), QLatin1String("x")); + QCOMPARE(animation.to(), qreal(200)); animation.start(); QVERIFY(animation.isRunning()); QTest::qWait(animation.duration()); @@ -161,7 +163,7 @@ void tst_qquickanimations::simpleNumber() QVERIFY(animation.isRunning()); QVERIFY(animation.isPaused()); animation.setCurrentTime(125); - QVERIFY(animation.currentTime() == 125); + QCOMPARE(animation.currentTime(), 125); QCOMPARE(rect.x(), qreal(100)); } @@ -172,9 +174,9 @@ void tst_qquickanimations::simpleColor() animation.setTargetObject(&rect); animation.setProperty("color"); animation.setTo(QColor("red")); - QVERIFY(animation.target() == &rect); - QVERIFY(animation.property() == "color"); - QVERIFY(animation.to() == QColor("red")); + QCOMPARE(animation.target(), &rect); + QCOMPARE(animation.property(), QLatin1String("color")); + QCOMPARE(animation.to(), QColor("red")); animation.start(); QVERIFY(animation.isRunning()); QTest::qWait(animation.duration()); @@ -186,12 +188,12 @@ void tst_qquickanimations::simpleColor() QVERIFY(animation.isRunning()); QVERIFY(animation.isPaused()); animation.setCurrentTime(125); - QVERIFY(animation.currentTime() == 125); + QCOMPARE(animation.currentTime(), 125); QCOMPARE(rect.color(), QColor::fromRgbF(0.498039, 0, 0.498039, 1)); rect.setColor(QColor("green")); animation.setFrom(QColor("blue")); - QVERIFY(animation.from() == QColor("blue")); + QCOMPARE(animation.from(), QColor("blue")); animation.restart(); QCOMPARE(rect.color(), QColor("blue")); QVERIFY(animation.isRunning()); @@ -206,10 +208,10 @@ void tst_qquickanimations::simpleRotation() animation.setTargetObject(&rect); animation.setProperty("rotation"); animation.setTo(270); - QVERIFY(animation.target() == &rect); - QVERIFY(animation.property() == "rotation"); - QVERIFY(animation.to() == 270); - QVERIFY(animation.direction() == QQuickRotationAnimation::Numerical); + QCOMPARE(animation.target(), &rect); + QCOMPARE(animation.property(), QLatin1String("rotation")); + QCOMPARE(animation.to(), qreal(270)); + QCOMPARE(animation.direction(), QQuickRotationAnimation::Numerical); animation.start(); QVERIFY(animation.isRunning()); QTest::qWait(animation.duration()); @@ -221,7 +223,7 @@ void tst_qquickanimations::simpleRotation() QVERIFY(animation.isRunning()); QVERIFY(animation.isPaused()); animation.setCurrentTime(125); - QVERIFY(animation.currentTime() == 125); + QCOMPARE(animation.currentTime(), 125); QCOMPARE(rect.rotation(), qreal(135)); } @@ -567,8 +569,8 @@ void tst_qquickanimations::alwaysRunToEnd() animation.setDuration(1000); animation.setLoops(-1); animation.setAlwaysRunToEnd(true); - QVERIFY(animation.loops() == -1); - QVERIFY(animation.alwaysRunToEnd() == true); + QCOMPARE(animation.loops(), -1); + QVERIFY(animation.alwaysRunToEnd()); QElapsedTimer timer; timer.start(); @@ -600,7 +602,7 @@ void tst_qquickanimations::complete() animation.setFrom(1); animation.setTo(200); animation.setDuration(500); - QVERIFY(animation.from() == 1); + QCOMPARE(animation.from().toInt(), 1); animation.start(); QTest::qWait(50); animation.stop(); @@ -620,7 +622,7 @@ void tst_qquickanimations::resume() animation.setFrom(10); animation.setTo(200); animation.setDuration(1000); - QVERIFY(animation.from() == 10); + QCOMPARE(animation.from().toInt(), 10); animation.start(); QTest::qWait(400); @@ -685,7 +687,7 @@ void tst_qquickanimations::dotProperty() animation.start(); animation.pause(); animation.setCurrentTime(125); - QVERIFY(animation.currentTime() == 125); + QCOMPARE(animation.currentTime(), 125); QCOMPARE(rect.border()->width(), 5.0); } @@ -708,7 +710,7 @@ void tst_qquickanimations::badTypes() QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready"); c.create(); - QVERIFY(c.errors().count() == 1); + QCOMPARE(c.errors().count(), 1); QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: number expected")); } @@ -719,7 +721,7 @@ void tst_qquickanimations::badTypes() QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready"); c.create(); - QVERIFY(c.errors().count() == 1); + QCOMPARE(c.errors().count(), 1); QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: color expected")); } @@ -1065,7 +1067,7 @@ void tst_qquickanimations::propertyValueSourceDefaultStart() QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim"); QVERIFY(myAnim); - QVERIFY(myAnim->isRunning() == false); + QVERIFY(!myAnim->isRunning()); } { @@ -1078,7 +1080,7 @@ void tst_qquickanimations::propertyValueSourceDefaultStart() QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim"); QVERIFY(myAnim && !myAnim->qtAnimation()); - //QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimationJob::Stopped); + //QCOMPARE(myAnim->qtAnimation()->state(), QAbstractAnimationJob::Stopped); } } @@ -1097,7 +1099,7 @@ void tst_qquickanimations::dontStart() QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim"); QVERIFY(myAnim && !myAnim->qtAnimation()); - //QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimationJob::Stopped); + //QCOMPARE(myAnim->qtAnimation()->state(), QAbstractAnimationJob::Stopped); } { @@ -1112,7 +1114,7 @@ void tst_qquickanimations::dontStart() QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim"); QVERIFY(myAnim && !myAnim->qtAnimation()); - //QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimationJob::Stopped); + //QCOMPARE(myAnim->qtAnimation()->state(), QAbstractAnimationJob::Stopped); } } @@ -1350,8 +1352,8 @@ void tst_qquickanimations::alwaysRunToEndRestartBug() animation.setDuration(1000); animation.setLoops(-1); animation.setAlwaysRunToEnd(true); - QVERIFY(animation.loops() == -1); - QVERIFY(animation.alwaysRunToEnd() == true); + QCOMPARE(animation.loops(), -1); + QVERIFY(animation.alwaysRunToEnd()); animation.start(); animation.stop(); animation.start(); @@ -1387,7 +1389,7 @@ void tst_qquickanimations::pauseBindingBug() QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); QVERIFY(rect != 0); QQuickAbstractAnimation *anim = rect->findChild<QQuickAbstractAnimation*>("animation"); - QVERIFY(anim->qtAnimation()->state() == QAbstractAnimationJob::Paused); + QCOMPARE(anim->qtAnimation()->state(), QAbstractAnimationJob::Paused); delete rect; } @@ -1491,7 +1493,40 @@ void tst_qquickanimations::scriptActionCrash() delete obj; } +// QTBUG-49364 +// Test that we don't crash when the target of an Animator becomes +// invalid between the time the animator is started and the time the +// animator job is actually started +void tst_qquickanimations::animatorInvalidTargetCrash() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("animatorInvalidTargetCrash.qml")); + QObject *obj = c.create(); + + //just testing that we don't crash + QTest::qWait(5000); //animator duration + + delete obj; +} + +Q_DECLARE_METATYPE(QList<QQmlError>) + +// QTBUG-22141 +void tst_qquickanimations::defaultPropertyWarning() +{ + QQmlEngine engine; + + qRegisterMetaType<QList<QQmlError> >(); + QSignalSpy warnings(&engine, SIGNAL(warnings(QList<QQmlError>))); + QVERIFY(warnings.isValid()); + + QQmlComponent component(&engine, testFileUrl("defaultRotationAnimation.qml")); + QScopedPointer<QQuickItem> root(qobject_cast<QQuickItem*>(component.create())); + QVERIFY(root); + + QVERIFY(warnings.isEmpty()); +} QTEST_MAIN(tst_qquickanimations) diff --git a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp index 7df020405f..1d8fc430b8 100644 --- a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp +++ b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp @@ -97,7 +97,7 @@ void tst_qquickapplication::active() window.show(); window.requestActivate(); QTest::qWaitForWindowActive(&window); - QVERIFY(QGuiApplication::focusWindow() == &window); + QCOMPARE(QGuiApplication::focusWindow(), &window); QVERIFY(item->property("active").toBool()); QVERIFY(item->property("active2").toBool()); @@ -167,7 +167,7 @@ void tst_qquickapplication::state() window.show(); window.requestActivate(); QTest::qWaitForWindowActive(&window); - QVERIFY(QGuiApplication::focusWindow() == &window); + QCOMPARE(QGuiApplication::focusWindow(), &window); QCOMPARE(Qt::ApplicationState(item->property("state").toInt()), Qt::ApplicationActive); QCOMPARE(Qt::ApplicationState(item->property("state2").toInt()), Qt::ApplicationActive); diff --git a/tests/auto/quick/qquickbehaviors/BLACKLIST b/tests/auto/quick/qquickbehaviors/BLACKLIST new file mode 100644 index 0000000000..9be4da176d --- /dev/null +++ b/tests/auto/quick/qquickbehaviors/BLACKLIST @@ -0,0 +1,2 @@ +[currentValue] +windows diff --git a/tests/auto/quick/qquickbehaviors/data/Accelerator.qml b/tests/auto/quick/qquickbehaviors/data/Accelerator.qml new file mode 100644 index 0000000000..a2b5146c3f --- /dev/null +++ b/tests/auto/quick/qquickbehaviors/data/Accelerator.qml @@ -0,0 +1,18 @@ +import QtQuick 2.3 + +Rectangle { + property alias value: range.width + color: "yellow" + Text { + text: 'value: ' + value + } + + Rectangle { + id: range + objectName: "range" + color: "red" + width: 0 + height: 5 + anchors.bottom: parent.bottom + } +} diff --git a/tests/auto/quick/qquickbehaviors/data/aliased.qml b/tests/auto/quick/qquickbehaviors/data/aliased.qml new file mode 100644 index 0000000000..e65e035d83 --- /dev/null +++ b/tests/auto/quick/qquickbehaviors/data/aliased.qml @@ -0,0 +1,39 @@ +import QtQuick 2.3 + +Rectangle { + width: 400 + height: 400 + id: rect + property bool accelerating : false + + Text { + anchors.centerIn: parent + text: "Press anywere to accelerate" + } + + Accelerator { + id: acc + objectName: "acc" + anchors.fill: parent + value: accelerating ? 400 : 0 + Behavior on value { + NumberAnimation { + duration: 500 + } + } + } + + MouseArea { + id: clicker + anchors.fill: parent + } + + states: State { + name: "moved" + when: clicker.pressed + PropertyChanges { + target: rect + accelerating: true + } + } +} diff --git a/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp b/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp index b96f1de930..635958314f 100644 --- a/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp +++ b/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp @@ -76,45 +76,42 @@ private slots: void multipleChangesToValueType(); void currentValue(); void disabledWriteWhileRunning(); + void aliasedProperty(); }; void tst_qquickbehaviors::simpleBehavior() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("simple.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QTRY_VERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); QTRY_VERIFY(qobject_cast<QQuickBehavior*>(rect->findChild<QQuickBehavior*>("MyBehavior"))->animation()); - QQuickItemPrivate::get(rect)->setState("moved"); + QQuickItemPrivate::get(rect.data())->setState("moved"); QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() > 0); QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() < 200); //i.e. the behavior has been triggered - - delete rect; } void tst_qquickbehaviors::scriptTriggered() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("scripttrigger.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QTRY_VERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); rect->setColor(QColor("red")); QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() > 0); QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() < 200); //i.e. the behavior has been triggered - - delete rect; } void tst_qquickbehaviors::cppTriggered() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("cpptrigger.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QTRY_VERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect")); QTRY_VERIFY(innerRect); @@ -122,60 +119,52 @@ void tst_qquickbehaviors::cppTriggered() innerRect->setProperty("x", 200); QTRY_VERIFY(innerRect->x() > 0); QTRY_VERIFY(innerRect->x() < 200); //i.e. the behavior has been triggered - - delete rect; } void tst_qquickbehaviors::loop() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("loop.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QTRY_VERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); //don't crash - QQuickItemPrivate::get(rect)->setState("moved"); - - delete rect; + QQuickItemPrivate::get(rect.data())->setState("moved"); } void tst_qquickbehaviors::colorBehavior() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("color.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QTRY_VERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); - QQuickItemPrivate::get(rect)->setState("red"); + QQuickItemPrivate::get(rect.data())->setState("red"); QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->color() != QColor("red")); QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->color() != QColor("green")); //i.e. the behavior has been triggered - - delete rect; } void tst_qquickbehaviors::parentBehavior() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("parent.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QTRY_VERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); - QQuickItemPrivate::get(rect)->setState("reparented"); + QQuickItemPrivate::get(rect.data())->setState("reparented"); QTRY_VERIFY(rect->findChild<QQuickRectangle*>("MyRect")->parentItem() != rect->findChild<QQuickItem*>("NewParent")); QTRY_VERIFY(rect->findChild<QQuickRectangle*>("MyRect")->parentItem() == rect->findChild<QQuickItem*>("NewParent")); - - delete rect; } void tst_qquickbehaviors::replaceBinding() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("binding.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QTRY_VERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); - QQuickItemPrivate::get(rect)->setState("moved"); + QQuickItemPrivate::get(rect.data())->setState("moved"); QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect")); QTRY_VERIFY(innerRect); QTRY_VERIFY(innerRect->x() > 0); @@ -187,7 +176,7 @@ void tst_qquickbehaviors::replaceBinding() rect->setProperty("movedx", 210); QTRY_COMPARE(innerRect->x(), (qreal)210); - QQuickItemPrivate::get(rect)->setState(""); + QQuickItemPrivate::get(rect.data())->setState(""); QTRY_VERIFY(innerRect->x() > 10); QTRY_VERIFY(innerRect->x() < 210); //i.e. the behavior has been triggered QTRY_COMPARE(innerRect->x(), (qreal)10); @@ -195,8 +184,6 @@ void tst_qquickbehaviors::replaceBinding() QTRY_COMPARE(innerRect->x(), (qreal)10); rect->setProperty("basex", 20); QTRY_COMPARE(innerRect->x(), (qreal)20); - - delete rect; } void tst_qquickbehaviors::group() @@ -205,32 +192,27 @@ void tst_qquickbehaviors::group() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("groupProperty.qml"))); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - qDebug() << c.errorString(); - QTRY_VERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); - QQuickItemPrivate::get(rect)->setState("moved"); + QQuickItemPrivate::get(rect.data())->setState("moved"); //QTest::qWait(200); QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() > 0); QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() < 200); //i.e. the behavior has been triggered - - delete rect; } */ { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("groupProperty2.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QTRY_VERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); - QQuickItemPrivate::get(rect)->setState("moved"); + QQuickItemPrivate::get(rect.data())->setState("moved"); QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->border()->width() > 0); QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->border()->width() < 4); //i.e. the behavior has been triggered - - delete rect; } } @@ -238,56 +220,48 @@ void tst_qquickbehaviors::valueType() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("valueType.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QVERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); //QTBUG-20827 QCOMPARE(rect->color(), QColor::fromRgb(255,0,255)); - - delete rect; } void tst_qquickbehaviors::emptyBehavior() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("empty.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QVERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); - QQuickItemPrivate::get(rect)->setState("moved"); + QQuickItemPrivate::get(rect.data())->setState("moved"); qreal x = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x(); QCOMPARE(x, qreal(200)); //should change immediately - - delete rect; } void tst_qquickbehaviors::explicitSelection() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("explicit.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QVERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); - QQuickItemPrivate::get(rect)->setState("moved"); + QQuickItemPrivate::get(rect.data())->setState("moved"); QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() > 0); QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() < 200); //i.e. the behavior has been triggered - - delete rect; } void tst_qquickbehaviors::nonSelectingBehavior() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("nonSelecting2.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QVERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); - QQuickItemPrivate::get(rect)->setState("moved"); + QQuickItemPrivate::get(rect.data())->setState("moved"); qreal x = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x(); QCOMPARE(x, qreal(200)); //should change immediately - - delete rect; } void tst_qquickbehaviors::reassignedAnimation() @@ -296,27 +270,23 @@ void tst_qquickbehaviors::reassignedAnimation() QQmlComponent c(&engine, testFileUrl("reassignedAnimation.qml")); QString warning = testFileUrl("reassignedAnimation.qml").toString() + ":9:9: QML Behavior: Cannot change the animation assigned to a Behavior."; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QVERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); QCOMPARE(qobject_cast<QQuickNumberAnimation*>( rect->findChild<QQuickBehavior*>("MyBehavior")->animation())->duration(), 200); - - delete rect; } void tst_qquickbehaviors::disabled() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("disabled.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QVERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); QCOMPARE(rect->findChild<QQuickBehavior*>("MyBehavior")->enabled(), false); - QQuickItemPrivate::get(rect)->setState("moved"); + QQuickItemPrivate::get(rect.data())->setState("moved"); qreal x = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x(); QCOMPARE(x, qreal(200)); //should change immediately - - delete rect; } void tst_qquickbehaviors::dontStart() @@ -327,13 +297,12 @@ void tst_qquickbehaviors::dontStart() QString warning = c.url().toString() + ":13:13: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes."; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QVERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim"); - QVERIFY(myAnim && !myAnim->qtAnimation()); - - delete rect; + QVERIFY(myAnim); + QVERIFY(!myAnim->qtAnimation()); } void tst_qquickbehaviors::startup() @@ -341,22 +310,20 @@ void tst_qquickbehaviors::startup() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("startup.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QVERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); QQuickRectangle *innerRect = rect->findChild<QQuickRectangle*>("innerRect"); QVERIFY(innerRect); QCOMPARE(innerRect->x(), qreal(100)); //should be set immediately - - delete rect; } { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("startup2.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QVERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); QQuickRectangle *innerRect = rect->findChild<QQuickRectangle*>("innerRect"); QVERIFY(innerRect); @@ -365,8 +332,6 @@ void tst_qquickbehaviors::startup() QVERIFY(text); QCOMPARE(innerRect->x(), text->width()); //should be set immediately - - delete rect; } } @@ -375,10 +340,8 @@ void tst_qquickbehaviors::groupedPropertyCrash() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("groupedPropertyCrash.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QVERIFY(rect); //don't crash - - delete rect; + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); //don't crash } //QTBUG-5491 @@ -386,8 +349,8 @@ void tst_qquickbehaviors::runningTrue() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("runningTrue.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QVERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); QQuickAbstractAnimation *animation = rect->findChild<QQuickAbstractAnimation*>("rotAnim"); QVERIFY(animation); @@ -395,8 +358,6 @@ void tst_qquickbehaviors::runningTrue() QSignalSpy runningSpy(animation, SIGNAL(runningChanged(bool))); rect->setProperty("myValue", 180); QTRY_VERIFY(runningSpy.count() > 0); - - delete rect; } //QTBUG-12295 @@ -404,8 +365,8 @@ void tst_qquickbehaviors::sameValue() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("qtbug12295.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QVERIFY(rect); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); QQuickRectangle *target = rect->findChild<QQuickRectangle*>("myRect"); QVERIFY(target); @@ -424,8 +385,6 @@ void tst_qquickbehaviors::sameValue() //even though we set 0 twice in a row. target->setProperty("x", 0); QTRY_VERIFY(target->x() != qreal(0) && target->x() != qreal(100)); - - delete rect; } //QTBUG-18362 @@ -434,8 +393,8 @@ void tst_qquickbehaviors::delayedRegistration() QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("delayedRegistration.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QVERIFY(rect != 0); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); QQuickItem *innerRect = rect->property("myItem").value<QQuickItem*>(); QVERIFY(innerRect != 0); @@ -451,8 +410,8 @@ void tst_qquickbehaviors::startOnCompleted() QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("startOnCompleted.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); - QVERIFY(rect != 0); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));; + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); QQuickItem *innerRect = rect->findChild<QQuickRectangle*>(); QVERIFY(innerRect != 0); @@ -460,8 +419,6 @@ void tst_qquickbehaviors::startOnCompleted() QCOMPARE(innerRect->property("x").toInt(), int(0)); QTRY_COMPARE(innerRect->property("x").toInt(), int(100)); - - delete rect; } //QTBUG-25139 @@ -471,7 +428,7 @@ void tst_qquickbehaviors::multipleChangesToValueType() QQmlComponent c(&engine, testFileUrl("multipleChangesToValueType.qml")); QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle *>(c.create())); - QVERIFY(rect != 0); + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); QQuickText *text = rect->findChild<QQuickText *>(); QVERIFY(text != 0); @@ -496,8 +453,8 @@ void tst_qquickbehaviors::currentValue() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("qtbug21549.qml")); - QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); - QVERIFY(item); + QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(c.create())); + QVERIFY2(!item.isNull(), qPrintable(c.errorString())); QQuickRectangle *target = item->findChild<QQuickRectangle*>("myRect"); QVERIFY(target); @@ -516,15 +473,13 @@ void tst_qquickbehaviors::currentValue() target->setProperty("x", 100); QCOMPARE(item->property("behaviorCount").toInt(), 1); QCOMPARE(target->x(), qreal(100)); - - delete item; } { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("qtbug21549-2.qml")); - QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); - QVERIFY(item); + QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(c.create())); + QVERIFY2(!item.isNull(), qPrintable(c.errorString())); QQuickRectangle *target = item->findChild<QQuickRectangle*>("myRect"); QVERIFY(target); @@ -537,9 +492,7 @@ void tst_qquickbehaviors::currentValue() // in the QML (which should be between 50 and 80); QTRY_COMPARE(item->property("animRunning").toBool(), true); QTRY_COMPARE(item->property("animRunning").toBool(), false); - QVERIFY(target->x() > qreal(50) && target->x() < qreal(80)); - - delete item; + QVERIFY2(target->x() > qreal(50) && target->x() < qreal(80), QByteArray::number(target->x())); } } @@ -548,8 +501,8 @@ void tst_qquickbehaviors::disabledWriteWhileRunning() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("disabledWriteWhileRunning.qml")); - QQuickItem *root = qobject_cast<QQuickItem*>(c.create()); - QVERIFY(root); + QScopedPointer<QQuickItem> root(qobject_cast<QQuickItem*>(c.create())); + QVERIFY2(!root.isNull(), qPrintable(c.errorString())); QQuickRectangle *myRect = qobject_cast<QQuickRectangle*>(root->findChild<QQuickRectangle*>("MyRect")); QQuickBehavior *myBehavior = qobject_cast<QQuickBehavior*>(root->findChild<QQuickBehavior*>("MyBehavior")); @@ -579,16 +532,14 @@ void tst_qquickbehaviors::disabledWriteWhileRunning() QCOMPARE(myRect->x(), qreal(100)); QTest::qWait(200); QCOMPARE(myRect->x(), qreal(100)); - - delete root; } //test additional complications with SmoothedAnimation { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("disabledWriteWhileRunning2.qml")); - QQuickItem *root = qobject_cast<QQuickItem*>(c.create()); - QVERIFY(root); + QScopedPointer<QQuickItem> root(qobject_cast<QQuickItem*>(c.create())); + QVERIFY2(!root.isNull(), qPrintable(c.errorString())); QQuickRectangle *myRect = qobject_cast<QQuickRectangle*>(root->findChild<QQuickRectangle*>("MyRect")); QQuickBehavior *myBehavior = qobject_cast<QQuickBehavior*>(root->findChild<QQuickBehavior*>("MyBehavior")); @@ -623,11 +574,26 @@ void tst_qquickbehaviors::disabledWriteWhileRunning() QCOMPARE(myRect->x(), qreal(100)); QTest::qWait(200); QCOMPARE(myRect->x(), qreal(100)); - - delete root; } } +void tst_qquickbehaviors::aliasedProperty() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("aliased.qml")); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create())); + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); + + QQuickItemPrivate::get(rect.data())->setState("moved"); + QScopedPointer<QQuickRectangle> acc(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("acc"))); + QScopedPointer<QQuickRectangle> range(qobject_cast<QQuickRectangle*>(acc->findChild<QQuickRectangle*>("range"))); + QTRY_VERIFY(acc->property("value").toDouble() > 0); + QTRY_VERIFY(range->width() > 0); + QTRY_VERIFY(acc->property("value").toDouble() < 400); + QTRY_VERIFY(range->width() < 400); + //i.e. the behavior has been triggered +} + QTEST_MAIN(tst_qquickbehaviors) #include "tst_qquickbehaviors.moc" diff --git a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp index efe2ca8b18..265579ead2 100644 --- a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp +++ b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp @@ -123,7 +123,7 @@ void tst_qquickborderimage::imageSource_data() << "<Unknown File>:2:1: QML BorderImage: Cannot open: " + testFileUrl("no-such-file.png").toString(); QTest::newRow("remote") << "/colors.png" << true << ""; QTest::newRow("remote not found") << "/no-such-file.png" << true - << "<Unknown File>:2:1: QML BorderImage: Error downloading {{ServerBaseUrl}}/no-such-file.png - server replied: Not found"; + << "<Unknown File>:2:1: QML BorderImage: Error transferring {{ServerBaseUrl}}/no-such-file.png - server replied: Not found"; } void tst_qquickborderimage::imageSource() @@ -132,6 +132,13 @@ void tst_qquickborderimage::imageSource() QFETCH(bool, remote); QFETCH(QString, error); +#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) + if (qstrcmp(QTest::currentDataTag(), "remote") == 0 + || qstrcmp(QTest::currentDataTag(), "remote not found") == 0) { + QSKIP("Remote tests cause occasional hangs in the CI system -- QTBUG-45655"); + } +#endif + TestHTTPServer server; if (remote) { QVERIFY2(server.listen(), qPrintable(server.errorString())); @@ -150,12 +157,12 @@ void tst_qquickborderimage::imageSource() QVERIFY(obj != 0); if (remote) - QTRY_VERIFY(obj->status() == QQuickBorderImage::Loading); + QTRY_COMPARE(obj->status(), QQuickBorderImage::Loading); QCOMPARE(obj->source(), remote ? source : QUrl(source)); if (error.isEmpty()) { - QTRY_VERIFY(obj->status() == QQuickBorderImage::Ready); + QTRY_COMPARE(obj->status(), QQuickBorderImage::Ready); QCOMPARE(obj->width(), 120.); QCOMPARE(obj->height(), 120.); QCOMPARE(obj->sourceSize().width(), 120); @@ -163,7 +170,7 @@ void tst_qquickborderimage::imageSource() QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch); QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch); } else { - QTRY_VERIFY(obj->status() == QQuickBorderImage::Error); + QTRY_COMPARE(obj->status(), QQuickBorderImage::Error); } delete obj; @@ -178,13 +185,13 @@ void tst_qquickborderimage::clearSource() component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QQuickBorderImage *obj = qobject_cast<QQuickBorderImage*>(component.create()); QVERIFY(obj != 0); - QVERIFY(obj->status() == QQuickBorderImage::Ready); + QCOMPARE(obj->status(), QQuickBorderImage::Ready); QCOMPARE(obj->width(), 120.); QCOMPARE(obj->height(), 120.); ctxt->setContextProperty("srcImage", ""); QVERIFY(obj->source().isEmpty()); - QVERIFY(obj->status() == QQuickBorderImage::Null); + QCOMPARE(obj->status(), QQuickBorderImage::Null); QCOMPARE(obj->width(), 0.); QCOMPARE(obj->height(), 0.); @@ -296,14 +303,14 @@ void tst_qquickborderimage::sciSource() QVERIFY(obj != 0); if (remote) - QTRY_VERIFY(obj->status() == QQuickBorderImage::Loading); + QTRY_COMPARE(obj->status(), QQuickBorderImage::Loading); QCOMPARE(obj->source(), remote ? source : QUrl(source)); QCOMPARE(obj->width(), 300.); QCOMPARE(obj->height(), 300.); if (valid) { - QTRY_VERIFY(obj->status() == QQuickBorderImage::Ready); + QTRY_COMPARE(obj->status(), QQuickBorderImage::Ready); QCOMPARE(obj->border()->left(), 10); QCOMPARE(obj->border()->top(), 20); QCOMPARE(obj->border()->right(), 30); @@ -311,7 +318,7 @@ void tst_qquickborderimage::sciSource() QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Round); QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Repeat); } else { - QTRY_VERIFY(obj->status() == QQuickBorderImage::Error); + QTRY_COMPARE(obj->status(), QQuickBorderImage::Error); } delete obj; @@ -443,7 +450,7 @@ void tst_qquickborderimage::statusChanges() obj->setSource(source); if (remote) server.sendDelayedItem(); - QTRY_VERIFY(obj->status() == finalStatus); + QTRY_COMPARE(obj->status(), finalStatus); QCOMPARE(spy.count(), emissions); delete obj; @@ -529,8 +536,8 @@ void tst_qquickborderimage::progressAndStatusChanges() component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QQuickBorderImage *obj = qobject_cast<QQuickBorderImage*>(component.create()); QVERIFY(obj != 0); - QVERIFY(obj->status() == QQuickBorderImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QCOMPARE(obj->status(), QQuickBorderImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); qRegisterMetaType<QQuickBorderImage::Status>(); QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(QUrl))); @@ -539,33 +546,33 @@ void tst_qquickborderimage::progressAndStatusChanges() // Same file ctxt->setContextProperty("srcImage", testFileUrl("heart200.png")); - QTRY_VERIFY(obj->status() == QQuickBorderImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(obj->status(), QQuickBorderImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); QTRY_COMPARE(sourceSpy.count(), 0); QTRY_COMPARE(progressSpy.count(), 0); QTRY_COMPARE(statusSpy.count(), 0); // Loading local file ctxt->setContextProperty("srcImage", testFileUrl("colors.png")); - QTRY_VERIFY(obj->status() == QQuickBorderImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(obj->status(), QQuickBorderImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); QTRY_COMPARE(sourceSpy.count(), 1); QTRY_COMPARE(progressSpy.count(), 0); QTRY_COMPARE(statusSpy.count(), 1); // Loading remote file ctxt->setContextProperty("srcImage", server.url("/heart200.png")); - QTRY_VERIFY(obj->status() == QQuickBorderImage::Loading); - QTRY_VERIFY(obj->progress() == 0.0); - QTRY_VERIFY(obj->status() == QQuickBorderImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(obj->status(), QQuickBorderImage::Loading); + QTRY_COMPARE(obj->progress(), 0.0); + QTRY_COMPARE(obj->status(), QQuickBorderImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); QTRY_COMPARE(sourceSpy.count(), 2); QTRY_VERIFY(progressSpy.count() > 1); QTRY_COMPARE(statusSpy.count(), 3); ctxt->setContextProperty("srcImage", ""); - QTRY_VERIFY(obj->status() == QQuickBorderImage::Null); - QTRY_VERIFY(obj->progress() == 0.0); + QTRY_COMPARE(obj->status(), QQuickBorderImage::Null); + QTRY_COMPARE(obj->progress(), 0.0); QTRY_COMPARE(sourceSpy.count(), 3); QTRY_VERIFY(progressSpy.count() > 2); QTRY_COMPARE(statusSpy.count(), 4); diff --git a/tests/auto/quick/qquickdesignersupport/data/TestComponent.qml b/tests/auto/quick/qquickdesignersupport/data/TestComponent.qml new file mode 100644 index 0000000000..68f456af99 --- /dev/null +++ b/tests/auto/quick/qquickdesignersupport/data/TestComponent.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 + +Item { + width: 100 + height: 62 + + x: Math.max(0, 200) +} + diff --git a/tests/auto/quick/qquickdesignersupport/data/test.qml b/tests/auto/quick/qquickdesignersupport/data/test.qml new file mode 100644 index 0000000000..1d43cb3b7e --- /dev/null +++ b/tests/auto/quick/qquickdesignersupport/data/test.qml @@ -0,0 +1,39 @@ +import QtQuick 2.0 + +Rectangle { + objectName: "rootItem" + color: "white" + width: 800 + height: 600 + + TestComponent { + objectName: "testComponent" + + } + + Rectangle { + objectName: "rectangleItem" + gradient: Gradient { + + } + } + + Item { + id: item + objectName: "simpleItem" + property string testProperty: dynamicProperty + } + + states: [ + State { + name: "state01" + PropertyChanges { + target: item + width: 10 + } + }, + State { + name: "state02" + } + ] +} diff --git a/tests/auto/quick/qquickdesignersupport/qquickdesignersupport.pro b/tests/auto/quick/qquickdesignersupport/qquickdesignersupport.pro new file mode 100644 index 0000000000..af932d834b --- /dev/null +++ b/tests/auto/quick/qquickdesignersupport/qquickdesignersupport.pro @@ -0,0 +1,16 @@ +CONFIG += testcase +TARGET = tst_qquickdesignersupport +SOURCES += tst_qquickdesignersupport.cpp + +include (../../shared/util.pri) +include (../shared/util.pri) + +osx:CONFIG -= app_bundle + +TESTDATA = data/* + +QT += core-private gui-private qml-private quick-private testlib +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +DISTFILES += \ + data/TestComponent.qml diff --git a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp new file mode 100644 index 0000000000..1104ce1d98 --- /dev/null +++ b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp @@ -0,0 +1,501 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <qtest.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQuick/qquickview.h> +#include <private/qquickdesignersupportitems_p.h> +#include <private/qquickdesignersupportmetainfo_p.h> +#include <private/qquickdesignersupportproperties_p.h> +#include <private/qquickdesignersupportstates_p.h> +#include <private/qquickdesignersupportpropertychanges_p.h> +#include <private/qquickitem_p.h> +#include <private/qquickstate_p.h> +#include <private/qquickstate_p_p.h> +#include <private/qquickstategroup_p.h> +#include <private/qquickpropertychanges_p.h> +#include <private/qquickrectangle_p.h> +#include "../../shared/util.h" +#include "../shared/visualtestutil.h" + +using namespace QQuickVisualTestUtil; + +class tst_qquickdesignersupport : public QQmlDataTest +{ + Q_OBJECT +public: + tst_qquickdesignersupport() {} + +private slots: + void customData(); + void customDataBindings(); + void objectProperties(); + void dynamicProperty(); + void createComponent(); + void basicStates(); + void statesPropertyChanges(); + void testNotifyPropertyChangeCallBack(); + void testFixResourcePathsForObjectCallBack(); +}; + +void tst_qquickdesignersupport::customData() +{ + QScopedPointer<QQuickView> view(new QQuickView); + view->engine()->setOutputWarningsToStandardError(false); + view->setSource(testFileUrl("test.qml")); + + QVERIFY(view->errors().isEmpty()); + + QQuickItem *rootItem = view->rootObject(); + + QVERIFY(rootItem); + + QScopedPointer<QObject> newItemScopedPointer(QQuickDesignerSupportItems::createPrimitive(QLatin1String("QtQuick/Item"), 2, 6, view->rootContext())); + QObject *newItem = newItemScopedPointer.data(); + + QVERIFY(newItem); + QVERIFY(qobject_cast<QQuickItem*>(newItem)); + + QQuickDesignerSupportProperties::registerCustomData(newItem); + QVERIFY(QQuickDesignerSupportProperties::getResetValue(newItem, "width").isValid()); + int defaultWidth = QQuickDesignerSupportProperties::getResetValue(newItem, "width").toInt(); + QCOMPARE(defaultWidth, 0); + + newItem->setProperty("width", 200); + QCOMPARE(newItem->property("width").toInt(), 200); + + //Check if reseting property does work + QQuickDesignerSupportProperties::doResetProperty(newItem, view->rootContext(), "width"); + QCOMPARE(newItem->property("width").toInt(), 0); + + //Setting a binding on width + QQuickDesignerSupportProperties::setPropertyBinding(newItem, + view->engine()->contextForObject(newItem), + "width", + QLatin1String("Math.max(0, 200)")); + QCOMPARE(newItem->property("width").toInt(), 200); + QVERIFY(QQuickDesignerSupportProperties::hasBindingForProperty(newItem, + view->engine()->contextForObject(newItem), + "width", + 0)); + + //Check if reseting property does work after setting binding + QQuickDesignerSupportProperties::doResetProperty(newItem, view->rootContext(), "width"); + QCOMPARE(newItem->property("width").toInt(), 0); + + //No custom data available for the rootItem, because not registered by QQuickDesignerSupportProperties::registerCustomData + QVERIFY(!QQuickDesignerSupportProperties::getResetValue(rootItem, "width").isValid()); + + newItemScopedPointer.reset(); //Delete the item and check if item gets removed from the hash and an invalid QVariant is returned. + + QVERIFY(!QQuickDesignerSupportProperties::getResetValue(newItem, "width").isValid()); +} + +void tst_qquickdesignersupport::customDataBindings() +{ + QScopedPointer<QQuickView> view(new QQuickView); + view->engine()->setOutputWarningsToStandardError(false); + view->setSource(testFileUrl("test.qml")); + + QVERIFY(view->errors().isEmpty()); + + QQuickItem *rootItem = view->rootObject(); + + QVERIFY(rootItem); + + QQuickItem *testComponent = findItem<QQuickItem>(view->rootObject(), QLatin1String("testComponent")); + + QVERIFY(testComponent); + QQuickDesignerSupportProperties::registerCustomData(testComponent); + QQuickDesignerSupportProperties::hasValidResetBinding(testComponent, "x"); + QVERIFY(QQuickDesignerSupportProperties::hasBindingForProperty(testComponent, + view->engine()->contextForObject(testComponent), + "x", + 0)); + + QCOMPARE(testComponent->property("x").toInt(), 200); + + + //Set property to 100 and ovveride the default binding + QQmlProperty property(testComponent, "x", view->engine()->contextForObject(testComponent)); + QVERIFY(property.write(100)); + QCOMPARE(testComponent->property("x").toInt(), 100); + + QVERIFY(!QQuickDesignerSupportProperties::hasBindingForProperty(testComponent, + view->engine()->contextForObject(testComponent), + "x", + 0)); + + //Reset the binding to the default + QQuickDesignerSupportProperties::doResetProperty(testComponent, + view->engine()->contextForObject(testComponent), + "x"); + + QVERIFY(QQuickDesignerSupportProperties::hasBindingForProperty(testComponent, + view->engine()->contextForObject(testComponent), + "x", + 0)); + QCOMPARE(testComponent->property("x").toInt(), 200); + + + + //Set a different binding/expression + QQuickDesignerSupportProperties::setPropertyBinding(testComponent, + view->engine()->contextForObject(testComponent), + "x", + QLatin1String("Math.max(0, 300)")); + + QVERIFY(QQuickDesignerSupportProperties::hasBindingForProperty(testComponent, + view->engine()->contextForObject(testComponent), + "x", + 0)); + + QCOMPARE(testComponent->property("x").toInt(), 300); + + + + //Reset the binding to the default + QQuickDesignerSupportProperties::doResetProperty(testComponent, + view->engine()->contextForObject(testComponent), + "x"); + + + QVERIFY(QQuickDesignerSupportProperties::hasBindingForProperty(testComponent, + view->engine()->contextForObject(testComponent), + "x", + 0)); + QCOMPARE(testComponent->property("x").toInt(), 200); +} + +void tst_qquickdesignersupport::objectProperties() +{ + QScopedPointer<QQuickView> view(new QQuickView); + view->engine()->setOutputWarningsToStandardError(false); + view->setSource(testFileUrl("test.qml")); + + QVERIFY(view->errors().isEmpty()); + + QQuickItem *rootItem = view->rootObject(); + + QVERIFY(rootItem); + + QQuickItem *rectangleItem = findItem<QQuickItem>(view->rootObject(), QLatin1String("rectangleItem")); + QVERIFY(rectangleItem); + + + //Read gradient property as QObject + int propertyIndex = rectangleItem->metaObject()->indexOfProperty("gradient"); + QVERIFY(propertyIndex > 0); + QMetaProperty metaProperty = rectangleItem->metaObject()->property(propertyIndex); + QVERIFY(metaProperty.isValid()); + + QVERIFY(QQuickDesignerSupportProperties::isPropertyQObject(metaProperty)); + + QObject*gradient = QQuickDesignerSupportProperties::readQObjectProperty(metaProperty, rectangleItem); + QVERIFY(gradient); + + + //The width property is not a QObject + propertyIndex = rectangleItem->metaObject()->indexOfProperty("width"); + QVERIFY(propertyIndex > 0); + metaProperty = rectangleItem->metaObject()->property(propertyIndex); + QVERIFY(metaProperty.isValid()); + QVERIFY(!QQuickDesignerSupportProperties::isPropertyQObject(metaProperty)); +} + +void tst_qquickdesignersupport::dynamicProperty() +{ + QScopedPointer<QQuickView> view(new QQuickView); + view->engine()->setOutputWarningsToStandardError(false); + view->setSource(testFileUrl("test.qml")); + + QVERIFY(view->errors().isEmpty()); + + QQuickItem *rootItem = view->rootObject(); + + QVERIFY(rootItem); + + QQuickItem *simpleItem = findItem<QQuickItem>(view->rootObject(), QLatin1String("simpleItem")); + + QVERIFY(simpleItem); + + QQuickDesignerSupportProperties::registerNodeInstanceMetaObject(simpleItem, view->engine()); + QQuickDesignerSupportProperties::getPropertyCache(simpleItem, view->engine()); + + QQuickDesignerSupportProperties::createNewDynamicProperty(simpleItem, view->engine(), QLatin1String("dynamicProperty")); + + QQmlProperty property(simpleItem, "dynamicProperty", view->engine()->contextForObject(simpleItem)); + QVERIFY(property.isValid()); + QVERIFY(property.write(QLatin1String("test"))); + + + QCOMPARE(property.read().toString(), QLatin1String("test")); + + //Force evalutation of all bindings + QQuickDesignerSupport::refreshExpressions(view->rootContext()); + + //Check if expression to dynamic property gets properly resolved + property = QQmlProperty(simpleItem, "testProperty", view->engine()->contextForObject(simpleItem)); + QVERIFY(property.isValid()); + QCOMPARE(property.read().toString(), QLatin1String("test")); +} + +void tst_qquickdesignersupport::createComponent() +{ + QScopedPointer<QQuickView> view(new QQuickView); + view->engine()->setOutputWarningsToStandardError(false); + view->setSource(testFileUrl("test.qml")); + + QVERIFY(view->errors().isEmpty()); + + QQuickItem *rootItem = view->rootObject(); + + QVERIFY(rootItem); + + QObject *testComponentObject = QQuickDesignerSupportItems::createComponent(testFileUrl("TestComponent.qml"), view->rootContext()); + QVERIFY(testComponentObject); + + QVERIFY(QQuickDesignerSupportMetaInfo::isSubclassOf(testComponentObject, "QtQuick/Item")); +} + +void tst_qquickdesignersupport::basicStates() +{ + QScopedPointer<QQuickView> view(new QQuickView); + view->engine()->setOutputWarningsToStandardError(false); + view->setSource(testFileUrl("test.qml")); + + QVERIFY(view->errors().isEmpty()); + + QQuickItem *rootItem = view->rootObject(); + + QVERIFY(rootItem); + + QQuickStateGroup *stateGroup = QQuickItemPrivate::get(rootItem)->_states(); + + QVERIFY(stateGroup); + + QCOMPARE(stateGroup->states().count(), 2 ); + + QQuickState *state01 = stateGroup->states().first(); + QQuickState *state02 = stateGroup->states().last(); + + QVERIFY(state01); + QVERIFY(state02); + + QCOMPARE(state01->property("name").toString(), QLatin1String("state01")); + QCOMPARE(state02->property("name").toString(), QLatin1String("state02")); + + QVERIFY(!QQuickDesignerSupportStates::isStateActive(state01, view->rootContext())); + QVERIFY(!QQuickDesignerSupportStates::isStateActive(state01, view->rootContext())); + + QQuickDesignerSupportStates::activateState(state01, view->rootContext()); + QVERIFY(QQuickDesignerSupportStates::isStateActive(state01, view->rootContext())); + + QQuickDesignerSupportStates::activateState(state02, view->rootContext()); + QVERIFY(QQuickDesignerSupportStates::isStateActive(state02, view->rootContext())); + QVERIFY(!QQuickDesignerSupportStates::isStateActive(state01, view->rootContext())); + + QQuickDesignerSupportStates::deactivateState(state02); + QVERIFY(!QQuickDesignerSupportStates::isStateActive(state01, view->rootContext())); + QVERIFY(!QQuickDesignerSupportStates::isStateActive(state01, view->rootContext())); +} + +void tst_qquickdesignersupport::statesPropertyChanges() +{ + QScopedPointer<QQuickView> view(new QQuickView); + view->engine()->setOutputWarningsToStandardError(false); + view->setSource(testFileUrl("test.qml")); + + QVERIFY(view->errors().isEmpty()); + + QQuickItem *rootItem = view->rootObject(); + + QVERIFY(rootItem); + + QQuickItem *simpleItem = findItem<QQuickItem>(view->rootObject(), QLatin1String("simpleItem")); + + QVERIFY(simpleItem); + + QQuickStateGroup *stateGroup = QQuickItemPrivate::get(rootItem)->_states(); + + QVERIFY(stateGroup); + + QCOMPARE(stateGroup->states().count(), 2 ); + + QQuickState *state01 = stateGroup->states().first(); + QQuickState *state02 = stateGroup->states().last(); + + QVERIFY(state01); + QVERIFY(state02); + + QCOMPARE(state01->property("name").toString(), QLatin1String("state01")); + QCOMPARE(state02->property("name").toString(), QLatin1String("state02")); + + //PropertyChanges are parsed lazily + QQuickDesignerSupportStates::activateState(state01, view->rootContext()); + QQuickDesignerSupportStates::deactivateState(state01); + + QQuickStatePrivate *statePrivate01 = static_cast<QQuickStatePrivate *>(QQuickStatePrivate::get(state01)); + + QCOMPARE(state01->operationCount(), 1); + + QCOMPARE(statePrivate01->operations.count(), 1); + + QQuickStateOperation *propertyChange = statePrivate01->operations.at(0).data(); + + QCOMPARE(QQuickDesignerSupportPropertyChanges::stateObject(propertyChange), state01); + + QQuickDesignerSupportPropertyChanges::changeValue(propertyChange, "width", 300); + + QCOMPARE(simpleItem->property("width").toInt(), 0); + QQuickDesignerSupportStates::activateState(state01, view->rootContext()); + QCOMPARE(simpleItem->property("width").toInt(), 300); + QQuickDesignerSupportStates::deactivateState(state01); + QCOMPARE(simpleItem->property("width").toInt(), 0); + + //Set "base state value" in state1 using the revert list + QQuickDesignerSupportStates::activateState(state01, view->rootContext()); + QQuickDesignerSupportStates::changeValueInRevertList(state01, simpleItem, "width", 200); + QCOMPARE(simpleItem->property("width").toInt(), 300); + QQuickDesignerSupportStates::deactivateState(state01); + QCOMPARE(simpleItem->property("width").toInt(), 200); + + + //Create new PropertyChanges + QQuickPropertyChanges *newPropertyChange = new QQuickPropertyChanges(); + newPropertyChange->setParent(state01); + QQmlListProperty<QQuickStateOperation> changes = state01->changes(); + QQuickStatePrivate::operations_append(&changes, newPropertyChange); + + newPropertyChange->setObject(rootItem); + + QQuickDesignerSupportPropertyChanges::attachToState(newPropertyChange); + + QCOMPARE(rootItem, QQuickDesignerSupportPropertyChanges::targetObject(newPropertyChange)); + + QCOMPARE(state01->operationCount(), 2); + QCOMPARE(statePrivate01->operations.count(), 2); + + QCOMPARE(QQuickDesignerSupportPropertyChanges::stateObject(newPropertyChange), state01); + + //Set color for rootItem in state1 + QQuickDesignerSupportPropertyChanges::changeValue(newPropertyChange, "color", QColor(Qt::red)); + + QQuickDesignerSupportStates::activateState(state01, view->rootContext()); + QCOMPARE(rootItem->property("color").value<QColor>(), QColor(Qt::red)); + QQuickDesignerSupportStates::deactivateState(state01); + QCOMPARE(rootItem->property("color").value<QColor>(), QColor(Qt::white)); + + QQuickDesignerSupportPropertyChanges::removeProperty(newPropertyChange, "color"); + QQuickDesignerSupportStates::activateState(state01, view->rootContext()); + QCOMPARE(rootItem->property("color").value<QColor>(), QColor(Qt::white)); + +} + +static QObject * s_object = 0; +static QQuickDesignerSupport::PropertyName s_propertyName; + +static void notifyPropertyChangeCallBackFunction(QObject *object, const QQuickDesignerSupport::PropertyName &propertyName) +{ + s_object = object; + s_propertyName = propertyName; +} + +static void (*notifyPropertyChangeCallBackPointer)(QObject *, const QQuickDesignerSupport::PropertyName &) = ¬ifyPropertyChangeCallBackFunction; + + +void tst_qquickdesignersupport::testNotifyPropertyChangeCallBack() +{ + QScopedPointer<QQuickView> view(new QQuickView); + view->engine()->setOutputWarningsToStandardError(false); + view->setSource(testFileUrl("test.qml")); + + QVERIFY(view->errors().isEmpty()); + + QQuickItem *rootItem = view->rootObject(); + + QVERIFY(rootItem); + + QQuickRectangle *rectangle = static_cast<QQuickRectangle *>(rootItem); + QVERIFY(rectangle); + + QQuickDesignerSupportProperties::registerNodeInstanceMetaObject(rectangle, view->engine()); + + QQuickGradient *gradient = new QQuickGradient(rectangle); + + QQuickDesignerSupportMetaInfo::registerNotifyPropertyChangeCallBack(notifyPropertyChangeCallBackPointer); + + rectangle->setProperty("gradient", QVariant::fromValue<QQuickGradient *>(gradient)); + + QVERIFY(s_object); + QCOMPARE(s_object, rootItem); + QCOMPARE(s_propertyName, QQuickDesignerSupport::PropertyName("gradient")); +} + +static void fixResourcePathsForObjectCallBackFunction(QObject *object) +{ + s_object = object; +} + +static void (*fixResourcePathsForObjectCallBackPointer)(QObject *) = &fixResourcePathsForObjectCallBackFunction; + +void tst_qquickdesignersupport::testFixResourcePathsForObjectCallBack() +{ + QScopedPointer<QQuickView> view(new QQuickView); + view->engine()->setOutputWarningsToStandardError(false); + view->setSource(testFileUrl("test.qml")); + + QVERIFY(view->errors().isEmpty()); + + QQuickItem *rootItem = view->rootObject(); + + QVERIFY(rootItem); + + s_object = 0; + + QQuickDesignerSupportItems::registerFixResourcePathsForObjectCallBack(fixResourcePathsForObjectCallBackPointer); + + QQuickItem *simpleItem = findItem<QQuickItem>(view->rootObject(), QLatin1String("simpleItem")); + + QVERIFY(simpleItem); + + QQuickDesignerSupportItems::tweakObjects(simpleItem); + + //Check that the fixResourcePathsForObjectCallBack was called on simpleItem + QCOMPARE(simpleItem , s_object); +} + + +QTEST_MAIN(tst_qquickdesignersupport) + +#include "tst_qquickdesignersupport.moc" diff --git a/tests/auto/quick/qquickdynamicpropertyanimation/tst_qquickdynamicpropertyanimation.cpp b/tests/auto/quick/qquickdynamicpropertyanimation/tst_qquickdynamicpropertyanimation.cpp index 40bd6624f0..3656bb8aab 100644 --- a/tests/auto/quick/qquickdynamicpropertyanimation/tst_qquickdynamicpropertyanimation.cpp +++ b/tests/auto/quick/qquickdynamicpropertyanimation/tst_qquickdynamicpropertyanimation.cpp @@ -59,11 +59,11 @@ private: QQmlProperty testProp(item, propertyName); QPropertyAnimation animation(item, propertyName, this); animation.setEndValue(toValue); - QVERIFY(animation.targetObject() == item); - QVERIFY(animation.propertyName() == propertyName); - QVERIFY(animation.endValue().value<T>() == toValue); + QCOMPARE(animation.targetObject(), item); + QCOMPARE(animation.propertyName(), propertyName); + QCOMPARE(animation.endValue().value<T>(), toValue); animation.start(); - QVERIFY(animation.state() == QAbstractAnimation::Running); + QCOMPARE(animation.state(), QAbstractAnimation::Running); QTest::qWait(animation.duration()); QTRY_COMPARE(testProp.read().value<T>(), toValue); } diff --git a/tests/auto/quick/qquickflickable/BLACKLIST b/tests/auto/quick/qquickflickable/BLACKLIST index 92ed8708de..647bf819a5 100644 --- a/tests/auto/quick/qquickflickable/BLACKLIST +++ b/tests/auto/quick/qquickflickable/BLACKLIST @@ -10,7 +10,7 @@ osx-10.10 osx-10.10 [stopAtBounds] osx-10.10 -windows 32bit developer-build +windows developer-build [returnToBounds] osx [pressWhileFlicking] diff --git a/tests/auto/quick/qquickflickable/data/movementSignals.qml b/tests/auto/quick/qquickflickable/data/movementSignals.qml new file mode 100644 index 0000000000..581e882139 --- /dev/null +++ b/tests/auto/quick/qquickflickable/data/movementSignals.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 + +Flickable { + width: 400; height: 400 + contentWidth: 400; contentHeight: 1200 + + property string signalString + + Rectangle { + width: 400; height: 400 + color: "red" + } + Rectangle { + y: 400; width: 400; height: 400 + color: "yellow" + } + Rectangle { + y: 800; width: 400; height: 400 + color: "green" + } + + onMovementStarted: signalString += "ms" + onMovementEnded: signalString += "me" + onFlickStarted: signalString += "fs" + onFlickEnded: signalString += "fe" +} diff --git a/tests/auto/quick/qquickflickable/data/nestedPressDelay.qml b/tests/auto/quick/qquickflickable/data/nestedPressDelay.qml index 742656641f..bdb866ce65 100644 --- a/tests/auto/quick/qquickflickable/data/nestedPressDelay.qml +++ b/tests/auto/quick/qquickflickable/data/nestedPressDelay.qml @@ -8,12 +8,18 @@ Flickable { contentHeight: 320 flickableDirection: Flickable.HorizontalFlick pressDelay: 10000 - Rectangle { + MouseArea { + objectName: "filteringMouseArea" x: 20 y: 20 width: 400 height: 300 - color: "yellow" + drag.filterChildren: true + Rectangle { + id: rectangle + color: "yellow" + anchors.fill: parent + } Flickable { objectName: "innerFlickable" anchors.fill: parent diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index 7d08c3c81e..dc7171746c 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -67,6 +67,7 @@ private slots: void flickDeceleration(); void pressDelay(); void nestedPressDelay(); + void filterReplayedPress(); void nestedClickThenFlick(); void flickableDirection(); void resizeContent(); @@ -91,7 +92,9 @@ private slots: void stopAtBounds_data(); void nestedMouseAreaUsingTouch(); void pressDelayWithLoader(); + void movementFromProgrammaticFlick(); void cleanup(); + void contentSize(); private: void flickWithTouch(QQuickWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to); @@ -195,9 +198,9 @@ void tst_qquickflickable::properties() QCOMPARE(obj->pressDelay(), 200); QCOMPARE(obj->maximumFlickVelocity(), 2000.); - QVERIFY(obj->property("ok").toBool() == false); + QVERIFY(!obj->property("ok").toBool()); QMetaObject::invokeMethod(obj, "check"); - QVERIFY(obj->property("ok").toBool() == true); + QVERIFY(obj->property("ok").toBool()); delete obj; } @@ -211,28 +214,28 @@ void tst_qquickflickable::boundsBehavior() QSignalSpy spy(flickable, SIGNAL(boundsBehaviorChanged())); QVERIFY(flickable); - QVERIFY(flickable->boundsBehavior() == QQuickFlickable::StopAtBounds); + QCOMPARE(flickable->boundsBehavior(), QQuickFlickable::StopAtBounds); flickable->setBoundsBehavior(QQuickFlickable::DragAndOvershootBounds); - QVERIFY(flickable->boundsBehavior() == QQuickFlickable::DragAndOvershootBounds); + QCOMPARE(flickable->boundsBehavior(), QQuickFlickable::DragAndOvershootBounds); QCOMPARE(spy.count(),1); flickable->setBoundsBehavior(QQuickFlickable::DragAndOvershootBounds); QCOMPARE(spy.count(),1); flickable->setBoundsBehavior(QQuickFlickable::DragOverBounds); - QVERIFY(flickable->boundsBehavior() == QQuickFlickable::DragOverBounds); + QCOMPARE(flickable->boundsBehavior(), QQuickFlickable::DragOverBounds); QCOMPARE(spy.count(),2); flickable->setBoundsBehavior(QQuickFlickable::DragOverBounds); QCOMPARE(spy.count(),2); flickable->setBoundsBehavior(QQuickFlickable::StopAtBounds); - QVERIFY(flickable->boundsBehavior() == QQuickFlickable::StopAtBounds); + QCOMPARE(flickable->boundsBehavior(), QQuickFlickable::StopAtBounds); QCOMPARE(spy.count(),3); flickable->setBoundsBehavior(QQuickFlickable::StopAtBounds); QCOMPARE(spy.count(),3); flickable->setBoundsBehavior(QQuickFlickable::OvershootBounds); - QVERIFY(flickable->boundsBehavior() == QQuickFlickable::OvershootBounds); + QCOMPARE(flickable->boundsBehavior(), QQuickFlickable::OvershootBounds); QCOMPARE(spy.count(),4); flickable->setBoundsBehavior(QQuickFlickable::OvershootBounds); QCOMPARE(spy.count(),4); @@ -249,7 +252,7 @@ void tst_qquickflickable::rebound() QQuickViewTestUtil::moveMouseAway(window.data()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != 0); QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); @@ -295,11 +298,11 @@ void tst_qquickflickable::rebound() // flick and trigger the transition multiple times // (moving signals are emitted as soon as the first transition starts) - flick(window.data(), QPoint(20,20), QPoint(120,120), 200); // both x and y will bounce back - flick(window.data(), QPoint(20,120), QPoint(120,20), 200); // only x will bounce back + flick(window.data(), QPoint(20,20), QPoint(120,120), 50); // both x and y will bounce back + flick(window.data(), QPoint(20,120), QPoint(120,20), 50); // only x will bounce back QVERIFY(flickable->isMoving()); - QVERIFY(window->rootObject()->property("transitionsStarted").toInt() >= 1); + QTRY_VERIFY(window->rootObject()->property("transitionsStarted").toInt() >= 1); QCOMPARE(hMoveSpy.count(), 1); QCOMPARE(vMoveSpy.count(), 1); QCOMPARE(movementStartedSpy.count(), 1); @@ -388,7 +391,7 @@ void tst_qquickflickable::pressDelay() QQuickViewTestUtil::centerOnScreen(window.data()); QQuickViewTestUtil::moveMouseAway(window.data()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != 0); QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); @@ -406,13 +409,13 @@ void tst_qquickflickable::pressDelay() QQuickItem *mouseArea = window->rootObject()->findChild<QQuickItem*>("mouseArea"); QSignalSpy clickedSpy(mouseArea, SIGNAL(clicked(QQuickMouseEvent*))); - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(150, 150)); + moveAndPress(window.data(), QPoint(150, 150)); // The press should not occur immediately - QVERIFY(mouseArea->property("pressed").toBool() == false); + QVERIFY(!mouseArea->property("pressed").toBool()); // But, it should occur eventually - QTRY_VERIFY(mouseArea->property("pressed").toBool() == true); + QTRY_VERIFY(mouseArea->property("pressed").toBool()); QCOMPARE(clickedSpy.count(),0); @@ -427,10 +430,10 @@ void tst_qquickflickable::pressDelay() // Test a quick tap within the pressDelay timeout clickedSpy.clear(); - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(180, 180)); + moveAndPress(window.data(), QPoint(180, 180)); // The press should not occur immediately - QVERIFY(mouseArea->property("pressed").toBool() == false); + QVERIFY(!mouseArea->property("pressed").toBool()); QCOMPARE(clickedSpy.count(),0); @@ -444,16 +447,16 @@ void tst_qquickflickable::pressDelay() // QTBUG-31168 - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(150, 110)); + moveAndPress(window.data(), QPoint(150, 110)); // The press should not occur immediately - QVERIFY(mouseArea->property("pressed").toBool() == false); + QVERIFY(!mouseArea->property("pressed").toBool()); QTest::mouseMove(window.data(), QPoint(150, 190)); // As we moved pass the drag threshold, we should never receive the press - QVERIFY(mouseArea->property("pressed").toBool() == false); - QTRY_VERIFY(mouseArea->property("pressed").toBool() == false); + QVERIFY(!mouseArea->property("pressed").toBool()); + QTRY_VERIFY(!mouseArea->property("pressed").toBool()); // On release the clicked signal should *not* be emitted QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(150, 190)); @@ -469,7 +472,7 @@ void tst_qquickflickable::nestedPressDelay() QQuickViewTestUtil::centerOnScreen(window.data()); QQuickViewTestUtil::moveMouseAway(window.data()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != 0); QQuickFlickable *outer = qobject_cast<QQuickFlickable*>(window->rootObject()); @@ -478,48 +481,90 @@ void tst_qquickflickable::nestedPressDelay() QQuickFlickable *inner = window->rootObject()->findChild<QQuickFlickable*>("innerFlickable"); QVERIFY(inner != 0); - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(150, 150)); + moveAndPress(window.data(), QPoint(150, 150)); // the MouseArea is not pressed immediately - QVERIFY(outer->property("pressed").toBool() == false); - QVERIFY(inner->property("pressed").toBool() == false); + QVERIFY(!outer->property("pressed").toBool()); + QVERIFY(!inner->property("pressed").toBool()); // The inner pressDelay will prevail (50ms, vs. 10sec) // QTRY_VERIFY() has 5sec timeout, so will timeout well within 10sec. - QTRY_VERIFY(outer->property("pressed").toBool() == true); + QTRY_VERIFY(outer->property("pressed").toBool()); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(150, 150)); // Dragging inner Flickable should work - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(80, 150)); + moveAndPress(window.data(), QPoint(80, 150)); // the MouseArea is not pressed immediately - QVERIFY(outer->property("pressed").toBool() == false); - QVERIFY(inner->property("pressed").toBool() == false); + QVERIFY(!outer->property("pressed").toBool()); + QVERIFY(!inner->property("pressed").toBool()); QTest::mouseMove(window.data(), QPoint(60, 150)); QTest::mouseMove(window.data(), QPoint(40, 150)); QTest::mouseMove(window.data(), QPoint(20, 150)); - QVERIFY(inner->property("moving").toBool() == true); - QVERIFY(outer->property("moving").toBool() == false); + QVERIFY(inner->property("moving").toBool()); + QVERIFY(!outer->property("moving").toBool()); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(20, 150)); // Dragging the MouseArea in the inner Flickable should move the inner Flickable - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(150, 150)); + moveAndPress(window.data(), QPoint(150, 150)); // the MouseArea is not pressed immediately - QVERIFY(outer->property("pressed").toBool() == false); + QVERIFY(!outer->property("pressed").toBool()); QTest::mouseMove(window.data(), QPoint(130, 150)); QTest::mouseMove(window.data(), QPoint(110, 150)); QTest::mouseMove(window.data(), QPoint(90, 150)); - QVERIFY(outer->property("moving").toBool() == false); - QVERIFY(inner->property("moving").toBool() == true); + QVERIFY(!outer->property("moving").toBool()); + QVERIFY(inner->property("moving").toBool()); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(90, 150)); } +void tst_qquickflickable::filterReplayedPress() +{ + QScopedPointer<QQuickView> window(new QQuickView); + window->setSource(testFileUrl("nestedPressDelay.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + QQuickViewTestUtil::centerOnScreen(window.data()); + QQuickViewTestUtil::moveMouseAway(window.data()); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + QVERIFY(window->rootObject() != 0); + + QQuickFlickable *outer = qobject_cast<QQuickFlickable*>(window->rootObject()); + QVERIFY(outer != 0); + + QQuickFlickable *inner = window->rootObject()->findChild<QQuickFlickable*>("innerFlickable"); + QVERIFY(inner != 0); + + QQuickItem *filteringMouseArea = outer->findChild<QQuickItem *>("filteringMouseArea"); + QVERIFY(filteringMouseArea); + + moveAndPress(window.data(), QPoint(150, 150)); + // the MouseArea filtering the Flickable is pressed immediately. + QCOMPARE(filteringMouseArea->property("pressed").toBool(), true); + + // Some event causes the mouse area to set keepMouseGrab. + filteringMouseArea->setKeepMouseGrab(true); + QCOMPARE(filteringMouseArea->keepMouseGrab(), true); + + // The inner pressDelay will prevail (50ms, vs. 10sec) + // QTRY_VERIFY() has 5sec timeout, so will timeout well within 10sec. + QTRY_VERIFY(outer->property("pressed").toBool()); + + // The replayed press event isn't delivered to parent items of the + // flickable with the press delay, and the state of the parent mouse + // area is therefore unaffected. + QCOMPARE(filteringMouseArea->property("pressed").toBool(), true); + QCOMPARE(filteringMouseArea->keepMouseGrab(), true); + + QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(150, 150)); +} + + // QTBUG-37316 void tst_qquickflickable::nestedClickThenFlick() { @@ -529,7 +574,7 @@ void tst_qquickflickable::nestedClickThenFlick() QQuickViewTestUtil::centerOnScreen(window.data()); QQuickViewTestUtil::moveMouseAway(window.data()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != 0); QQuickFlickable *outer = qobject_cast<QQuickFlickable*>(window->rootObject()); @@ -538,29 +583,29 @@ void tst_qquickflickable::nestedClickThenFlick() QQuickFlickable *inner = window->rootObject()->findChild<QQuickFlickable*>("innerFlickable"); QVERIFY(inner != 0); - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(150, 150)); + moveAndPress(window.data(), QPoint(150, 150)); // the MouseArea is not pressed immediately - QVERIFY(outer->property("pressed").toBool() == false); - QTRY_VERIFY(outer->property("pressed").toBool() == true); + QVERIFY(!outer->property("pressed").toBool()); + QTRY_VERIFY(outer->property("pressed").toBool()); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(150, 150)); - QVERIFY(outer->property("pressed").toBool() == false); + QVERIFY(!outer->property("pressed").toBool()); // Dragging inner Flickable should work - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(80, 150)); + moveAndPress(window.data(), QPoint(80, 150)); // the MouseArea is not pressed immediately - QVERIFY(outer->property("pressed").toBool() == false); + QVERIFY(!outer->property("pressed").toBool()); QTest::mouseMove(window.data(), QPoint(80, 148)); QTest::mouseMove(window.data(), QPoint(80, 140)); QTest::mouseMove(window.data(), QPoint(80, 120)); QTest::mouseMove(window.data(), QPoint(80, 100)); - QVERIFY(outer->property("moving").toBool() == false); - QVERIFY(inner->property("moving").toBool() == true); + QVERIFY(!outer->property("moving").toBool()); + QVERIFY(inner->property("moving").toBool()); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(80, 100)); } @@ -628,6 +673,8 @@ void tst_qquickflickable::returnToBounds() window->rootContext()->setContextProperty("setRebound", setRebound); window->setSource(testFileUrl("resize.qml")); + window->show(); + QTest::qWaitForWindowActive(window.data()); QVERIFY(window->rootObject() != 0); QQuickFlickable *obj = findItem<QQuickFlickable>(window->rootObject(), "flick"); @@ -671,7 +718,7 @@ void tst_qquickflickable::wheel() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("wheel.qml")); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != 0); QQuickFlickable *flick = window->rootObject()->findChild<QQuickFlickable*>("flick"); @@ -685,10 +732,10 @@ void tst_qquickflickable::wheel() } QTRY_VERIFY(flick->contentY() > 0); - QVERIFY(flick->contentX() == 0); + QCOMPARE(flick->contentX(), qreal(0)); flick->setContentY(0); - QVERIFY(flick->contentY() == 0); + QCOMPARE(flick->contentY(), qreal(0)); { QPoint pos(200, 200); @@ -699,7 +746,7 @@ void tst_qquickflickable::wheel() } QTRY_VERIFY(flick->contentX() > 0); - QVERIFY(flick->contentY() == 0); + QCOMPARE(flick->contentY(), qreal(0)); } void tst_qquickflickable::movingAndFlicking_data() @@ -740,7 +787,7 @@ void tst_qquickflickable::movingAndFlicking() QQuickViewTestUtil::centerOnScreen(window.data()); QQuickViewTestUtil::moveMouseAway(window.data()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != 0); QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); @@ -903,7 +950,7 @@ void tst_qquickflickable::movingAndDragging() QQuickViewTestUtil::centerOnScreen(window.data()); QQuickViewTestUtil::moveMouseAway(window.data()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != 0); QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); @@ -922,7 +969,7 @@ void tst_qquickflickable::movingAndDragging() QSignalSpy moveEndSpy(flickable, SIGNAL(movementEnded())); // start the drag - QTest::mousePress(window.data(), Qt::LeftButton, 0, moveFrom); + moveAndPress(window.data(), moveFrom); QTest::mouseMove(window.data(), moveFrom + moveByWithoutSnapBack); QTest::mouseMove(window.data(), moveFrom + moveByWithoutSnapBack*2); QTest::mouseMove(window.data(), moveFrom + moveByWithoutSnapBack*3); @@ -962,7 +1009,7 @@ void tst_qquickflickable::movingAndDragging() // Don't test whether moving finished because a flick could occur // wait for any motion to end - QTRY_VERIFY(flickable->isMoving() == false); + QTRY_VERIFY(!flickable->isMoving()); QVERIFY(!flickable->isMovingHorizontally()); QVERIFY(!flickable->isMovingVertically()); @@ -998,7 +1045,7 @@ void tst_qquickflickable::movingAndDragging() flickable->setContentX(0); flickable->setContentY(0); QTRY_VERIFY(!flickable->isMoving()); - QTest::mousePress(window.data(), Qt::LeftButton, 0, moveFrom); + moveAndPress(window.data(), moveFrom); QTest::mouseMove(window.data(), moveFrom + moveByWithSnapBack); QTest::mouseMove(window.data(), moveFrom + moveByWithSnapBack*2); QTest::mouseMove(window.data(), moveFrom + moveByWithSnapBack*3); @@ -1072,7 +1119,7 @@ void tst_qquickflickable::flickOnRelease() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("flickable03.qml")); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != 0); QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); @@ -1085,14 +1132,14 @@ void tst_qquickflickable::flickOnRelease() // underlying drivers will hopefully provide a pre-calculated velocity // (based on more data than what the UI gets), thus making this use case // working even with small movements. - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(50, 300)); + moveAndPress(window.data(), QPoint(50, 300)); QTest::mouseMove(window.data(), QPoint(50, 10), 10); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(50, 10), 10); QCOMPARE(vFlickSpy.count(), 1); // wait for any motion to end - QTRY_VERIFY(flickable->isMoving() == false); + QTRY_VERIFY(!flickable->isMoving()); #ifdef Q_OS_MAC QEXPECT_FAIL("", "QTBUG-26094 stopping on a full pixel doesn't work on OS X", Continue); @@ -1109,7 +1156,7 @@ void tst_qquickflickable::pressWhileFlicking() QQuickViewTestUtil::centerOnScreen(window.data()); QQuickViewTestUtil::moveMouseAway(window.data()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != 0); QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); @@ -1159,27 +1206,27 @@ void tst_qquickflickable::disabled() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("disabled.qml")); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != 0); QQuickFlickable *flick = window->rootObject()->findChild<QQuickFlickable*>("flickable"); QVERIFY(flick != 0); - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(50, 90)); + moveAndPress(window.data(), QPoint(50, 90)); QTest::mouseMove(window.data(), QPoint(50, 80)); QTest::mouseMove(window.data(), QPoint(50, 70)); QTest::mouseMove(window.data(), QPoint(50, 60)); - QVERIFY(flick->isMoving() == false); + QVERIFY(!flick->isMoving()); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(50, 60)); // verify that mouse clicks on other elements still work (QTBUG-20584) - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(50, 10)); + moveAndPress(window.data(), QPoint(50, 10)); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(50, 10)); - QTRY_VERIFY(window->rootObject()->property("clicked").toBool() == true); + QTRY_VERIFY(window->rootObject()->property("clicked").toBool()); } void tst_qquickflickable::flickVelocity() @@ -1190,7 +1237,7 @@ void tst_qquickflickable::flickVelocity() QQuickViewTestUtil::centerOnScreen(window.data()); QQuickViewTestUtil::moveMouseAway(window.data()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != 0); QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); @@ -1199,12 +1246,12 @@ void tst_qquickflickable::flickVelocity() // flick up flick(window.data(), QPoint(20,190), QPoint(20, 50), 200); QVERIFY(flickable->verticalVelocity() > 0.0); - QTRY_VERIFY(flickable->verticalVelocity() == 0.0); + QTRY_COMPARE(flickable->verticalVelocity(), 0.0); // flick down flick(window.data(), QPoint(20,10), QPoint(20, 140), 200); QTRY_VERIFY(flickable->verticalVelocity() < 0.0); - QTRY_VERIFY(flickable->verticalVelocity() == 0.0); + QTRY_COMPARE(flickable->verticalVelocity(), 0.0); #ifdef Q_OS_MAC QSKIP("boost doesn't work on OS X"); @@ -1223,7 +1270,7 @@ void tst_qquickflickable::flickVelocity() // Flick in opposite direction -> boost cancelled. flick(window.data(), QPoint(20,10), QPoint(20, 340), 200); QTRY_VERIFY(flickable->verticalVelocity() < 0.0); - QVERIFY(fp->flickBoost == 1.0); + QCOMPARE(fp->flickBoost, 1.0); } void tst_qquickflickable::margins() @@ -1235,7 +1282,7 @@ void tst_qquickflickable::margins() QQuickViewTestUtil::moveMouseAway(window.data()); window->setTitle(QTest::currentTestFunction()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(QTest::qWaitForWindowActive(window.data())); QQuickItem *root = window->rootObject(); QVERIFY(root); QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(root); @@ -1298,13 +1345,13 @@ void tst_qquickflickable::cancelOnMouseGrab() QQuickViewTestUtil::centerOnScreen(window.data()); QQuickViewTestUtil::moveMouseAway(window.data()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != 0); QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); QVERIFY(flickable != 0); - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(10, 10)); + moveAndPress(window.data(), QPoint(10, 10)); // drag out of bounds QTest::mouseMove(window.data(), QPoint(50, 50)); QTest::mouseMove(window.data(), QPoint(100, 100)); @@ -1324,7 +1371,7 @@ void tst_qquickflickable::cancelOnMouseGrab() QTRY_VERIFY(!flickable->isMoving()); QTRY_VERIFY(!flickable->isDragging()); - QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(50, 10)); + moveAndRelease(window.data(), QPoint(50, 10)); } @@ -1336,41 +1383,41 @@ void tst_qquickflickable::clickAndDragWhenTransformed() QQuickViewTestUtil::centerOnScreen(view.data()); QQuickViewTestUtil::moveMouseAway(view.data()); view->show(); - QVERIFY(QTest::qWaitForWindowExposed(view.data())); + QVERIFY(QTest::qWaitForWindowActive(view.data())); QVERIFY(view->rootObject() != 0); QQuickFlickable *flickable = view->rootObject()->findChild<QQuickFlickable*>("flickable"); QVERIFY(flickable != 0); // click outside child rect - QTest::mousePress(view.data(), Qt::LeftButton, 0, QPoint(190, 190)); + moveAndPress(view.data(), QPoint(190, 190)); QTRY_COMPARE(flickable->property("itemPressed").toBool(), false); QTest::mouseRelease(view.data(), Qt::LeftButton, 0, QPoint(190, 190)); // click inside child rect - QTest::mousePress(view.data(), Qt::LeftButton, 0, QPoint(200, 200)); + moveAndPress(view.data(), QPoint(200, 200)); QTRY_COMPARE(flickable->property("itemPressed").toBool(), true); QTest::mouseRelease(view.data(), Qt::LeftButton, 0, QPoint(200, 200)); const int threshold = qApp->styleHints()->startDragDistance(); // drag outside bounds - QTest::mousePress(view.data(), Qt::LeftButton, 0, QPoint(160, 160)); + moveAndPress(view.data(), QPoint(160, 160)); QTest::qWait(10); QTest::mouseMove(view.data(), QPoint(160 + threshold * 2, 160)); QTest::mouseMove(view.data(), QPoint(160 + threshold * 3, 160)); QCOMPARE(flickable->isDragging(), false); QCOMPARE(flickable->property("itemPressed").toBool(), false); - QTest::mouseRelease(view.data(), Qt::LeftButton, 0, QPoint(180, 160)); + moveAndRelease(view.data(), QPoint(180, 160)); // drag inside bounds - QTest::mousePress(view.data(), Qt::LeftButton, 0, QPoint(200, 140)); + moveAndPress(view.data(), QPoint(200, 140)); QTest::qWait(10); QTest::mouseMove(view.data(), QPoint(200 + threshold * 2, 140)); QTest::mouseMove(view.data(), QPoint(200 + threshold * 3, 140)); QCOMPARE(flickable->isDragging(), true); QCOMPARE(flickable->property("itemPressed").toBool(), false); - QTest::mouseRelease(view.data(), Qt::LeftButton, 0, QPoint(220, 140)); + moveAndRelease(view.data(), QPoint(220, 140)); } void tst_qquickflickable::flickTwiceUsingTouches() @@ -1459,7 +1506,7 @@ void tst_qquickflickable::nestedStopAtBounds() QQuickViewTestUtil::moveMouseAway(&view); view.show(); view.requestActivate(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(QTest::qWaitForWindowActive(&view)); QVERIFY(view.rootObject()); QQuickFlickable *outer = qobject_cast<QQuickFlickable*>(view.rootObject()); @@ -1489,7 +1536,7 @@ void tst_qquickflickable::nestedStopAtBounds() int &axis = transpose ? position.ry() : position.rx(); // drag toward the aligned boundary. Outer flickable dragged. - QTest::mousePress(&view, Qt::LeftButton, 0, position); + moveAndPress(&view, position); QTest::qWait(10); axis += invert ? threshold * 2 : -threshold * 2; QTest::mouseMove(&view, position); @@ -1507,7 +1554,7 @@ void tst_qquickflickable::nestedStopAtBounds() outer->setContentY(50); // drag away from the aligned boundary. Inner flickable dragged. - QTest::mousePress(&view, Qt::LeftButton, 0, position); + moveAndPress(&view, position); QTest::qWait(10); axis += invert ? -threshold * 2 : threshold * 2; QTest::mouseMove(&view, position); @@ -1526,7 +1573,7 @@ void tst_qquickflickable::nestedStopAtBounds() inner->setContentHeight(inner->height() - margin); // Drag inner with equal size and contentSize - QTest::mousePress(&view, Qt::LeftButton, 0, position); + moveAndPress(&view, position); QTest::qWait(10); axis += invert ? -threshold * 2 : threshold * 2; QTest::mouseMove(&view, position); @@ -1543,7 +1590,7 @@ void tst_qquickflickable::nestedStopAtBounds() inner->setContentHeight(inner->height() - 100); // Drag inner with size greater than contentSize - QTest::mousePress(&view, Qt::LeftButton, 0, position); + moveAndPress(&view, position); QTest::qWait(10); axis += invert ? -threshold * 2 : threshold * 2; QTest::mouseMove(&view, position); @@ -1583,7 +1630,7 @@ void tst_qquickflickable::stopAtBounds() QQuickViewTestUtil::moveMouseAway(&view); view.show(); view.requestActivate(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(QTest::qWaitForWindowActive(&view)); QVERIFY(view.rootObject()); QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(view.rootObject()); @@ -1601,7 +1648,7 @@ void tst_qquickflickable::stopAtBounds() int &axis = transpose ? position.ry() : position.rx(); // drag away from the aligned boundary. View should not move - QTest::mousePress(&view, Qt::LeftButton, 0, position); + moveAndPress(&view, position); QTest::qWait(10); for (int i = 0; i < 3; ++i) { axis += invert ? -threshold : threshold; @@ -1649,12 +1696,14 @@ void tst_qquickflickable::stopAtBounds() } else { flickable->setContentX(invert ? 100 : 0); } + + QSignalSpy flickSignal(flickable, SIGNAL(flickingChanged())); if (invert) flick(&view, QPoint(20,20), QPoint(120,120), 100); else flick(&view, QPoint(120,120), QPoint(20,20), 100); - QVERIFY(flickable->isFlicking()); + QVERIFY(flickSignal.count() > 0); if (transpose) { if (invert) QTRY_COMPARE(flickable->isAtYBeginning(), true); @@ -1707,14 +1756,67 @@ void tst_qquickflickable::pressDelayWithLoader() QQuickViewTestUtil::centerOnScreen(window.data()); QQuickViewTestUtil::moveMouseAway(window.data()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != 0); // do not crash - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(150, 150)); + moveAndPress(window.data(), QPoint(150, 150)); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(150, 150)); } +// QTBUG-34507 +void tst_qquickflickable::movementFromProgrammaticFlick() +{ + QScopedPointer<QQuickView> window(new QQuickView); + window->setSource(testFileUrl("movementSignals.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + QQuickViewTestUtil::centerOnScreen(window.data()); + QQuickViewTestUtil::moveMouseAway(window.data()); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); + QVERIFY(flickable != 0); + + // verify that the signals for movement and flicking are called in the right order + flickable->flick(0, -1000); + QTRY_COMPARE(flickable->property("signalString").toString(), QString("msfsfeme")); +} + +// QTBUG_35038 +void tst_qquickflickable::contentSize() +{ + QQuickFlickable flickable; + QCOMPARE(flickable.contentWidth(), qreal(-1)); + QCOMPARE(flickable.contentHeight(), qreal(-1)); + + QSignalSpy cwspy(&flickable, SIGNAL(contentWidthChanged())); + QVERIFY(cwspy.isValid()); + + QSignalSpy chspy(&flickable, SIGNAL(contentHeightChanged())); + QVERIFY(chspy.isValid()); + + flickable.setWidth(100); + QCOMPARE(flickable.width(), qreal(100)); + QCOMPARE(flickable.contentWidth(), qreal(-1.0)); + QCOMPARE(cwspy.count(), 0); + + flickable.setContentWidth(10); + QCOMPARE(flickable.width(), qreal(100)); + QCOMPARE(flickable.contentWidth(), qreal(10)); + QCOMPARE(cwspy.count(), 1); + + flickable.setHeight(100); + QCOMPARE(flickable.height(), qreal(100)); + QCOMPARE(flickable.contentHeight(), qreal(-1.0)); + QCOMPARE(chspy.count(), 0); + + flickable.setContentHeight(10); + QCOMPARE(flickable.height(), qreal(100)); + QCOMPARE(flickable.contentHeight(), qreal(10)); + QCOMPARE(chspy.count(), 1); +} + QTEST_MAIN(tst_qquickflickable) #include "tst_qquickflickable.moc" diff --git a/tests/auto/quick/qquickflipable/tst_qquickflipable.cpp b/tests/auto/quick/qquickflipable/tst_qquickflipable.cpp index 76bf509cf0..2eb8942eee 100644 --- a/tests/auto/quick/qquickflipable/tst_qquickflipable.cpp +++ b/tests/auto/quick/qquickflipable/tst_qquickflipable.cpp @@ -108,11 +108,11 @@ void tst_qquickflipable::flipFlipable() QQmlComponent c(&engine, testFileUrl("flip-flipable.qml")); QQuickFlipable *obj = qobject_cast<QQuickFlipable*>(c.create()); QVERIFY(obj != 0); - QVERIFY(obj->side() == QQuickFlipable::Front); + QCOMPARE(obj->side(), QQuickFlipable::Front); obj->setProperty("flipped", QVariant(true)); - QTRY_VERIFY(obj->side() == QQuickFlipable::Back); - QTRY_VERIFY(obj->side() == QQuickFlipable::Front); - QTRY_VERIFY(obj->side() == QQuickFlipable::Back); + QTRY_COMPARE(obj->side(), QQuickFlipable::Back); + QTRY_COMPARE(obj->side(), QQuickFlipable::Front); + QTRY_COMPARE(obj->side(), QQuickFlipable::Back); delete obj; } diff --git a/tests/auto/quick/qquickfocusscope/tst_qquickfocusscope.cpp b/tests/auto/quick/qquickfocusscope/tst_qquickfocusscope.cpp index 98f85af92e..4b377f92d6 100644 --- a/tests/auto/quick/qquickfocusscope/tst_qquickfocusscope.cpp +++ b/tests/auto/quick/qquickfocusscope/tst_qquickfocusscope.cpp @@ -81,27 +81,27 @@ void tst_qquickfocusscope::basic() view->requestActivate(); QTest::qWaitForWindowActive(view); - QTRY_VERIFY(view == qGuiApp->focusWindow()); + QTRY_COMPARE(view, qGuiApp->focusWindow()); QVERIFY(view->isTopLevel()); - QVERIFY(item0->hasActiveFocus() == true); - QVERIFY(item1->hasActiveFocus() == true); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); + QVERIFY(item0->hasActiveFocus()); + QVERIFY(item1->hasActiveFocus()); + QVERIFY(!item2->hasActiveFocus()); + QVERIFY(!item3->hasActiveFocus()); QTest::keyClick(view, Qt::Key_Right); QTest::qWait(50); - QVERIFY(item0->hasActiveFocus() == true); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == true); - QVERIFY(item3->hasActiveFocus() == false); + QVERIFY(item0->hasActiveFocus()); + QVERIFY(!item1->hasActiveFocus()); + QVERIFY(item2->hasActiveFocus()); + QVERIFY(!item3->hasActiveFocus()); QTest::keyClick(view, Qt::Key_Down); QTest::qWait(50); - QVERIFY(item0->hasActiveFocus() == false); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == true); + QVERIFY(!item0->hasActiveFocus()); + QVERIFY(!item1->hasActiveFocus()); + QVERIFY(!item2->hasActiveFocus()); + QVERIFY(item3->hasActiveFocus()); delete view; } @@ -126,13 +126,13 @@ void tst_qquickfocusscope::nested() view->requestActivate(); QTest::qWaitForWindowActive(view); - QTRY_VERIFY(view == qGuiApp->focusWindow()); + QTRY_COMPARE(view, qGuiApp->focusWindow()); - QVERIFY(item1->hasActiveFocus() == true); - QVERIFY(item2->hasActiveFocus() == true); - QVERIFY(item3->hasActiveFocus() == true); - QVERIFY(item4->hasActiveFocus() == true); - QVERIFY(item5->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus()); + QVERIFY(item2->hasActiveFocus()); + QVERIFY(item3->hasActiveFocus()); + QVERIFY(item4->hasActiveFocus()); + QVERIFY(item5->hasActiveFocus()); delete view; } @@ -153,24 +153,24 @@ void tst_qquickfocusscope::noFocus() view->show(); view->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(view)); - QVERIFY(view == qGuiApp->focusWindow()); + QCOMPARE(view, qGuiApp->focusWindow()); - QVERIFY(item0->hasActiveFocus() == false); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); + QVERIFY(!item0->hasActiveFocus()); + QVERIFY(!item1->hasActiveFocus()); + QVERIFY(!item2->hasActiveFocus()); + QVERIFY(!item3->hasActiveFocus()); QTest::keyClick(view, Qt::Key_Right); - QVERIFY(item0->hasActiveFocus() == false); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); + QVERIFY(!item0->hasActiveFocus()); + QVERIFY(!item1->hasActiveFocus()); + QVERIFY(!item2->hasActiveFocus()); + QVERIFY(!item3->hasActiveFocus()); QTest::keyClick(view, Qt::Key_Down); - QVERIFY(item0->hasActiveFocus() == false); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); + QVERIFY(!item0->hasActiveFocus()); + QVERIFY(!item1->hasActiveFocus()); + QVERIFY(!item2->hasActiveFocus()); + QVERIFY(!item3->hasActiveFocus()); delete view; } @@ -194,33 +194,33 @@ void tst_qquickfocusscope::textEdit() QTest::qWaitForWindowActive(view); - QTRY_VERIFY(view == qGuiApp->focusWindow()); - QVERIFY(item0->hasActiveFocus() == true); - QVERIFY(item1->hasActiveFocus() == true); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); + QTRY_COMPARE(view, qGuiApp->focusWindow()); + QVERIFY(item0->hasActiveFocus()); + QVERIFY(item1->hasActiveFocus()); + QVERIFY(!item2->hasActiveFocus()); + QVERIFY(!item3->hasActiveFocus()); QTest::keyClick(view, Qt::Key_Right); - QVERIFY(item0->hasActiveFocus() == true); - QVERIFY(item1->hasActiveFocus() == true); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); + QVERIFY(item0->hasActiveFocus()); + QVERIFY(item1->hasActiveFocus()); + QVERIFY(!item2->hasActiveFocus()); + QVERIFY(!item3->hasActiveFocus()); QTest::keyClick(view, Qt::Key_Right); QTest::keyClick(view, Qt::Key_Right); QTest::keyClick(view, Qt::Key_Right); QTest::keyClick(view, Qt::Key_Right); QTest::keyClick(view, Qt::Key_Right); - QVERIFY(item0->hasActiveFocus() == true); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == true); - QVERIFY(item3->hasActiveFocus() == false); + QVERIFY(item0->hasActiveFocus()); + QVERIFY(!item1->hasActiveFocus()); + QVERIFY(item2->hasActiveFocus()); + QVERIFY(!item3->hasActiveFocus()); QTest::keyClick(view, Qt::Key_Down); - QVERIFY(item0->hasActiveFocus() == false); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == true); + QVERIFY(!item0->hasActiveFocus()); + QVERIFY(!item1->hasActiveFocus()); + QVERIFY(!item2->hasActiveFocus()); + QVERIFY(item3->hasActiveFocus()); delete view; } @@ -246,30 +246,30 @@ void tst_qquickfocusscope::forceFocus() view->show(); view->requestActivate(); QTest::qWaitForWindowActive(view); - QTRY_VERIFY(view == qGuiApp->focusWindow()); + QTRY_COMPARE(view, qGuiApp->focusWindow()); - QVERIFY(item0->hasActiveFocus() == true); - QVERIFY(item1->hasActiveFocus() == true); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); - QVERIFY(item4->hasActiveFocus() == false); - QVERIFY(item5->hasActiveFocus() == false); + QVERIFY(item0->hasActiveFocus()); + QVERIFY(item1->hasActiveFocus()); + QVERIFY(!item2->hasActiveFocus()); + QVERIFY(!item3->hasActiveFocus()); + QVERIFY(!item4->hasActiveFocus()); + QVERIFY(!item5->hasActiveFocus()); QTest::keyClick(view, Qt::Key_4); - QVERIFY(item0->hasActiveFocus() == true); - QVERIFY(item1->hasActiveFocus() == true); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); - QVERIFY(item4->hasActiveFocus() == false); - QVERIFY(item5->hasActiveFocus() == false); + QVERIFY(item0->hasActiveFocus()); + QVERIFY(item1->hasActiveFocus()); + QVERIFY(!item2->hasActiveFocus()); + QVERIFY(!item3->hasActiveFocus()); + QVERIFY(!item4->hasActiveFocus()); + QVERIFY(!item5->hasActiveFocus()); QTest::keyClick(view, Qt::Key_5); - QVERIFY(item0->hasActiveFocus() == false); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == true); - QVERIFY(item4->hasActiveFocus() == false); - QVERIFY(item5->hasActiveFocus() == true); + QVERIFY(!item0->hasActiveFocus()); + QVERIFY(!item1->hasActiveFocus()); + QVERIFY(!item2->hasActiveFocus()); + QVERIFY(item3->hasActiveFocus()); + QVERIFY(!item4->hasActiveFocus()); + QVERIFY(item5->hasActiveFocus()); delete view; } @@ -283,13 +283,13 @@ void tst_qquickfocusscope::noParentFocus() view->show(); view->requestActivate(); QTest::qWaitForWindowActive(view); - QTRY_VERIFY(view == qGuiApp->focusWindow()); + QTRY_COMPARE(view, qGuiApp->focusWindow()); - QVERIFY(view->rootObject()->property("focus1") == false); - QVERIFY(view->rootObject()->property("focus2") == false); - QVERIFY(view->rootObject()->property("focus3") == true); - QVERIFY(view->rootObject()->property("focus4") == true); - QVERIFY(view->rootObject()->property("focus5") == true); + QVERIFY(!view->rootObject()->property("focus1").toBool()); + QVERIFY(!view->rootObject()->property("focus2").toBool()); + QVERIFY(view->rootObject()->property("focus3").toBool()); + QVERIFY(view->rootObject()->property("focus4").toBool()); + QVERIFY(view->rootObject()->property("focus5").toBool()); delete view; } @@ -312,7 +312,7 @@ void tst_qquickfocusscope::signalEmission() view->requestActivate(); QTest::qWaitForWindowActive(view); - QTRY_VERIFY(view == qGuiApp->focusWindow()); + QTRY_COMPARE(view, qGuiApp->focusWindow()); QVariant blue(QColor("blue")); QVariant red(QColor("red")); @@ -362,7 +362,7 @@ void tst_qquickfocusscope::qtBug13380() QVERIFY(QTest::qWaitForWindowExposed(view)); - QTRY_VERIFY(view == qGuiApp->focusWindow()); + QTRY_COMPARE(view, qGuiApp->focusWindow()); QVERIFY(view->rootObject()->property("noFocus").toBool()); view->rootObject()->setProperty("showRect", true); @@ -379,7 +379,7 @@ void tst_qquickfocusscope::forceActiveFocus() view->show(); view->requestActivate(); QVERIFY(QTest::qWaitForWindowExposed(view)); - QTRY_VERIFY(view == qGuiApp->focusWindow()); + QTRY_COMPARE(view, qGuiApp->focusWindow()); QQuickItem *rootObject = view->rootObject(); QVERIFY(rootObject); @@ -532,7 +532,7 @@ void tst_qquickfocusscope::canvasFocus() view->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(view)); - QVERIFY(view == qGuiApp->focusWindow()); + QCOMPARE(view, qGuiApp->focusWindow()); // Now the window has focus, active focus given to item1 QCOMPARE(rootItem->hasFocus(), true); @@ -558,7 +558,7 @@ void tst_qquickfocusscope::canvasFocus() alternateView.show(); alternateView.requestActivate(); QVERIFY(QTest::qWaitForWindowActive(&alternateView)); - QVERIFY(QGuiApplication::focusWindow() == &alternateView); + QCOMPARE(QGuiApplication::focusWindow(), &alternateView); QCOMPARE(rootItem->hasFocus(), false); QCOMPARE(rootItem->hasActiveFocus(), false); @@ -604,7 +604,7 @@ void tst_qquickfocusscope::canvasFocus() view->show(); view->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(view)); - QVERIFY(QGuiApplication::focusWindow() == view); + QCOMPARE(QGuiApplication::focusWindow(), view); QCOMPARE(rootItem->hasFocus(), true); QCOMPARE(rootItem->hasActiveFocus(), true); diff --git a/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp b/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp index a084c86a95..b16e89dc39 100644 --- a/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp +++ b/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp @@ -85,7 +85,7 @@ void tst_qquickfontloader::noFont() QVERIFY(fontObject != 0); QCOMPARE(fontObject->name(), QString("")); QCOMPARE(fontObject->source(), QUrl("")); - QTRY_VERIFY(fontObject->status() == QQuickFontLoader::Null); + QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Null); delete fontObject; } @@ -100,7 +100,7 @@ void tst_qquickfontloader::namedFont() QVERIFY(fontObject != 0); QCOMPARE(fontObject->source(), QUrl("")); QCOMPARE(fontObject->name(), QString("Helvetica")); - QTRY_VERIFY(fontObject->status() == QQuickFontLoader::Ready); + QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Ready); } void tst_qquickfontloader::localFont() @@ -113,13 +113,13 @@ void tst_qquickfontloader::localFont() QVERIFY(fontObject != 0); QVERIFY(fontObject->source() != QUrl("")); QTRY_COMPARE(fontObject->name(), QString("OCRA")); - QTRY_VERIFY(fontObject->status() == QQuickFontLoader::Ready); + QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Ready); } void tst_qquickfontloader::failLocalFont() { QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"" + testFileUrl("dummy.ttf").toString() + "\" }"; - QTest::ignoreMessage(QtWarningMsg, QString("<Unknown File>:2:1: QML FontLoader: Cannot load font: \"" + testFileUrl("dummy.ttf").toString() + "\"").toUtf8().constData()); + QTest::ignoreMessage(QtWarningMsg, QString("<Unknown File>:2:1: QML FontLoader: Cannot load font: \"" + testFileUrl("dummy.ttf").toString() + QLatin1Char('"')).toUtf8().constData()); QQmlComponent component(&engine); component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QQuickFontLoader *fontObject = qobject_cast<QQuickFontLoader*>(component.create()); @@ -127,7 +127,7 @@ void tst_qquickfontloader::failLocalFont() QVERIFY(fontObject != 0); QVERIFY(fontObject->source() != QUrl("")); QTRY_COMPARE(fontObject->name(), QString("")); - QTRY_VERIFY(fontObject->status() == QQuickFontLoader::Error); + QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Error); } void tst_qquickfontloader::webFont() @@ -141,7 +141,7 @@ void tst_qquickfontloader::webFont() QVERIFY(fontObject != 0); QVERIFY(fontObject->source() != QUrl("")); QTRY_COMPARE(fontObject->name(), QString("OCRA")); - QTRY_VERIFY(fontObject->status() == QQuickFontLoader::Ready); + QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Ready); } void tst_qquickfontloader::redirWebFont() @@ -157,7 +157,7 @@ void tst_qquickfontloader::redirWebFont() QVERIFY(fontObject != 0); QVERIFY(fontObject->source() != QUrl("")); QTRY_COMPARE(fontObject->name(), QString("OCRA")); - QTRY_VERIFY(fontObject->status() == QQuickFontLoader::Ready); + QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Ready); } void tst_qquickfontloader::failWebFont() @@ -172,7 +172,7 @@ void tst_qquickfontloader::failWebFont() QVERIFY(fontObject != 0); QVERIFY(fontObject->source() != QUrl("")); QTRY_COMPARE(fontObject->name(), QString("")); - QTRY_VERIFY(fontObject->status() == QQuickFontLoader::Error); + QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Error); } void tst_qquickfontloader::changeFont() @@ -189,26 +189,26 @@ void tst_qquickfontloader::changeFont() QSignalSpy nameSpy(fontObject, SIGNAL(nameChanged())); QSignalSpy statusSpy(fontObject, SIGNAL(statusChanged())); - QTRY_VERIFY(fontObject->status() == QQuickFontLoader::Ready); + QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Ready); QCOMPARE(nameSpy.count(), 0); QCOMPARE(statusSpy.count(), 0); QTRY_COMPARE(fontObject->name(), QString("OCRA")); ctxt->setContextProperty("font", server.urlString("/daniel.ttf")); - QTRY_VERIFY(fontObject->status() == QQuickFontLoader::Loading); - QTRY_VERIFY(fontObject->status() == QQuickFontLoader::Ready); + QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Loading); + QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Ready); QCOMPARE(nameSpy.count(), 1); QCOMPARE(statusSpy.count(), 2); QTRY_COMPARE(fontObject->name(), QString("Daniel")); ctxt->setContextProperty("font", testFileUrl("tarzeau_ocr_a.ttf")); - QTRY_VERIFY(fontObject->status() == QQuickFontLoader::Ready); + QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Ready); QCOMPARE(nameSpy.count(), 2); QCOMPARE(statusSpy.count(), 2); QTRY_COMPARE(fontObject->name(), QString("OCRA")); ctxt->setContextProperty("font", server.urlString("/daniel.ttf")); - QTRY_VERIFY(fontObject->status() == QQuickFontLoader::Ready); + QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Ready); QCOMPARE(nameSpy.count(), 3); QCOMPARE(statusSpy.count(), 2); QTRY_COMPARE(fontObject->name(), QString("Daniel")); @@ -224,7 +224,7 @@ void tst_qquickfontloader::changeFontSourceViaState() QQuickFontLoader *fontObject = qobject_cast<QQuickFontLoader*>(qvariant_cast<QObject *>(window.rootObject()->property("fontloader"))); QVERIFY(fontObject != 0); - QTRY_VERIFY(fontObject->status() == QQuickFontLoader::Ready); + QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Ready); QVERIFY(fontObject->source() != QUrl("")); QTRY_COMPARE(fontObject->name(), QString("OCRA")); @@ -236,7 +236,7 @@ void tst_qquickfontloader::changeFontSourceViaState() QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); QEXPECT_FAIL("", "QTBUG-20268", Abort); - QTRY_VERIFY(fontObject->status() == QQuickFontLoader::Ready); + QTRY_COMPARE(fontObject->status(), QQuickFontLoader::Ready); QCOMPARE(window.rootObject()->property("name").toString(), QString("Tahoma")); } diff --git a/tests/auto/quick/qquickfontloader_static/data/font.ttf b/tests/auto/quick/qquickfontloader_static/data/font.ttf Binary files differnew file mode 100644 index 0000000000..aae50d5035 --- /dev/null +++ b/tests/auto/quick/qquickfontloader_static/data/font.ttf diff --git a/tests/auto/quick/qquickfontloader_static/qquickfontloader_static.pro b/tests/auto/quick/qquickfontloader_static/qquickfontloader_static.pro new file mode 100644 index 0000000000..f6835c05c0 --- /dev/null +++ b/tests/auto/quick/qquickfontloader_static/qquickfontloader_static.pro @@ -0,0 +1,12 @@ +CONFIG += testcase +TARGET = tst_qquickfontloader_static +macx:CONFIG -= app_bundle + +SOURCES += tst_qquickfontloader_static.cpp + +include (../../shared/util.pri) + +TESTDATA = data/* + +QT += core-private gui-private qml-private quick-private network testlib +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickfontloader_static/tst_qquickfontloader_static.cpp b/tests/auto/quick/qquickfontloader_static/tst_qquickfontloader_static.cpp new file mode 100644 index 0000000000..f7f00172ba --- /dev/null +++ b/tests/auto/quick/qquickfontloader_static/tst_qquickfontloader_static.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/QGuiApplication> +#include <QtQuick/QQuickView> +#include <QtQml/QQmlComponent> +#include "../../shared/util.h" +#include <qtest.h> + +QByteArray qmltemplate("import QtQuick 2.0\n" +"\n" +"Rectangle {\n" +" width: 400\n" +" height: 400\n" +" color: \"red\"\n" +" FontLoader { id: fixedFont; source: \"%1\" }\n" +" Text {\n" +" text: \"hello world\"\n" +" anchors.centerIn: parent\n" +" font.family: fixedFont.name\n" +" }\n" +"}\n"); + +int main(int argc, char **argv) +{ + for (int i = 0; i < 3; i++) { + QGuiApplication app(argc, argv); + QQmlDataTest dataTest; + dataTest.initTestCase(); + QQuickView window; + QQmlComponent component (window.engine()); + QUrl current = QUrl::fromLocalFile(""); + qmltemplate.replace("%1", dataTest.testFileUrl("font.ttf").toString().toLocal8Bit()); + component.setData(qmltemplate, current); + window.setContent(current, &component, component.create()); + window.show(); + QTest::qWaitForWindowActive(&window); + } +} diff --git a/tests/auto/quick/qquickgridview/BLACKLIST b/tests/auto/quick/qquickgridview/BLACKLIST new file mode 100644 index 0000000000..9eb9940aa5 --- /dev/null +++ b/tests/auto/quick/qquickgridview/BLACKLIST @@ -0,0 +1,2 @@ +[snapOneRow:horizontal, right to left] +windows diff --git a/tests/auto/quick/qquickgridview/data/contentHeightWithDelayRemove.qml b/tests/auto/quick/qquickgridview/data/contentHeightWithDelayRemove.qml new file mode 100644 index 0000000000..3f8246bafc --- /dev/null +++ b/tests/auto/quick/qquickgridview/data/contentHeightWithDelayRemove.qml @@ -0,0 +1,47 @@ +import QtQuick 2.1 + +Item { + width: 400 + height: 600 + function takeOne() + { + gridView.model.remove(2) + } + function takeThree() + { + gridView.model.remove(4) + gridView.model.remove(2) + gridView.model.remove(0) + } + function takeAll() + { + gridView.model.clear() + } + + GridView { + id: gridView + + property bool useDelayRemove + + height: parent.height + width: 400 + cellWidth: width/2 + model: ListModel { + ListElement { name: "A" } + ListElement { name: "B" } + ListElement { name: "C" } + ListElement { name: "D" } + ListElement { name: "E" } + } + delegate: Text { + id: wrapper + height: 100 + text: index + gridView.count + GridView.delayRemove: gridView.useDelayRemove + GridView.onRemove: SequentialAnimation { + PauseAnimation { duration: wrapper.GridView.delayRemove ? 100 : 0 } + PropertyAction { target: wrapper; property: "GridView.delayRemove"; value: false } + } + } + } +} diff --git a/tests/auto/quick/qquickgridview/data/gridview-initCurrent.qml b/tests/auto/quick/qquickgridview/data/gridview-initCurrent.qml index af35d2fa1b..0a6184c9de 100644 --- a/tests/auto/quick/qquickgridview/data/gridview-initCurrent.qml +++ b/tests/auto/quick/qquickgridview/data/gridview-initCurrent.qml @@ -6,6 +6,7 @@ Rectangle { property int current: grid.currentIndex property bool showHeader: false property bool showFooter: false + property int currentItemChangedCount: 0 width: 240 height: 320 @@ -63,5 +64,7 @@ Rectangle { model: testModel header: root.showHeader ? headerFooter : null footer: root.showFooter ? headerFooter : null + + onCurrentItemChanged: { root.currentItemChangedCount++ } } } diff --git a/tests/auto/quick/qquickgridview/data/qtbug45640.qml b/tests/auto/quick/qquickgridview/data/qtbug45640.qml new file mode 100644 index 0000000000..6973773432 --- /dev/null +++ b/tests/auto/quick/qquickgridview/data/qtbug45640.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +GridView { + id: gridView + width: 400; height: 400 + cellHeight: 100 + cellWidth: 100 + model: 32 + + topMargin: 50 + snapMode: GridView.SnapToRow + preferredHighlightBegin: 50 + preferredHighlightEnd: 50 + highlightRangeMode: GridView.ApplyRange + + delegate: Rectangle { + width: 100 + height: 100 + color: index % 2 == 0 ? "#FFFF00" : "#0000FF" + } + + highlight: Rectangle { color: "red"; z: 2 } + highlightMoveDuration: 1000 +} diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp index 9472407e01..3699bef56d 100644 --- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp +++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp @@ -206,6 +206,11 @@ private slots: void jsArrayChange(); + void contentHeightWithDelayRemove_data(); + void contentHeightWithDelayRemove(); + + void QTBUG_45640(); + private: QList<int> toIntList(const QVariantList &list); void matchIndexLists(const QVariantList &indexLists, const QList<int> &expectedIndexes); @@ -373,7 +378,7 @@ void tst_QQuickGridView::items() ctxt->setContextProperty("testModel", &model2); int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); - QTRY_VERIFY(itemCount == 0); + QTRY_COMPARE(itemCount, 0); delete window; } @@ -473,8 +478,8 @@ void tst_QQuickGridView::inserted_basic() // Confirm items positioned correctly for (int i = 0; i < model.count(); ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); - QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60); + QTRY_COMPARE(item->x(), qreal((i%3)*80)); + QTRY_COMPARE(item->y(), qreal((i/3)*60)); } for (int i = model.count(); i < 30; ++i) @@ -485,7 +490,7 @@ void tst_QQuickGridView::inserted_basic() // Insert item outside visible area model.insertItem(1, "Hello", "1324"); - QTRY_VERIFY(gridview->contentY() == 120); + QTRY_COMPARE(gridview->contentY(), qreal(120)); delete window; } @@ -815,8 +820,8 @@ void tst_QQuickGridView::removed_basic() for (int i = 0; i < model.count() && i < itemCount; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60); + QTRY_COMPARE(item->x(), qreal((i%3)*80)); + QTRY_COMPARE(item->y(), qreal((i/3)*60)); } // Remove first item (which is the current item); @@ -836,8 +841,8 @@ void tst_QQuickGridView::removed_basic() for (int i = 0; i < model.count() && i < itemCount; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60); + QTRY_COMPARE(item->x(), qreal((i%3)*80)); + QTRY_COMPARE(item->y(), qreal((i/3)*60)); } // Remove items not visible @@ -849,8 +854,8 @@ void tst_QQuickGridView::removed_basic() for (int i = 0; i < model.count() && i < itemCount; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60); + QTRY_COMPARE(item->x(), qreal((i%3)*80)); + QTRY_COMPARE(item->y(), qreal((i/3)*60)); } // Remove items before visible @@ -867,8 +872,8 @@ void tst_QQuickGridView::removed_basic() for (int i = 6; i < 18; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60); + QTRY_COMPARE(item->x(), qreal((i%3)*80)); + QTRY_COMPARE(item->y(), qreal((i/3)*60)); } // Remove currentIndex @@ -886,8 +891,8 @@ void tst_QQuickGridView::removed_basic() itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); for (int i = 0; i < model.count() && i < itemCount; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); - QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60); + QTRY_COMPARE(item->x(), qreal((i%3)*80)); + QTRY_COMPARE(item->y(), qreal((i/3)*60)); } // remove item outside current view. @@ -895,7 +900,7 @@ void tst_QQuickGridView::removed_basic() gridview->setContentY(240); model.removeItem(30); - QTRY_VERIFY(gridview->currentIndex() == 31); + QTRY_COMPARE(gridview->currentIndex(), 31); // remove current item beyond visible items. gridview->setCurrentIndex(20); @@ -912,7 +917,7 @@ void tst_QQuickGridView::removed_basic() model.removeItem(6); QTRY_COMPARE(gridview->currentIndex(), 7); - QTRY_VERIFY(gridview->currentItem() == oldCurrent); + QTRY_COMPARE(gridview->currentItem(), oldCurrent); delete window; } @@ -1211,7 +1216,7 @@ void tst_QQuickGridView::addOrRemoveBeforeVisible() for (int i = 0; i < model.count() && i < itemCount; ++i) { QTRY_VERIFY(findItem<QQuickItem>(contentItem, "wrapper", i)); QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); - QTRY_VERIFY(item->x() == (i%3)*80); + QTRY_COMPARE(item->x(), qreal((i%3)*80)); QTRY_VERIFY(item->y() == (i/3)*60 + newTopContentY); } @@ -1249,10 +1254,10 @@ void tst_QQuickGridView::clear() model.clear(); gridview->forceLayout(); - QVERIFY(gridview->count() == 0); - QVERIFY(gridview->currentItem() == 0); - QVERIFY(gridview->contentY() == 0); - QVERIFY(gridview->currentIndex() == -1); + QCOMPARE(gridview->count(), 0); + QVERIFY(!gridview->currentItem()); + QCOMPARE(gridview->contentY(), qreal(0)); + QCOMPARE(gridview->currentIndex(), -1); QCOMPARE(gridview->contentHeight(), 0.0); // confirm sanity when adding an item to cleared list @@ -1260,7 +1265,7 @@ void tst_QQuickGridView::clear() gridview->forceLayout(); QTRY_COMPARE(gridview->count(), 1); QVERIFY(gridview->currentItem() != 0); - QVERIFY(gridview->currentIndex() == 0); + QCOMPARE(gridview->currentIndex(), 0); delete window; } @@ -1799,7 +1804,7 @@ void tst_QQuickGridView::swapWithFirstItem() // ensure content position is stable gridview->setContentY(0); model.moveItem(10, 0); - QTRY_VERIFY(gridview->contentY() == 0); + QTRY_COMPARE(gridview->contentY(), qreal(0)); delete window; } @@ -1849,7 +1854,7 @@ void tst_QQuickGridView::currentIndex() gridview->setCurrentIndex(35); QTRY_VERIFY(gridview->verticalVelocity() != 0.0); gridview->setCurrentIndex(0); - QTRY_VERIFY(gridview->verticalVelocity() == 0.0); + QTRY_COMPARE(gridview->verticalVelocity(), 0.0); // footer should become visible if it is out of view, and then current index moves to the first row window->rootObject()->setProperty("showFooter", true); @@ -1871,7 +1876,7 @@ void tst_QQuickGridView::currentIndex() // turn off auto highlight gridview->setHighlightFollowsCurrentItem(false); - QVERIFY(gridview->highlightFollowsCurrentItem() == false); + QVERIFY(!gridview->highlightFollowsCurrentItem()); QVERIFY(gridview->highlightItem()); qreal hlPosX = gridview->highlightItem()->x(); qreal hlPosY = gridview->highlightItem()->y(); @@ -1881,9 +1886,12 @@ void tst_QQuickGridView::currentIndex() QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY); // insert item before currentIndex + window->rootObject()->setProperty("currentItemChangedCount", QVariant(0)); gridview->setCurrentIndex(28); + QTRY_COMPARE(window->rootObject()->property("currentItemChangedCount").toInt(), 1); model.insertItem(0, "Foo", "1111"); QTRY_COMPARE(window->rootObject()->property("current").toInt(), 29); + QCOMPARE(window->rootObject()->property("currentItemChangedCount").toInt(), 1); // check removing highlight by setting currentIndex to -1; gridview->setCurrentIndex(-1); @@ -1971,7 +1979,7 @@ void tst_QQuickGridView::keyNavigation() window->requestActivate(); QTest::qWaitForWindowActive(window); - QTRY_VERIFY(qGuiApp->focusWindow() == window); + QTRY_COMPARE(qGuiApp->focusWindow(), window); QCOMPARE(gridview->currentIndex(), 0); QTest::keyClick(window, forwardsKey); @@ -2256,15 +2264,15 @@ void tst_QQuickGridView::defaultValues() QQuickGridView *obj = qobject_cast<QQuickGridView*>(c.create()); QTRY_VERIFY(obj != 0); - QTRY_VERIFY(obj->model() == QVariant()); - QTRY_VERIFY(obj->delegate() == 0); + QTRY_COMPARE(obj->model(), QVariant()); + QTRY_VERIFY(!obj->delegate()); QTRY_COMPARE(obj->currentIndex(), -1); - QTRY_VERIFY(obj->currentItem() == 0); + QTRY_VERIFY(!obj->currentItem()); QTRY_COMPARE(obj->count(), 0); - QTRY_VERIFY(obj->highlight() == 0); - QTRY_VERIFY(obj->highlightItem() == 0); + QTRY_VERIFY(!obj->highlight()); + QTRY_VERIFY(!obj->highlightItem()); QTRY_COMPARE(obj->highlightFollowsCurrentItem(), true); - QTRY_VERIFY(obj->flow() == 0); + QTRY_COMPARE(obj->flow(), QQuickGridView::FlowLeftToRight); QTRY_COMPARE(obj->isWrapEnabled(), false); #ifdef QML_VIEW_DEFAULTCACHEBUFFER QTRY_COMPARE(obj->cacheBuffer(), QML_VIEW_DEFAULTCACHEBUFFER); @@ -2291,7 +2299,7 @@ void tst_QQuickGridView::properties() QTRY_VERIFY(obj->highlight() != 0); QTRY_VERIFY(obj->highlightItem() != 0); QTRY_COMPARE(obj->highlightFollowsCurrentItem(), false); - QTRY_VERIFY(obj->flow() == 0); + QTRY_COMPARE(obj->flow(), QQuickGridView::FlowLeftToRight); QTRY_COMPARE(obj->isWrapEnabled(), true); QTRY_COMPARE(obj->cacheBuffer(), 200); QTRY_COMPARE(obj->cellWidth(), qreal(100)); @@ -2728,7 +2736,7 @@ void tst_QQuickGridView::mirroring() foreach (const QString objectName, objectNames) QCOMPARE(findItem<QQuickItem>(gridviewA, objectName)->x(), findItem<QQuickItem>(gridviewB, objectName)->x()); - QVERIFY(gridviewB->layoutDirection() == gridviewB->effectiveLayoutDirection()); + QCOMPARE(gridviewB->layoutDirection(), gridviewB->effectiveLayoutDirection()); QQuickItemPrivate::get(gridviewB)->setLayoutMirror(true); QVERIFY(gridviewB->layoutDirection() != gridviewB->effectiveLayoutDirection()); @@ -3016,7 +3024,7 @@ void tst_QQuickGridView::footer() QQuickText *footer = findItem<QQuickText>(contentItem, "footer"); QVERIFY(footer); - QVERIFY(footer == gridview->footerItem()); + QCOMPARE(footer, gridview->footerItem()); QCOMPARE(footer->position(), initialFooterPos); QCOMPARE(footer->width(), 100.); @@ -3082,7 +3090,7 @@ void tst_QQuickGridView::footer() QVERIFY(!footer); footer = findItem<QQuickText>(contentItem, "footer2"); QVERIFY(footer); - QVERIFY(footer == gridview->footerItem()); + QCOMPARE(footer, gridview->footerItem()); QCOMPARE(footer->position(), changedFooterPos); QCOMPARE(footer->width(), 50.); @@ -3265,7 +3273,7 @@ void tst_QQuickGridView::header() QQuickText *header = findItem<QQuickText>(contentItem, "header"); QVERIFY(header); - QVERIFY(header == gridview->headerItem()); + QCOMPARE(header, gridview->headerItem()); QCOMPARE(header->position(), initialHeaderPos); QCOMPARE(header->width(), 100.); @@ -3302,7 +3310,7 @@ void tst_QQuickGridView::header() header = findItem<QQuickText>(contentItem, "header2"); QVERIFY(header); - QVERIFY(header == gridview->headerItem()); + QCOMPARE(header, gridview->headerItem()); QCOMPARE(header->position(), changedHeaderPos); QCOMPARE(header->width(), 50.); @@ -3609,11 +3617,11 @@ void tst_QQuickGridView::resetModel_headerFooter() // A reset should not force a new header or footer to be created. QQuickItem *newHeader = findItem<QQuickItem>(contentItem, "header"); - QVERIFY(newHeader == header); + QCOMPARE(newHeader, header); QCOMPARE(header->y(), -header->height()); QQuickItem *newFooter = findItem<QQuickItem>(contentItem, "footer"); - QVERIFY(newFooter == footer); + QCOMPARE(newFooter, footer); QCOMPARE(footer->y(), 60.*2); delete window; @@ -4315,8 +4323,19 @@ void tst_QQuickGridView::snapToRow() QQuickItem *contentItem = gridview->contentItem(); QTRY_VERIFY(contentItem != 0); + qreal origContentY = gridview->contentY(); + qreal origContentX = gridview->contentX(); // confirm that a flick hits an item boundary flick(window, flickStart, flickEnd, 180); + + // wait until it's at least one cell further + QTRY_VERIFY(qAbs(gridview->contentX() - origContentX) > 80 || + qAbs(gridview->contentY() - origContentY) > 80); + + // click to stop it. Otherwise we wouldn't know how much further it will go. We don't want to it + // to hit the endExtent, yet. + QTest::mouseClick(window, Qt::LeftButton, 0, flickEnd); + QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops if (flow == QQuickGridView::FlowLeftToRight) QCOMPARE(qreal(fmod(gridview->contentY(),80.0)), snapAlignment); @@ -5810,7 +5829,7 @@ void tst_QQuickGridView::cacheBuffer() window->engine()->setIncubationController(&controller); window->rootObject()->setProperty("cacheBuffer", 200); - QTRY_VERIFY(gridview->cacheBuffer() == 200); + QTRY_COMPARE(gridview->cacheBuffer(), 200); // items will be created one at a time for (int i = itemCount; i < qMin(itemCount+9,model.count()); ++i) { @@ -5910,8 +5929,8 @@ void tst_QQuickGridView::asynchronous() for (int i = 0; i < 12; ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; - QVERIFY(item->x() == (i%3)*100); - QVERIFY(item->y() == (i/3)*100); + QCOMPARE(item->x(), qreal((i%3)*100)); + QCOMPARE(item->y(), qreal((i/3)*100)); } delete window; @@ -6329,7 +6348,7 @@ void tst_QQuickGridView::matchIndexLists(const QVariantList &indexLists, const Q void tst_QQuickGridView::matchItemsAndIndexes(const QVariantMap &items, const QaimModel &model, const QList<int> &expectedIndexes) { for (QVariantMap::const_iterator it = items.begin(); it != items.end(); ++it) { - QVERIFY(it.value().type() == QVariant::Int); + QCOMPARE(it.value().type(), QVariant::Int); QString name = it.key(); int itemIndex = it.value().toInt(); QVERIFY2(expectedIndexes.contains(itemIndex), QTest::toString(QString("Index %1 not found in expectedIndexes").arg(itemIndex))); @@ -6460,6 +6479,93 @@ void tst_QQuickGridView::jsArrayChange() QCOMPARE(spy.count(), 1); } +void tst_QQuickGridView::contentHeightWithDelayRemove_data() +{ + QTest::addColumn<bool>("useDelayRemove"); + QTest::addColumn<QByteArray>("removeFunc"); + QTest::addColumn<int>("countDelta"); + QTest::addColumn<qreal>("contentHeightDelta"); + + QTest::newRow("remove without delayRemove") + << false + << QByteArray("takeOne") + << -1 + << qreal(-1 * 100.0); + + QTest::newRow("remove with delayRemove") + << true + << QByteArray("takeOne") + << -1 + << qreal(-1 * 100.0); + + QTest::newRow("remove with multiple delayRemove") + << true + << QByteArray("takeThree") + << -3 + << qreal(-2 * 100.0); + + QTest::newRow("clear with delayRemove") + << true + << QByteArray("takeAll") + << -5 + << qreal(-3 * 100.0); +} + +void tst_QQuickGridView::contentHeightWithDelayRemove() +{ + QFETCH(bool, useDelayRemove); + QFETCH(QByteArray, removeFunc); + QFETCH(int, countDelta); + QFETCH(qreal, contentHeightDelta); + + QQuickView *window = createView(); + window->setSource(testFileUrl("contentHeightWithDelayRemove.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickGridView *gridview = window->rootObject()->findChild<QQuickGridView*>(); + QTRY_VERIFY(gridview != 0); + + const int initialCount(gridview->count()); + const int eventualCount(initialCount + countDelta); + + const qreal initialContentHeight(gridview->contentHeight()); + const int eventualContentHeight(qRound(initialContentHeight + contentHeightDelta)); + + gridview->setProperty("useDelayRemove", useDelayRemove); + QMetaObject::invokeMethod(window->rootObject(), removeFunc.constData()); + QTest::qWait(50); + QCOMPARE(gridview->count(), eventualCount); + + if (useDelayRemove) { + QCOMPARE(qRound(gridview->contentHeight()), qRound(initialContentHeight)); + QTRY_COMPARE(qRound(gridview->contentHeight()), eventualContentHeight); + } else { + QCOMPARE(qRound(gridview->contentHeight()), eventualContentHeight); + } + + delete window; +} + +void tst_QQuickGridView::QTBUG_45640() +{ + QQuickView *window = createView(); + window->setSource(testFileUrl("qtbug45640.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickGridView *gridview = qobject_cast<QQuickGridView*>(window->rootObject()); + QVERIFY(gridview != 0); + + QCOMPARE(gridview->contentY(), qreal(-50.0)); + + gridview->moveCurrentIndexDown(); + + QTRY_VERIFY(gridview->contentY() > qreal(-50.0) && gridview->contentY() < qreal(0.0)); + + delete window; +} + QTEST_MAIN(tst_QQuickGridView) #include "tst_qquickgridview.moc" diff --git a/tests/auto/quick/qquickimage/tst_qquickimage.cpp b/tests/auto/quick/qquickimage/tst_qquickimage.cpp index ce8b52222d..3975654694 100644 --- a/tests/auto/quick/qquickimage/tst_qquickimage.cpp +++ b/tests/auto/quick/qquickimage/tst_qquickimage.cpp @@ -121,7 +121,7 @@ void tst_qquickimage::noSource() QQuickImage *obj = qobject_cast<QQuickImage*>(component.create()); QVERIFY(obj != 0); QCOMPARE(obj->source(), QUrl()); - QVERIFY(obj->status() == QQuickImage::Null); + QCOMPARE(obj->status(), QQuickImage::Null); QCOMPARE(obj->width(), 0.); QCOMPARE(obj->height(), 0.); QCOMPARE(obj->fillMode(), QQuickImage::Stretch); @@ -154,7 +154,7 @@ void tst_qquickimage::imageSource_data() if (QImageReader::supportedImageFormats().contains("svgz")) QTest::newRow("remote svgz") << "/heart.svgz" << 550.0 << 500.0 << true << false << false << ""; QTest::newRow("remote not found") << "/no-such-file.png" << 0.0 << 0.0 << true - << false << true << "<Unknown File>:2:1: QML Image: Error downloading {{ServerBaseUrl}}/no-such-file.png - server replied: Not found"; + << false << true << "<Unknown File>:2:1: QML Image: Error transferring {{ServerBaseUrl}}/no-such-file.png - server replied: Not found"; } @@ -168,6 +168,18 @@ void tst_qquickimage::imageSource() QFETCH(bool, cache); QFETCH(QString, error); + +#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) + if (qstrcmp(QTest::currentDataTag(), "remote") == 0 + || qstrcmp(QTest::currentDataTag(), "remote redirected") == 0 + || qstrcmp(QTest::currentDataTag(), "remote svg") == 0 + || qstrcmp(QTest::currentDataTag(), "remote svgz") == 0 + || qstrcmp(QTest::currentDataTag(), "remote not found") == 0 + ) { + QSKIP("Remote tests cause occasional hangs in the CI system -- QTBUG-45655"); + } +#endif + TestHTTPServer server; if (remote) { QVERIFY2(server.listen(), qPrintable(server.errorString())); @@ -189,28 +201,28 @@ void tst_qquickimage::imageSource() QVERIFY(obj != 0); if (async) - QVERIFY(obj->asynchronous() == true); + QVERIFY(obj->asynchronous()); else - QVERIFY(obj->asynchronous() == false); + QVERIFY(!obj->asynchronous()); if (cache) - QVERIFY(obj->cache() == true); + QVERIFY(obj->cache()); else - QVERIFY(obj->cache() == false); + QVERIFY(!obj->cache()); if (remote || async) - QTRY_VERIFY(obj->status() == QQuickImage::Loading); + QTRY_COMPARE(obj->status(), QQuickImage::Loading); QCOMPARE(obj->source(), remote ? source : QUrl(source)); if (error.isEmpty()) { - QTRY_VERIFY(obj->status() == QQuickImage::Ready); + QTRY_COMPARE(obj->status(), QQuickImage::Ready); QCOMPARE(obj->width(), qreal(width)); QCOMPARE(obj->height(), qreal(height)); QCOMPARE(obj->fillMode(), QQuickImage::Stretch); QCOMPARE(obj->progress(), 1.0); } else { - QTRY_VERIFY(obj->status() == QQuickImage::Error); + QTRY_COMPARE(obj->status(), QQuickImage::Error); } delete obj; @@ -225,14 +237,14 @@ void tst_qquickimage::clearSource() component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QQuickImage *obj = qobject_cast<QQuickImage*>(component.create()); QVERIFY(obj != 0); - QVERIFY(obj->status() == QQuickImage::Ready); + QCOMPARE(obj->status(), QQuickImage::Ready); QCOMPARE(obj->width(), 120.); QCOMPARE(obj->height(), 120.); QCOMPARE(obj->progress(), 1.0); ctxt->setContextProperty("srcImage", ""); QVERIFY(obj->source().isEmpty()); - QVERIFY(obj->status() == QQuickImage::Null); + QCOMPARE(obj->status(), QQuickImage::Null); QCOMPARE(obj->width(), 0.); QCOMPARE(obj->height(), 0.); QCOMPARE(obj->progress(), 0.0); @@ -533,7 +545,7 @@ void tst_qquickimage::noLoading() component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QQuickImage *obj = qobject_cast<QQuickImage*>(component.create()); QVERIFY(obj != 0); - QVERIFY(obj->status() == QQuickImage::Ready); + QCOMPARE(obj->status(), QQuickImage::Ready); QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(QUrl))); QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal))); @@ -541,29 +553,30 @@ void tst_qquickimage::noLoading() // Loading local file ctxt->setContextProperty("srcImage", testFileUrl("green.png")); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(obj->status(), QQuickImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); QTRY_COMPARE(sourceSpy.count(), 1); QTRY_COMPARE(progressSpy.count(), 0); QTRY_COMPARE(statusSpy.count(), 1); // Loading remote file ctxt->setContextProperty("srcImage", server.url("/rect.png")); - QTRY_VERIFY(obj->status() == QQuickImage::Loading); - QTRY_VERIFY(obj->progress() == 0.0); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(obj->status(), QQuickImage::Loading); + QTRY_COMPARE(obj->progress(), 0.0); + QTRY_COMPARE(obj->status(), QQuickImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); QTRY_COMPARE(sourceSpy.count(), 2); - QTRY_COMPARE(progressSpy.count(), 2); + QTRY_VERIFY(progressSpy.count() >= 2); QTRY_COMPARE(statusSpy.count(), 3); // Loading remote file again - should not go through 'Loading' state. + progressSpy.clear(); ctxt->setContextProperty("srcImage", testFileUrl("green.png")); ctxt->setContextProperty("srcImage", server.url("/rect.png")); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(obj->status(), QQuickImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); QTRY_COMPARE(sourceSpy.count(), 4); - QTRY_COMPARE(progressSpy.count(), 2); + QTRY_COMPARE(progressSpy.count(), 0); QTRY_COMPARE(statusSpy.count(), 5); delete obj; @@ -615,7 +628,7 @@ void tst_qquickimage::sourceSize_QTBUG_14303() QSignalSpy sourceSizeSpy(obj, SIGNAL(sourceSizeChanged())); QTRY_VERIFY(obj != 0); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); + QTRY_COMPARE(obj->status(), QQuickImage::Ready); QTRY_COMPARE(obj->sourceSize().width(), 200); QTRY_COMPARE(obj->sourceSize().height(), 200); @@ -831,8 +844,8 @@ void tst_qquickimage::progressAndStatusChanges() component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QQuickImage *obj = qobject_cast<QQuickImage*>(component.create()); QVERIFY(obj != 0); - QVERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QCOMPARE(obj->status(), QQuickImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); qRegisterMetaType<QQuickImageBase::Status>(); QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(QUrl))); @@ -841,33 +854,33 @@ void tst_qquickimage::progressAndStatusChanges() // Same image ctxt->setContextProperty("srcImage", testFileUrl("heart.png")); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(obj->status(), QQuickImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); QTRY_COMPARE(sourceSpy.count(), 0); QTRY_COMPARE(progressSpy.count(), 0); QTRY_COMPARE(statusSpy.count(), 0); // Loading local file ctxt->setContextProperty("srcImage", testFileUrl("colors.png")); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(obj->status(), QQuickImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); QTRY_COMPARE(sourceSpy.count(), 1); QTRY_COMPARE(progressSpy.count(), 0); QTRY_COMPARE(statusSpy.count(), 1); // Loading remote file ctxt->setContextProperty("srcImage", server.url("/heart.png")); - QTRY_VERIFY(obj->status() == QQuickImage::Loading); - QTRY_VERIFY(obj->progress() == 0.0); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(obj->status(), QQuickImage::Loading); + QTRY_COMPARE(obj->progress(), 0.0); + QTRY_COMPARE(obj->status(), QQuickImage::Ready); + QTRY_COMPARE(obj->progress(), 1.0); QTRY_COMPARE(sourceSpy.count(), 2); QTRY_VERIFY(progressSpy.count() > 1); QTRY_COMPARE(statusSpy.count(), 3); ctxt->setContextProperty("srcImage", ""); - QTRY_VERIFY(obj->status() == QQuickImage::Null); - QTRY_VERIFY(obj->progress() == 0.0); + QTRY_COMPARE(obj->status(), QQuickImage::Null); + QTRY_COMPARE(obj->progress(), 0.0); QTRY_COMPARE(sourceSpy.count(), 3); QTRY_VERIFY(progressSpy.count() > 2); QTRY_COMPARE(statusSpy.count(), 4); diff --git a/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp b/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp index dae46b5c3d..644f2be129 100644 --- a/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp +++ b/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp @@ -37,6 +37,7 @@ #include <private/qquickimage_p.h> #include <QImageReader> #include <QWaitCondition> +#include <QThreadPool> Q_DECLARE_METATYPE(QQuickImageProvider*); @@ -68,6 +69,8 @@ private slots: void threadTest(); + void asyncTextureTest(); + private: QString newImageFileName() const; void fillRequestTestsData(const QString &id); @@ -234,15 +237,15 @@ void tst_qquickimageprovider::runTest(bool async, QQuickImageProvider *provider) async |= (provider->flags() & QQuickImageProvider::ForceAsynchronousImageLoading) != 0; if (async) - QTRY_VERIFY(obj->status() == QQuickImage::Loading); + QTRY_COMPARE(obj->status(), QQuickImage::Loading); QCOMPARE(obj->source(), QUrl(source)); if (error.isEmpty()) { if (async) - QTRY_VERIFY(obj->status() == QQuickImage::Ready); + QTRY_COMPARE(obj->status(), QQuickImage::Ready); else - QVERIFY(obj->status() == QQuickImage::Ready); + QCOMPARE(obj->status(), QQuickImage::Ready); if (QByteArray(QTest::currentDataTag()).startsWith("qimage")) QCOMPARE(static_cast<TestQImageProvider*>(provider)->lastImageId, imageId); else @@ -254,9 +257,9 @@ void tst_qquickimageprovider::runTest(bool async, QQuickImageProvider *provider) QCOMPARE(obj->progress(), 1.0); } else { if (async) - QTRY_VERIFY(obj->status() == QQuickImage::Error); + QTRY_COMPARE(obj->status(), QQuickImage::Error); else - QVERIFY(obj->status() == QQuickImage::Error); + QCOMPARE(obj->status(), QQuickImage::Error); } delete obj; @@ -453,7 +456,102 @@ void tst_qquickimageprovider::threadTest() provider->cond.wakeAll(); QTest::qWait(250); foreach (QQuickImage *img, images) { - QTRY_VERIFY(img->status() == QQuickImage::Ready); + QTRY_COMPARE(img->status(), QQuickImage::Ready); + } +} + +class TestImageResponse : public QQuickImageResponse, public QRunnable +{ + public: + TestImageResponse(QMutex *lock, QWaitCondition *condition, bool *ok, const QString &id, const QSize &requestedSize) + : m_lock(lock), m_condition(condition), m_ok(ok), m_id(id), m_requestedSize(requestedSize), m_texture(0) + { + setAutoDelete(false); + } + + QQuickTextureFactory *textureFactory() const + { + return m_texture; + } + + void run() + { + m_lock->lock(); + if (!(*m_ok)) { + m_condition->wait(m_lock); + } + m_lock->unlock(); + QImage image(50, 50, QImage::Format_RGB32); + image.fill(QColor(m_id).rgb()); + if (m_requestedSize.isValid()) + image = image.scaled(m_requestedSize); + m_texture = QQuickTextureFactory::textureFactoryForImage(image); + emit finished(); + } + + QMutex *m_lock; + QWaitCondition *m_condition; + bool *m_ok; + QString m_id; + QSize m_requestedSize; + QQuickTextureFactory *m_texture; +}; + +class TestAsyncProvider : public QQuickAsyncImageProvider +{ + public: + TestAsyncProvider() : ok(false) + { + pool.setMaxThreadCount(4); + } + + ~TestAsyncProvider() {} + + QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) + { + TestImageResponse *response = new TestImageResponse(&lock, &condition, &ok, id, requestedSize); + pool.start(response); + return response; + } + + QThreadPool pool; + QMutex lock; + QWaitCondition condition; + bool ok; +}; + + +void tst_qquickimageprovider::asyncTextureTest() +{ + QQmlEngine engine; + + TestAsyncProvider *provider = new TestAsyncProvider; + + engine.addImageProvider("test_async", provider); + QVERIFY(engine.imageProvider("test_async") != 0); + + QString componentStr = "import QtQuick 2.0\nItem { \n" + "Image { source: \"image://test_async/blue\"; }\n" + "Image { source: \"image://test_async/red\"; }\n" + "Image { source: \"image://test_async/green\"; }\n" + "Image { source: \"image://test_async/yellow\"; }\n" + " }"; + QQmlComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QObject *obj = component.create(); + //MUST not deadlock + QVERIFY(obj != 0); + QList<QQuickImage *> images = obj->findChildren<QQuickImage *>(); + QCOMPARE(images.count(), 4); + + QTRY_COMPARE(provider->pool.activeThreadCount(), 4); + foreach (QQuickImage *img, images) { + QTRY_COMPARE(img->status(), QQuickImage::Loading); + } + provider->ok = true; + provider->condition.wakeAll(); + foreach (QQuickImage *img, images) { + QTRY_COMPARE(img->status(), QQuickImage::Ready); } } diff --git a/tests/auto/quick/qquickitem/BLACKLIST b/tests/auto/quick/qquickitem/BLACKLIST new file mode 100644 index 0000000000..d94a3ef102 --- /dev/null +++ b/tests/auto/quick/qquickitem/BLACKLIST @@ -0,0 +1,2 @@ +[contains:hollow square: testing points inside] +xcb diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index c79af91747..73e691b08c 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -276,7 +276,7 @@ void tst_qquickitem::simpleFocus() QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *l1c1 = new TestItem(window.contentItem()); QQuickItem *l1c2 = new TestItem(window.contentItem()); @@ -327,7 +327,7 @@ void tst_qquickitem::scopedFocus() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *l1c1 = new TestItem(window.contentItem()); QQuickItem *l1c2 = new TestItem(window.contentItem()); @@ -407,7 +407,7 @@ void tst_qquickitem::addedToWindow() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *item = new TestItem; @@ -427,7 +427,7 @@ void tst_qquickitem::addedToWindow() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *item = new TestItem(window.contentItem()); @@ -456,7 +456,7 @@ void tst_qquickitem::addedToWindow() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *tree = new TestItem; QQuickItem *c1 = new TestItem(tree); @@ -480,7 +480,7 @@ void tst_qquickitem::addedToWindow() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *tree = new TestFocusScope; QQuickItem *c1 = new TestItem(tree); QQuickItem *c2 = new TestItem(tree); @@ -508,7 +508,7 @@ void tst_qquickitem::addedToWindow() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *tree = new TestFocusScope; QQuickItem *c1 = new TestItem(tree); QQuickItem *c2 = new TestItem(tree); @@ -534,7 +534,7 @@ void tst_qquickitem::addedToWindow() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *child = new TestItem(window.contentItem()); QQuickItem *tree = new TestFocusScope; QQuickItem *c1 = new TestItem(tree); @@ -574,7 +574,7 @@ void tst_qquickitem::changeParent() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *child = new TestItem(window.contentItem()); FocusState focusState; @@ -596,7 +596,7 @@ void tst_qquickitem::changeParent() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *child = new TestItem(window.contentItem()); QQuickItem *child2 = new TestItem(window.contentItem()); @@ -617,7 +617,7 @@ void tst_qquickitem::changeParent() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *child = new TestItem(window.contentItem()); QQuickItem *child2 = new TestFocusScope(window.contentItem()); QQuickItem *item = new TestItem(child); @@ -639,7 +639,7 @@ void tst_qquickitem::changeParent() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *child = new TestItem(window.contentItem()); QQuickItem *child2 = new TestFocusScope(window.contentItem()); QQuickItem *item = new TestItem(child2); @@ -661,7 +661,7 @@ void tst_qquickitem::changeParent() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *child = new TestItem(window.contentItem()); QQuickItem *child2 = new TestFocusScope(window.contentItem()); QQuickItem *item = new TestItem(child2); @@ -687,7 +687,7 @@ void tst_qquickitem::changeParent() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *item = new TestFocusScope(window.contentItem()); QQuickItem *child = new TestItem(item); QQuickItem *child2 = new TestItem; @@ -726,7 +726,7 @@ void tst_qquickitem::multipleFocusClears() view.setSource(testFileUrl("multipleFocusClears.qml")); view.show(); ensureFocus(&view); - QTRY_VERIFY(QGuiApplication::focusWindow() == &view); + QTRY_COMPARE(QGuiApplication::focusWindow(), &view); } void tst_qquickitem::focusSubItemInNonFocusScope() @@ -757,7 +757,7 @@ void tst_qquickitem::parentItemWithFocus() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); { QQuickItem parent; QQuickItem child; @@ -856,7 +856,7 @@ void tst_qquickitem::reparentFocusedItem() { QQuickWindow window; ensureFocus(&window); - QTRY_VERIFY(QGuiApplication::focusWindow() == &window); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); QQuickItem parent(window.contentItem()); QQuickItem child(&parent); @@ -883,18 +883,18 @@ void tst_qquickitem::reparentFocusedItem() void tst_qquickitem::constructor() { QScopedPointer<QQuickItem> root(new QQuickItem); - QVERIFY(root->parent() == 0); - QVERIFY(root->parentItem() == 0); + QVERIFY(!root->parent()); + QVERIFY(!root->parentItem()); QQuickItem *child1 = new QQuickItem(root.data()); - QVERIFY(child1->parent() == root.data()); - QVERIFY(child1->parentItem() == root.data()); + QCOMPARE(child1->parent(), root.data()); + QCOMPARE(child1->parentItem(), root.data()); QCOMPARE(root->childItems().count(), 1); QCOMPARE(root->childItems().at(0), child1); QQuickItem *child2 = new QQuickItem(root.data()); - QVERIFY(child2->parent() == root.data()); - QVERIFY(child2->parentItem() == root.data()); + QCOMPARE(child2->parent(), root.data()); + QCOMPARE(child2->parentItem(), root.data()); QCOMPARE(root->childItems().count(), 2); QCOMPARE(root->childItems().at(0), child1); QCOMPARE(root->childItems().at(1), child2); @@ -903,41 +903,41 @@ void tst_qquickitem::constructor() void tst_qquickitem::setParentItem() { QQuickItem *root = new QQuickItem; - QVERIFY(root->parent() == 0); - QVERIFY(root->parentItem() == 0); + QVERIFY(!root->parent()); + QVERIFY(!root->parentItem()); QQuickItem *child1 = new QQuickItem; - QVERIFY(child1->parent() == 0); - QVERIFY(child1->parentItem() == 0); + QVERIFY(!child1->parent()); + QVERIFY(!child1->parentItem()); child1->setParentItem(root); - QVERIFY(child1->parent() == 0); - QVERIFY(child1->parentItem() == root); + QVERIFY(!child1->parent()); + QCOMPARE(child1->parentItem(), root); QCOMPARE(root->childItems().count(), 1); QCOMPARE(root->childItems().at(0), child1); QQuickItem *child2 = new QQuickItem; - QVERIFY(child2->parent() == 0); - QVERIFY(child2->parentItem() == 0); + QVERIFY(!child2->parent()); + QVERIFY(!child2->parentItem()); child2->setParentItem(root); - QVERIFY(child2->parent() == 0); - QVERIFY(child2->parentItem() == root); + QVERIFY(!child2->parent()); + QCOMPARE(child2->parentItem(), root); QCOMPARE(root->childItems().count(), 2); QCOMPARE(root->childItems().at(0), child1); QCOMPARE(root->childItems().at(1), child2); child1->setParentItem(0); - QVERIFY(child1->parent() == 0); - QVERIFY(child1->parentItem() == 0); + QVERIFY(!child1->parent()); + QVERIFY(!child1->parentItem()); QCOMPARE(root->childItems().count(), 1); QCOMPARE(root->childItems().at(0), child2); delete root; - QVERIFY(child1->parent() == 0); - QVERIFY(child1->parentItem() == 0); - QVERIFY(child2->parent() == 0); - QVERIFY(child2->parentItem() == 0); + QVERIFY(!child1->parent()); + QVERIFY(!child1->parentItem()); + QVERIFY(!child2->parent()); + QVERIFY(!child2->parentItem()); delete child1; delete child2; diff --git a/tests/auto/quick/qquickitem2/data/childrenRectBottomRightCorner.qml b/tests/auto/quick/qquickitem2/data/childrenRectBottomRightCorner.qml new file mode 100644 index 0000000000..0b83e20b20 --- /dev/null +++ b/tests/auto/quick/qquickitem2/data/childrenRectBottomRightCorner.qml @@ -0,0 +1,47 @@ +import QtQuick 2.0 + +Item { + width: 300 + height: 300 + + Item { + anchors.centerIn: parent + + Rectangle { + objectName: "childrenRectProxy" + x: container.childrenRect.x + y: container.childrenRect.y + width: container.childrenRect.width + height: container.childrenRect.height + color: "red" + opacity: 0.5 + } + + Item { + id: container + + Rectangle { + x: -100 + y: -100 + width: 10 + height: 10 + color: "red" + } + + Rectangle { + x: -60 + y: -60 + width: 10 + height: 10 + color: "red" + } + } + + Rectangle { + id: origin + width: 5 + height: 5 + color: "black" + } + } +} diff --git a/tests/auto/quick/qquickitem2/data/mapCoordinates.qml b/tests/auto/quick/qquickitem2/data/mapCoordinates.qml index 0b0b15a767..a9c5030e12 100644 --- a/tests/auto/quick/qquickitem2/data/mapCoordinates.qml +++ b/tests/auto/quick/qquickitem2/data/mapCoordinates.qml @@ -65,12 +65,20 @@ Item { } function checkMapAToInvalid(x, y) { - var pos = itemA.mapToItem(1122, x, y) - return pos == undefined; + try { + itemA.mapToItem(1122, x, y) + } catch (e) { + return e instanceof TypeError + } + return false } function checkMapAFromInvalid(x, y) { - var pos = itemA.mapFromItem(1122, x, y) - return pos == undefined; + try { + itemA.mapFromItem(1122, x, y) + } catch (e) { + return e instanceof TypeError + } + return false } } diff --git a/tests/auto/quick/qquickitem2/data/mapCoordinatesRect.qml b/tests/auto/quick/qquickitem2/data/mapCoordinatesRect.qml index e21aab1f01..c127407eae 100644 --- a/tests/auto/quick/qquickitem2/data/mapCoordinatesRect.qml +++ b/tests/auto/quick/qquickitem2/data/mapCoordinatesRect.qml @@ -66,12 +66,20 @@ Item { } function checkMapAToInvalid(x, y, w, h) { - var pos = itemA.mapToItem(1122, x, y, w, h) - return pos == undefined; + try { + itemA.mapToItem(1122, x, y, w, h) + } catch (e) { + return e instanceof TypeError + } + return false; } function checkMapAFromInvalid(x, y, w, h) { - var pos = itemA.mapFromItem(1122, x, y, w, h) - return pos == undefined; + try { + itemA.mapFromItem(1122, x, y, w, h) + } catch (e) { + return e instanceof TypeError + } + return false; } } diff --git a/tests/auto/quick/qquickitem2/data/tabFence.qml b/tests/auto/quick/qquickitem2/data/tabFence.qml new file mode 100644 index 0000000000..fcf69b418b --- /dev/null +++ b/tests/auto/quick/qquickitem2/data/tabFence.qml @@ -0,0 +1,49 @@ +import QtQuick 2.1 +import Test 1.0 + +Item { + objectName: "root" + focus: true + width: 800 + height: 600 + + TabFence { + objectName: "fence1" + + TextInput { + objectName: "input11" + activeFocusOnTab: true + } + TextInput { + objectName: "input12" + activeFocusOnTab: true + } + TextInput { + objectName: "input13" + activeFocusOnTab: true + } + } + + TextInput { + objectName: "input1" + activeFocusOnTab: true + } + + TextInput { + objectName: "input2" + activeFocusOnTab: true + } + + TabFence { + objectName: "fence2" + } + + TextInput { + objectName: "input3" + activeFocusOnTab: true + } + + TabFence { + objectName: "fence3" + } +} diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index f3333df60d..c7717b9cca 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -73,6 +73,8 @@ private slots: void nextItemInFocusChain2(); void nextItemInFocusChain3(); + void tabFence(); + void keys(); void standardKeys_data(); void standardKeys(); @@ -102,6 +104,7 @@ private slots: void childrenRectBug(); void childrenRectBug2(); void childrenRectBug3(); + void childrenRectBottomRightCorner(); void childrenProperty(); void resourcesProperty(); @@ -290,6 +293,20 @@ private: QML_DECLARE_TYPE(HollowTestItem); +class TabFenceItem : public QQuickItem +{ + Q_OBJECT + +public: + TabFenceItem(QQuickItem *parent = Q_NULLPTR) + : QQuickItem(parent) + { + QQuickItemPrivate *d = QQuickItemPrivate::get(this); + d->isTabFence = true; + } +}; + +QML_DECLARE_TYPE(TabFenceItem); tst_QQuickItem::tst_QQuickItem() { @@ -300,6 +317,7 @@ void tst_QQuickItem::initTestCase() QQmlDataTest::initTestCase(); qmlRegisterType<KeyTestItem>("Test",1,0,"KeyTestItem"); qmlRegisterType<HollowTestItem>("Test", 1, 0, "HollowTestItem"); + qmlRegisterType<TabFenceItem>("Test", 1, 0, "TabFence"); } void tst_QQuickItem::cleanup() @@ -320,7 +338,7 @@ void tst_QQuickItem::activeFocusOnTab() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); // original: button12 QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "button12"); @@ -432,7 +450,7 @@ void tst_QQuickItem::activeFocusOnTab2() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); // original: button12 QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "button12"); @@ -472,7 +490,7 @@ void tst_QQuickItem::activeFocusOnTab3() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); // original: button1 QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "button1"); @@ -654,7 +672,7 @@ void tst_QQuickItem::activeFocusOnTab4() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); // original: button11 QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "button11"); @@ -686,7 +704,7 @@ void tst_QQuickItem::activeFocusOnTab5() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); // original: button11 in sub1 QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "button11"); @@ -720,7 +738,7 @@ void tst_QQuickItem::activeFocusOnTab6() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); // original: button12 QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "button12"); @@ -778,7 +796,7 @@ void tst_QQuickItem::activeFocusOnTab7() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "button1"); QVERIFY(item); @@ -811,7 +829,7 @@ void tst_QQuickItem::activeFocusOnTab8() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); QQuickItem *content = window->contentItem(); QVERIFY(content); @@ -863,7 +881,7 @@ void tst_QQuickItem::activeFocusOnTab9() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); QQuickItem *content = window->contentItem(); QVERIFY(content); @@ -914,7 +932,7 @@ void tst_QQuickItem::activeFocusOnTab10() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); QQuickItem *content = window->contentItem(); QVERIFY(content); @@ -997,7 +1015,7 @@ void tst_QQuickItem::nextItemInFocusChain() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); QQuickItem *button11 = findItem<QQuickItem>(window->rootObject(), "button11"); QVERIFY(button11); @@ -1073,7 +1091,7 @@ void tst_QQuickItem::nextItemInFocusChain2() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); QQuickItem *button11 = findItem<QQuickItem>(window->rootObject(), "button11"); QVERIFY(button11); @@ -1118,7 +1136,62 @@ void tst_QQuickItem::nextItemInFocusChain3() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); + QCOMPARE(QGuiApplication::focusWindow(), window); +} + +void verifyTabFocusChain(QQuickView *window, const char **focusChain, bool forward) +{ + int idx = 0; + for (const char **objectName = focusChain; *objectName; ++objectName, ++idx) { + const QString &descrStr = QString("idx=%1 objectName=\"%2\"").arg(idx).arg(*objectName); + const char *descr = descrStr.toLocal8Bit().data(); + QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, forward ? Qt::NoModifier : Qt::ShiftModifier); + QGuiApplication::sendEvent(window, &key); + QVERIFY2(key.isAccepted(), descr); + + QQuickItem *item = findItem<QQuickItem>(window->rootObject(), *objectName); + QVERIFY2(item, descr); + QVERIFY2(item->hasActiveFocus(), descr); + } +} + +void tst_QQuickItem::tabFence() +{ + QQuickView *window = new QQuickView(0); + window->setBaseSize(QSize(800,600)); + + window->setSource(testFileUrl("tabFence.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); QVERIFY(QGuiApplication::focusWindow() == window); + QVERIFY(window->rootObject()->hasActiveFocus()); + + const char *rootTabFocusChain[] = { + "input1", "input2", "input3", "input1", Q_NULLPTR + }; + verifyTabFocusChain(window, rootTabFocusChain, true /* forward */); + + const char *rootBacktabFocusChain[] = { + "input3", "input2", "input1", "input3", Q_NULLPTR + }; + verifyTabFocusChain(window, rootBacktabFocusChain, false /* forward */); + + // Give focus to input11 in fence1 + QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "input11"); + item->setFocus(true); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + const char *fence1TabFocusChain[] = { + "input12", "input13", "input11", "input12", Q_NULLPTR + }; + verifyTabFocusChain(window, fence1TabFocusChain, true /* forward */); + + const char *fence1BacktabFocusChain[] = { + "input11", "input13", "input12", "input11", Q_NULLPTR + }; + verifyTabFocusChain(window, fence1BacktabFocusChain, false /* forward */); } void tst_QQuickItem::keys() @@ -1136,7 +1209,7 @@ void tst_QQuickItem::keys() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); QVERIFY(window->rootObject()); QCOMPARE(window->rootObject()->property("isEnabled").toBool(), true); @@ -1146,7 +1219,7 @@ void tst_QQuickItem::keys() QCOMPARE(testObject->mKey, int(Qt::Key_A)); QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A)); QCOMPARE(testObject->mText, QLatin1String("A")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); + QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); QVERIFY(!key.isAccepted()); testObject->reset(); @@ -1156,7 +1229,7 @@ void tst_QQuickItem::keys() QCOMPARE(testObject->mKey, int(Qt::Key_A)); QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A)); QCOMPARE(testObject->mText, QLatin1String("A")); - QVERIFY(testObject->mModifiers == Qt::ShiftModifier); + QCOMPARE(testObject->mModifiers, int(Qt::ShiftModifier)); QVERIFY(key.isAccepted()); testObject->reset(); @@ -1166,7 +1239,7 @@ void tst_QQuickItem::keys() QCOMPARE(testObject->mKey, int(Qt::Key_Return)); QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Return)); QCOMPARE(testObject->mText, QLatin1String("Return")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); + QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); QVERIFY(key.isAccepted()); testObject->reset(); @@ -1176,7 +1249,7 @@ void tst_QQuickItem::keys() QCOMPARE(testObject->mKey, int(Qt::Key_0)); QCOMPARE(testObject->mForwardedKey, int(Qt::Key_0)); QCOMPARE(testObject->mText, QLatin1String("0")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); + QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); QVERIFY(key.isAccepted()); testObject->reset(); @@ -1186,7 +1259,7 @@ void tst_QQuickItem::keys() QCOMPARE(testObject->mKey, int(Qt::Key_9)); QCOMPARE(testObject->mForwardedKey, int(Qt::Key_9)); QCOMPARE(testObject->mText, QLatin1String("9")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); + QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); QVERIFY(!key.isAccepted()); testObject->reset(); @@ -1196,7 +1269,7 @@ void tst_QQuickItem::keys() QCOMPARE(testObject->mKey, int(Qt::Key_Tab)); QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Tab)); QCOMPARE(testObject->mText, QLatin1String("Tab")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); + QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); QVERIFY(key.isAccepted()); testObject->reset(); @@ -1206,7 +1279,7 @@ void tst_QQuickItem::keys() QCOMPARE(testObject->mKey, int(Qt::Key_Backtab)); QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Backtab)); QCOMPARE(testObject->mText, QLatin1String("Backtab")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); + QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); QVERIFY(key.isAccepted()); testObject->reset(); @@ -1215,8 +1288,8 @@ void tst_QQuickItem::keys() QGuiApplication::sendEvent(window, &key); QCOMPARE(testObject->mKey, int(Qt::Key_VolumeUp)); QCOMPARE(testObject->mForwardedKey, int(Qt::Key_VolumeUp)); - QVERIFY(testObject->mModifiers == Qt::NoModifier); - QVERIFY(testObject->mNativeScanCode == 1234); + QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); + QCOMPARE(testObject->mNativeScanCode, quint32(1234)); QVERIFY(key.isAccepted()); testObject->reset(); @@ -1227,7 +1300,7 @@ void tst_QQuickItem::keys() QCOMPARE(testObject->mKey, int(Qt::Key_A)); QCOMPARE(testObject->mForwardedKey, 0); QCOMPARE(testObject->mText, QLatin1String("A")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); + QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); QVERIFY(!key.isAccepted()); testObject->reset(); @@ -1322,7 +1395,7 @@ void tst_QQuickItem::keysProcessingOrder() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); KeyTestItem *testItem = qobject_cast<KeyTestItem*>(window->rootObject()); QVERIFY(testItem); @@ -1333,7 +1406,7 @@ void tst_QQuickItem::keysProcessingOrder() QGuiApplication::sendEvent(window, &key); QCOMPARE(testObject->mKey, int(Qt::Key_A)); QCOMPARE(testObject->mText, QLatin1String("A")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); + QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); QVERIFY(key.isAccepted()); testObject->reset(); @@ -1353,7 +1426,7 @@ void tst_QQuickItem::keysProcessingOrder() QGuiApplication::sendEvent(window, &key); QCOMPARE(testObject->mKey, int(Qt::Key_B)); QCOMPARE(testObject->mText, QLatin1String("B")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); + QCOMPARE(testObject->mModifiers, int(Qt::NoModifier)); QVERIFY(!key.isAccepted()); testObject->reset(); @@ -1380,7 +1453,7 @@ void tst_QQuickItem::keysim() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); QVERIFY(window->rootObject()); QVERIFY(window->rootObject()->hasFocus() && window->rootObject()->hasActiveFocus()); @@ -1406,7 +1479,7 @@ void tst_QQuickItem::keysForward() window.show(); window.requestActivate(); QVERIFY(QTest::qWaitForWindowActive(&window)); - QVERIFY(QGuiApplication::focusWindow() == &window); + QCOMPARE(QGuiApplication::focusWindow(), &window); QQuickItem *rootItem = qobject_cast<QQuickItem *>(window.rootObject()); QVERIFY(rootItem); @@ -1646,7 +1719,7 @@ void tst_QQuickItem::keyNavigation() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "item1"); QVERIFY(item); @@ -1723,7 +1796,7 @@ void tst_QQuickItem::keyNavigation_RightToLeft() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); QQuickItem *rootItem = qobject_cast<QQuickItem*>(window->rootObject()); QVERIFY(rootItem); @@ -1778,7 +1851,7 @@ void tst_QQuickItem::keyNavigation_skipNotVisible() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "item1"); QVERIFY(item); @@ -1853,7 +1926,7 @@ void tst_QQuickItem::keyNavigation_implicitSetting() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); QEvent wa(QEvent::WindowActivate); QGuiApplication::sendEvent(window, &wa); @@ -1983,7 +2056,7 @@ void tst_QQuickItem::keyNavigation_focusReason() window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); // install event filter on first item QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "item1"); @@ -2018,10 +2091,14 @@ void tst_QQuickItem::keyNavigation_focusReason() QVERIFY(key.isAccepted()); QCOMPARE(focusEventFilter.lastFocusReason, Qt::BacktabFocusReason); - // some arbitrary cursor key + // right - it's also one kind of key navigation key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); QGuiApplication::sendEvent(window, &key); QVERIFY(key.isAccepted()); + QCOMPARE(focusEventFilter.lastFocusReason, Qt::TabFocusReason); + + item->setFocus(true, Qt::OtherFocusReason); + QVERIFY(item->hasActiveFocus()); QCOMPARE(focusEventFilter.lastFocusReason, Qt::OtherFocusReason); delete window; @@ -2066,8 +2143,8 @@ void tst_QQuickItem::smooth() QVERIFY(item->smooth()); QCOMPARE(spy.count(),1); QList<QVariant> arguments = spy.first(); - QVERIFY(arguments.count() == 1); - QVERIFY(arguments.at(0).toBool() == true); + QCOMPARE(arguments.count(), 1); + QVERIFY(arguments.at(0).toBool()); item->setSmooth(true); QCOMPARE(spy.count(),1); @@ -2095,8 +2172,8 @@ void tst_QQuickItem::antialiasing() QVERIFY(item->antialiasing()); QCOMPARE(spy.count(),1); QList<QVariant> arguments = spy.first(); - QVERIFY(arguments.count() == 1); - QVERIFY(arguments.at(0).toBool() == true); + QCOMPARE(arguments.count(), 1); + QVERIFY(arguments.at(0).toBool()); item->setAntialiasing(true); QCOMPARE(spy.count(),1); @@ -2124,8 +2201,8 @@ void tst_QQuickItem::clip() QVERIFY(item->clip()); QList<QVariant> arguments = spy.first(); - QVERIFY(arguments.count() == 1); - QVERIFY(arguments.at(0).toBool() == true); + QCOMPARE(arguments.count(), 1); + QVERIFY(arguments.at(0).toBool()); QCOMPARE(spy.count(),1); item->setClip(true); @@ -2351,7 +2428,7 @@ void tst_QQuickItem::propertyChanges() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "item"); QQuickItem *parentItem = findItem<QQuickItem>(window->rootObject(), "parentItem"); @@ -2379,7 +2456,7 @@ void tst_QQuickItem::propertyChanges() QCOMPARE(item->parentItem(), parentItem); QCOMPARE(parentSpy.count(),1); QList<QVariant> parentArguments = parentSpy.first(); - QVERIFY(parentArguments.count() == 1); + QCOMPARE(parentArguments.count(), 1); QCOMPARE(item->parentItem(), qvariant_cast<QQuickItem *>(parentArguments.at(0))); QCOMPARE(childrenChangedSpy.count(),1); @@ -2395,19 +2472,19 @@ void tst_QQuickItem::propertyChanges() QCOMPARE(item->baselineOffset(), 10.0); QCOMPARE(baselineOffsetSpy.count(),1); QList<QVariant> baselineOffsetArguments = baselineOffsetSpy.first(); - QVERIFY(baselineOffsetArguments.count() == 1); + QCOMPARE(baselineOffsetArguments.count(), 1); QCOMPARE(item->baselineOffset(), baselineOffsetArguments.at(0).toReal()); QCOMPARE(parentItem->childrenRect(), QRectF(0.0,0.0,100.0,200.0)); QCOMPARE(childrenRectSpy.count(),1); QList<QVariant> childrenRectArguments = childrenRectSpy.at(0); - QVERIFY(childrenRectArguments.count() == 1); + QCOMPARE(childrenRectArguments.count(), 1); QCOMPARE(parentItem->childrenRect(), childrenRectArguments.at(0).toRectF()); QCOMPARE(item->hasActiveFocus(), true); QCOMPARE(focusSpy.count(),1); QList<QVariant> focusArguments = focusSpy.first(); - QVERIFY(focusArguments.count() == 1); + QCOMPARE(focusArguments.count(), 1); QCOMPARE(focusArguments.at(0).toBool(), true); QCOMPARE(parentItem->hasActiveFocus(), false); @@ -2519,6 +2596,22 @@ void tst_QQuickItem::childrenRectBug3() delete window; } +// QTBUG-38732 +void tst_QQuickItem::childrenRectBottomRightCorner() +{ + QQuickView *window = new QQuickView(0); + window->setSource(testFileUrl("childrenRectBottomRightCorner.qml")); + window->show(); + + QQuickItem *rect = window->rootObject()->findChild<QQuickItem*>("childrenRectProxy"); + QCOMPARE(rect->x(), qreal(-100)); + QCOMPARE(rect->y(), qreal(-100)); + QCOMPARE(rect->width(), qreal(50)); + QCOMPARE(rect->height(), qreal(50)); + + delete window; +} + // QTBUG-13893 void tst_QQuickItem::transformCrash() { @@ -2671,7 +2764,10 @@ void tst_QQuickItem::parentLoop() { QQuickView *window = new QQuickView(0); - QTest::ignoreMessage(QtWarningMsg, "QQuickItem::setParentItem: Parent is already part of this items subtree."); +#ifndef QT_NO_REGULAREXPRESSION + QRegularExpression msgRegexp = QRegularExpression("QQuickItem::setParentItem: Parent QQuickItem\\(.*\\) is already part of the subtree of QQuickItem\\(.*\\)"); + QTest::ignoreMessage(QtWarningMsg, msgRegexp); +#endif window->setSource(testFileUrl("parentLoop.qml")); QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject()); @@ -2763,7 +2859,7 @@ void tst_QQuickItem::contains() window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QCOMPARE(QGuiApplication::focusWindow(), window); QQuickItem *root = qobject_cast<QQuickItem *>(window->rootObject()); QVERIFY(root); diff --git a/tests/auto/quick/qquickitemlayer/data/TextureMirroring.qml b/tests/auto/quick/qquickitemlayer/data/TextureMirroring.qml new file mode 100644 index 0000000000..2827960153 --- /dev/null +++ b/tests/auto/quick/qquickitemlayer/data/TextureMirroring.qml @@ -0,0 +1,159 @@ +import QtQuick 2.6 + +Item +{ + width: 250 + height: 50 + + property int mirroring: 0 + + // Layered box without effect. Mirroring should not affect how it looks. + Rectangle { + x: 0 + y: 0 + width: 50 + height: 50 + layer.enabled: true + layer.textureMirroring: mirroring + Rectangle { + x: 0 + y: 0 + width: 25 + height: 25 + color: "#000000" + } + Rectangle { + x: 25 + y: 0 + width: 25 + height: 25 + color: "#ff0000" + } + Rectangle { + x: 0 + y: 25 + width: 25 + height: 25 + color: "#00ff00" + } + Rectangle { + x: 25 + y: 25 + width: 25 + height: 25 + color: "#0000ff" + } + } + + // Layered box with effect. Mirroring should affect how it looks. + Rectangle { + id: layeredEffectBox + x: 50 + y: 0 + width: 50 + height: 50 + layer.enabled: true + layer.textureMirroring: mirroring + layer.samplerName: "source" + layer.effect: ShaderEffect { + property variant source: layeredEffectBox + fragmentShader: " + uniform lowp sampler2D source; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = texture2D(source, qt_TexCoord0); + }" + + } + + Rectangle { + x: 0 + y: 0 + width: 25 + height: 25 + color: "#000000" + } + Rectangle { + x: 25 + y: 0 + width: 25 + height: 25 + color: "#ff0000" + } + Rectangle { + x: 0 + y: 25 + width: 25 + height: 25 + color: "#00ff00" + } + Rectangle { + x: 25 + y: 25 + width: 25 + height: 25 + color: "#0000ff" + } + } + + // Non-layered source item for ShaderEffectSource. Mirroring should not affect how it looks. + Rectangle { + id: box2 + x: 100 + y: 0 + width: 50 + height: 50 + Rectangle { + x: 0 + y: 0 + width: 25 + height: 25 + color: "#000000" + } + Rectangle { + x: 25 + y: 0 + width: 25 + height: 25 + color: "#ff0000" + } + Rectangle { + x: 0 + y: 25 + width: 25 + height: 25 + color: "#00ff00" + } + Rectangle { + x: 25 + y: 25 + width: 25 + height: 25 + color: "#0000ff" + } + } + // ShaderEffectSource item. Mirroring should not affect how it looks. + ShaderEffectSource { + id: theSource + x: 150 + y: 0 + width: 50 + height: 50 + sourceItem: box2 + textureMirroring: mirroring + } + // ShaderEffect item. Mirroring should affect how it looks. + ShaderEffect { + x: 200 + y: 0 + width: 50 + height: 50 + property variant source: theSource + fragmentShader: " + uniform lowp sampler2D source; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = texture2D(source, qt_TexCoord0); + }" + } +} diff --git a/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro b/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro index 999f0cf23d..a087948f6d 100644 --- a/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro +++ b/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro @@ -25,5 +25,6 @@ OTHER_FILES += \ data/DisableLayer.qml \ data/SamplerNameChange.qml \ data/ItemEffect.qml \ - data/RectangleEffect.qml + data/RectangleEffect.qml \ + data/TextureMirroring.qml DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp index 25a75c0580..094b69c07f 100644 --- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp +++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp @@ -87,7 +87,12 @@ private slots: void itemEffect(); void rectangleEffect(); + void textureMirroring_data(); + void textureMirroring(); + private: + void mirroringCheck(int mirroring, int x, bool shouldMirror, const QImage &fb); + bool m_isMesaSoftwareRasterizer; int m_mesaVersion; }; @@ -434,6 +439,94 @@ void tst_QQuickItemLayer::rectangleEffect() QCOMPARE(fb.pixel(0, 100), qRgb(0, 0, 0xff)); } +void tst_QQuickItemLayer::textureMirroring_data() +{ + QTest::addColumn<int>("mirroring"); + + QTest::newRow("no mirroring") << 0; + QTest::newRow("horizontal") << 1; + QTest::newRow("vertical") << 2; + QTest::newRow("horizontal | vertical") << 3; +} + +void tst_QQuickItemLayer::textureMirroring() +{ + QFETCH(int, mirroring); + + QQuickView view; + view.setSource(testFileUrl("TextureMirroring.qml")); + + QQuickItem *child = view.contentItem()->childItems().at(0); + child->setProperty("mirroring", mirroring); + + view.show(); + + QTest::qWaitForWindowExposed(&view); + + QImage fb = view.grabWindow(); + + // Mirroring should have no visual effect on layered item without shader effect + mirroringCheck(mirroring, 0, false, fb); + + // Mirroring should have visual effect on layered item with shader effect + mirroringCheck(mirroring, 50, true, fb); + + // Mirroring should have no visual effect on source item for ShaderEffectSource + mirroringCheck(mirroring, 100, false, fb); + + // Mirroring should have no visual effect on ShaderEffectSource item + mirroringCheck(mirroring, 150, false, fb); + + // Mirroring should have visual effect on ShaderEffect item itself + mirroringCheck(mirroring, 200, true, fb); +} + +void tst_QQuickItemLayer::mirroringCheck(int mirroring, int x, bool shouldMirror, const QImage &fb) +{ + int offset = 10; + int spacing = 25; + + if (shouldMirror) { + switch (mirroring) { + case 0: { // No mirroring -> Visually Y gets swapped, X is default + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0, 0, 0xff)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0xff, 0, 0)); + break; + } + case 1: { // Horizontal mirroring -> Visually both X and Y get swapped, as neither is default + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0, 0, 0xff)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0xff, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0, 0, 0)); + break; + } + case 2: { // Vertical mirroring -> The default case, nothing gets swapped + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0xff, 0, 0)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0, 0, 0xff)); + break; + } + case 3: { // Both axes mirrored -> Visually X gets swapped, Y is default + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0xff, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0, 0, 0)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0, 0, 0xff)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0, 0xff, 0)); + break; + } + default: + qWarning() << "Invalid case!"; + break; + } + } else { + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0xff, 0, 0)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0, 0, 0xff)); + } +} QTEST_MAIN(tst_QQuickItemLayer) diff --git a/tests/auto/quick/qquicklistview/BLACKLIST b/tests/auto/quick/qquicklistview/BLACKLIST new file mode 100644 index 0000000000..269696ce8c --- /dev/null +++ b/tests/auto/quick/qquicklistview/BLACKLIST @@ -0,0 +1,4 @@ +[QTBUG_38209] +* +[enforceRange_withoutHighlight] +osx diff --git a/tests/auto/quick/qquicklistview/data/contentHeightWithDelayRemove.qml b/tests/auto/quick/qquicklistview/data/contentHeightWithDelayRemove.qml new file mode 100644 index 0000000000..06011519b2 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/contentHeightWithDelayRemove.qml @@ -0,0 +1,46 @@ +import QtQuick 2.1 + +Item { + width: 400 + height: 600 + function takeOne() + { + listView.model.remove(2) + } + function takeThree() + { + listView.model.remove(4) + listView.model.remove(2) + listView.model.remove(0) + } + function takeAll() + { + listView.model.clear() + } + + ListView { + id: listView + + property bool useDelayRemove + + height: parent.height + width: 400 + model: ListModel { + ListElement { name: "A" } + ListElement { name: "B" } + ListElement { name: "C" } + ListElement { name: "D" } + ListElement { name: "E" } + } + delegate: Text { + id: wrapper + height: 100 + text: index + listView.count + ListView.delayRemove: listView.useDelayRemove + ListView.onRemove: SequentialAnimation { + PauseAnimation { duration: wrapper.ListView.delayRemove ? 100 : 0 } + PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: false } + } + } + } +} diff --git a/tests/auto/quick/qquicklistview/data/listview-initCurrent.qml b/tests/auto/quick/qquicklistview/data/listview-initCurrent.qml index a02b66b8af..8aff649a67 100644 --- a/tests/auto/quick/qquicklistview/data/listview-initCurrent.qml +++ b/tests/auto/quick/qquicklistview/data/listview-initCurrent.qml @@ -6,6 +6,7 @@ Rectangle { property int current: list.currentIndex property bool showHeader: false property bool showFooter: false + property int currentItemChangedCount: 0 width: 240 height: 320 @@ -60,5 +61,7 @@ Rectangle { model: testModel header: root.showHeader ? headerFooter : null footer: root.showFooter ? headerFooter : null + + onCurrentItemChanged: { root.currentItemChangedCount++ } } } diff --git a/tests/auto/quick/qquicklistview/data/objectmodel.qml b/tests/auto/quick/qquicklistview/data/objectmodel.qml new file mode 100644 index 0000000000..5c23d64cd3 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/objectmodel.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 +import QtQml.Models 2.1 + +ListView { + width: 360 + height: 360 + model: ObjectModel { + Rectangle { + width: 20 + height: 20 + color: "red" + } + Rectangle { + width: 20 + height: 20 + color: "green" + } + Rectangle { + width: 20 + height: 20 + color: "blue" + } + } +} diff --git a/tests/auto/quick/qquicklistview/data/qtbug48044.qml b/tests/auto/quick/qquicklistview/data/qtbug48044.qml new file mode 100644 index 0000000000..d318643c1c --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/qtbug48044.qml @@ -0,0 +1,144 @@ +import QtQuick 2.0 + +Item { + width: 200 + height: 442 + + ListModel { + id: listModel + ListElement { + name: "h1" + txt: "Header 1" + header: true + collapsed: true + } + ListElement { + name: "h2" + txt: "Header 2" + header: true + collapsed: true + } + ListElement { + name: "h3" + txt: "Header 3" + header: true + collapsed: true + } + + function indexFromName(name) { + for (var i = 0; i < count; i++) + if (get(i).name === name) + return i + + console.warn("Did not find index for name " + name) + return -1 + } + } + + function populateModel(prefix, index, n) { + for (var k = 1; k <= n; k++) { + var name = prefix + k + var data = { + "collapsed": false, + "name": name, + "txt": name, + "header": false + } + listModel.insert(index + k, data) + } + } + + function h2(open) { + var i = listModel.indexFromName("h2") + if (listModel.get(i).collapsed === !open) + return + + listModel.setProperty(i, "collapsed", !open) + + var n = 15 + if (open) { + h3(false) + populateModel("c2_", listModel.indexFromName("h2"), n) + } else { + listModel.remove(i + 1, n) + } + + } + + function h3(open) { + var i = listModel.indexFromName("h3") + if (listModel.get(i).collapsed === !open) + return + + listModel.setProperty(i, "collapsed", !open) + + var n = 6 + if (open) { + h2(false) + populateModel("c3_", listModel.indexFromName("h3"), n) + } else { + listModel.remove(i + 1, n) + } + } + + ListView { + id: listView + width: parent.width + height: parent.height + cacheBuffer: 0 + model: listModel + + property bool transitionsDone: false + property int runningTransitions: 0 + onRunningTransitionsChanged: { + if (runningTransitions === 0) + transitionsDone = true + } + + displaced: Transition { + id: dispTrans + SequentialAnimation { + ScriptAction { + script: listView.runningTransitions++ + } + NumberAnimation { + property: "y"; + duration: 250 + } + ScriptAction { + script: listView.runningTransitions-- + } + } + } + + delegate: Rectangle { + id: rect + color: header ? "yellow" : "cyan" + border.color: "black" + height: 50 + width: parent.width + + Text { + anchors.centerIn: parent + font.pixelSize: 20 + text: txt + } + + MouseArea { + anchors.fill: parent + onClicked: { + listView.currentIndex = index + var i = listModel.indexFromName("h3") + if (i === -1) + return; + var isCollapsed = listModel.get(i).collapsed + if (name === "h2") + h2(isCollapsed) + else if (name === "h3") + h3(isCollapsed) + } + } + } + } +} + diff --git a/tests/auto/quick/qquicklistview/data/qtbug48870.qml b/tests/auto/quick/qquicklistview/data/qtbug48870.qml new file mode 100644 index 0000000000..217f58af48 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/qtbug48870.qml @@ -0,0 +1,24 @@ +import QtQuick 2.6 + +Rectangle { + width: 500 + height: 500 + color: "blue" + + ListView { + objectName: "list" + anchors.fill: parent + model: testModel + + delegate: Rectangle { + height: 50 + width: ListView.view ? ListView.view.width : height + color: "green" + + Text { + anchors.centerIn: parent + text: "Item " + index + } + } + } +} diff --git a/tests/auto/quick/qquicklistview/data/qtbug50097.qml b/tests/auto/quick/qquicklistview/data/qtbug50097.qml new file mode 100644 index 0000000000..24d506b804 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/qtbug50097.qml @@ -0,0 +1,47 @@ +import QtQuick 2.6 + +ListView { + id: lv + + // How many rows per page + property int pageSize: 5 + + // The current page number + property int currentPage: 1 + + // How large a single item is + property int itemSize: 100 + + // Arbitrary + property int totalPages: 5 + + height: itemSize * pageSize // display one full page at a time + width: 500 // arbitrary. + model: pageSize * totalPages + delegate: Text { + height: itemSize + text: "Item " + (index + 1) + " of " + lv.count + } + + // contentY should be < 0 to account for header visibility + onContentYChanged: console.log(contentY) + + headerPositioning: ListView.OverlayHeader + header: Rectangle { + height: itemSize + width: 500 + z: 1000 + visible: false + color: "black" + + Text { + anchors.centerIn: parent + color: "red" + text: "List header" + } + } + + onCurrentPageChanged: { + lv.positionViewAtIndex((currentPage - 1) * pageSize, ListView.Beginning); + } +} diff --git a/tests/auto/quick/qquicklistview/data/qtbug50105.qml b/tests/auto/quick/qquicklistview/data/qtbug50105.qml new file mode 100644 index 0000000000..a48a881a21 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/qtbug50105.qml @@ -0,0 +1,130 @@ +import QtQuick 2.4 +import QtQuick.Window 2.2 + +Window { + id : mainWindow + visible: true + width: 800 + height: 480 + + property real gridListWidth : (width * 0.60) + property real gridListHeight : (height * 0.50) + + property real gridCellSpacing : (height * 0.004) + property real gridCellHeight : (height * 0.039) + property real gridCellWidth : (width * 0.20) + + Rectangle { + id : rectBackground + anchors.fill: parent + color : "white" + + ListView { + id : ls + width: mainWindow.gridListWidth + height: mainWindow.gridListHeight + clip : true + headerPositioning: ListView.OverlayHeader + spacing : mainWindow.gridCellSpacing + + model: ListModel { + ListElement { + name: "Bill Smith" + number: "555 3264" + hairColor: "red" + } + ListElement { + name: "John Brown" + number: "484 7789" + hairColor: "blue" + } + ListElement { + name: "Sam Wise" + number: "284 1547" + hairColor: "yellow" + } + } + + header : Row { + spacing : mainWindow.gridCellSpacing + + Rectangle { + width : mainWindow.gridCellWidth + height : mainWindow.gridCellHeight + color : "blue" + + Text { + anchors.centerIn: parent + color : "white" + text: "Name" + } + } + + Rectangle { + width : mainWindow.gridCellWidth + height : mainWindow.gridCellHeight + color : "blue" + + Text { + anchors.centerIn: parent + color : "white" + text: "Number" + } + + } + + Rectangle { + width : mainWindow.gridCellWidth + height : mainWindow.gridCellHeight + color : "blue" + + Text { + anchors.centerIn: parent + color : "white" + text: "Hair Color" + } + } + } + + delegate: Row { + spacing : mainWindow.gridCellSpacing + + Rectangle { + width : mainWindow.gridCellWidth + height : mainWindow.gridCellHeight + color : "red" + + Text { + anchors.centerIn: parent + color : "white" + text: name + } + } + + Rectangle { + width : mainWindow.gridCellWidth + height : mainWindow.gridCellHeight + color : "red" + + Text { + anchors.centerIn: parent + color : "white" + text: number + } + } + + Rectangle { + width : mainWindow.gridCellWidth + height : mainWindow.gridCellHeight + color : "red" + + Text { + anchors.centerIn: parent + color : "white" + text: hairColor + } + } + } + } + } +} diff --git a/tests/auto/quick/qquicklistview/data/snapOneItemCurrentIndexRemoveAnimation.qml b/tests/auto/quick/qquicklistview/data/snapOneItemCurrentIndexRemoveAnimation.qml new file mode 100644 index 0000000000..215467f0cc --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/snapOneItemCurrentIndexRemoveAnimation.qml @@ -0,0 +1,39 @@ +import QtQuick 2.4 + +ListView { + id: root + height: 400 + width: height + model: ListModel { + id: lmodel + ListElement { dummy: 0 } + ListElement { dummy: 0 } + ListElement { dummy: 0 } + ListElement { dummy: 0 } + ListElement { dummy: 0 } + ListElement { dummy: 0 } + } + + function removeItemZero() + { + lmodel.remove(0); + } + + orientation: ListView.Horizontal + snapMode: ListView.SnapOneItem + highlightRangeMode: ListView.StrictlyEnforceRange + + property int transitionsRun: 0 + + removeDisplaced: Transition { + id: transition + PropertyAnimation { property: "x"; duration: 500 } + onRunningChanged: if (!running) transitionsRun++; + } + + delegate: Text { + text: index + " of " + lmodel.count + width: root.width + height: root.height + } +}
\ No newline at end of file diff --git a/tests/auto/quick/qquicklistview/data/snapOneItemResize.qml b/tests/auto/quick/qquicklistview/data/snapOneItemResize.qml new file mode 100644 index 0000000000..7ecc833a64 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/snapOneItemResize.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 + +ListView { + id: list + currentIndex: 5 + snapMode: ListView.SnapOneItem + orientation: ListView.Horizontal + highlightRangeMode: ListView.StrictlyEnforceRange + highlightFollowsCurrentItem: true + model: 10 + spacing: 10 + delegate: Item { + width: ListView.view.width + height: ListView.view.height + } +} diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index c93aac456d..12405e32c0 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -40,6 +40,7 @@ #include <QtQml/qqmlcontext.h> #include <QtQml/qqmlexpression.h> #include <QtQml/qqmlincubator.h> +#include <QtQuick/private/qquickitemview_p_p.h> #include <QtQuick/private/qquicklistview_p.h> #include <QtQuick/private/qquicktext_p.h> #include <QtQml/private/qqmlobjectmodel_p.h> @@ -179,8 +180,10 @@ private slots: void creationContext(); void snapToItem_data(); void snapToItem(); + void snapOneItemResize_QTBUG_43555(); void snapOneItem_data(); void snapOneItem(); + void snapOneItemCurrentIndexRemoveAnimation(); void QTBUG_9791(); void QTBUG_11105(); @@ -241,6 +244,16 @@ private slots: void QTBUG_39492(); void jsArrayChange(); + void objectModel(); + + void contentHeightWithDelayRemove(); + void contentHeightWithDelayRemove_data(); + + void QTBUG_48044_currentItemNotVisibleAfterTransition(); + void QTBUG_48870_fastModelUpdates(); + + void QTBUG_50105(); + void QTBUG_50097_stickyHeader_positionViewAtIndex(); private: template <class T> void items(const QUrl &source); @@ -391,7 +404,7 @@ void tst_QQuickListView::items(const QUrl &source) QTRY_VERIFY(contentItem != 0); QMetaObject::invokeMethod(window->rootObject(), "checkProperties"); - QTRY_VERIFY(testObject->error() == false); + QTRY_VERIFY(!testObject->error()); QTRY_VERIFY(listview->highlightItem() != 0); QTRY_COMPARE(listview->count(), model.count()); @@ -414,20 +427,20 @@ void tst_QQuickListView::items(const QUrl &source) // switch to other delegate testObject->setAnimate(true); QMetaObject::invokeMethod(window->rootObject(), "checkProperties"); - QTRY_VERIFY(testObject->error() == false); + QTRY_VERIFY(!testObject->error()); QTRY_VERIFY(listview->currentItem()); // set invalid highlight testObject->setInvalidHighlight(true); QMetaObject::invokeMethod(window->rootObject(), "checkProperties"); - QTRY_VERIFY(testObject->error() == false); + QTRY_VERIFY(!testObject->error()); QTRY_VERIFY(listview->currentItem()); - QTRY_VERIFY(listview->highlightItem() == 0); + QTRY_VERIFY(!listview->highlightItem()); // back to normal highlight testObject->setInvalidHighlight(false); QMetaObject::invokeMethod(window->rootObject(), "checkProperties"); - QTRY_VERIFY(testObject->error() == false); + QTRY_VERIFY(!testObject->error()); QTRY_VERIFY(listview->currentItem()); QTRY_VERIFY(listview->highlightItem() != 0); @@ -439,7 +452,7 @@ void tst_QQuickListView::items(const QUrl &source) listview->forceLayout(); int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); - QTRY_VERIFY(itemCount == 0); + QTRY_COMPARE(itemCount, 0); QTRY_COMPARE(listview->highlightResizeVelocity(), 1000.0); QTRY_COMPARE(listview->highlightMoveVelocity(), 100000.0); @@ -563,7 +576,7 @@ void tst_QQuickListView::inserted(const QUrl &source) // Insert item outside visible area model.insertItem(1, "Hello", "1324"); - QTRY_VERIFY(listview->contentY() == 80); + QTRY_COMPARE(listview->contentY(), qreal(80)); // Confirm items positioned correctly for (int i = 5; i < 5+15; ++i) { @@ -582,8 +595,7 @@ void tst_QQuickListView::inserted(const QUrl &source) QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 0); QVERIFY(item); - QCOMPARE(item->y(), 0.); - QTRY_VERIFY(listview->contentY() == 0); + QTRY_COMPARE(item->y() - listview->contentY(), 0.); delete window; delete testObject; @@ -634,7 +646,8 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v QTRY_COMPARE(listview->property("count").toInt(), model.count()); - + // FIXME This is NOT checking anything about visibleItems.first() +#if 0 // check visibleItems.first() is in correct position QQuickItem *item0 = findItem<QQuickItem>(contentItem, "wrapper", 0); QVERIFY(item0); @@ -642,6 +655,7 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v QCOMPARE(item0->y(), -item0->height() - itemsOffsetAfterMove); else QCOMPARE(item0->y(), itemsOffsetAfterMove); +#endif QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper"); int firstVisibleIndex = -1; @@ -657,12 +671,21 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v // Confirm items positioned correctly and indexes correct QQuickText *name; QQuickText *number; + const qreal visibleFromPos = listview->contentY() - listview->displayMarginBeginning() - listview->cacheBuffer(); + const qreal visibleToPos = listview->contentY() + listview->height() + listview->displayMarginEnd() + listview->cacheBuffer(); for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); qreal pos = i*20.0 + itemsOffsetAfterMove; if (verticalLayoutDirection == QQuickItemView::BottomToTop) - pos = -item0->height() - pos; + pos = -item->height() - pos; + // Items outside the visible area (including cache buffer) should be skipped + if (pos > visibleToPos || pos < visibleFromPos) { + QTRY_VERIFY2(QQuickItemPrivate::get(item)->culled || item->y() < visibleFromPos || item->y() > visibleToPos, + QTest::toString(QString("index %5, y %1, from %2, to %3, expected pos %4, culled %6"). + arg(item->y()).arg(visibleFromPos).arg(visibleToPos).arg(pos).arg(i).arg(bool(QQuickItemPrivate::get(item)->culled)))); + continue; + } QTRY_COMPARE(item->y(), pos); name = findItem<QQuickText>(contentItem, "textName", i); QVERIFY(name != 0); @@ -916,7 +939,7 @@ void tst_QQuickListView::removed(const QUrl &source, bool /* animated */) QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QTRY_VERIFY(item); - QTRY_VERIFY(item->y() == i*20); + QTRY_COMPARE(item->y(), qreal(i*20)); } // Remove first item (which is the current item); @@ -968,7 +991,7 @@ void tst_QQuickListView::removed(const QUrl &source, bool /* animated */) } // Remove current index - QTRY_VERIFY(listview->currentIndex() == 9); + QTRY_COMPARE(listview->currentIndex(), 9); QQuickItem *oldCurrent = listview->currentItem(); model.removeItem(9); @@ -1004,7 +1027,7 @@ void tst_QQuickListView::removed(const QUrl &source, bool /* animated */) model.removeItem(6); QTRY_COMPARE(listview->currentIndex(), 7); - QTRY_VERIFY(listview->currentItem() == oldCurrent); + QTRY_COMPARE(listview->currentItem(), oldCurrent); listview->setContentY(80); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); @@ -1272,22 +1295,22 @@ void tst_QQuickListView::clear(const QUrl &source, QQuickItemView::VerticalLayou model.clear(); QTRY_COMPARE(findItems<QQuickListView>(contentItem, "wrapper").count(), 0); - QTRY_VERIFY(listview->count() == 0); - QTRY_VERIFY(listview->currentItem() == 0); + QTRY_COMPARE(listview->count(), 0); + QTRY_VERIFY(!listview->currentItem()); if (verticalLayoutDirection == QQuickItemView::TopToBottom) QTRY_COMPARE(listview->contentY(), 0.0); else QTRY_COMPARE(listview->contentY(), -listview->height()); - QVERIFY(listview->currentIndex() == -1); + QCOMPARE(listview->currentIndex(), -1); QCOMPARE(listview->contentHeight(), 0.0); // confirm sanity when adding an item to cleared list model.addItem("New", "1"); listview->forceLayout(); - QTRY_VERIFY(listview->count() == 1); + QTRY_COMPARE(listview->count(), 1); QVERIFY(listview->currentItem() != 0); - QVERIFY(listview->currentIndex() == 0); + QCOMPARE(listview->currentIndex(), 0); delete window; delete testObject; @@ -1805,7 +1828,7 @@ void tst_QQuickListView::swapWithFirstItem() // ensure content position is stable listview->setContentY(0); model.moveItem(1, 0); - QTRY_VERIFY(listview->contentY() == 0); + QTRY_COMPARE(listview->contentY(), qreal(0)); delete testObject; delete window; @@ -1943,11 +1966,11 @@ void tst_QQuickListView::spacing() QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QTRY_VERIFY(item); - QTRY_VERIFY(item->y() == i*20); + QTRY_COMPARE(item->y(), qreal(i*20)); } listview->setSpacing(10); - QTRY_VERIFY(listview->spacing() == 10); + QTRY_COMPARE(listview->spacing(), qreal(10)); // Confirm items positioned correctly QTRY_VERIFY(findItems<QQuickItem>(contentItem, "wrapper").count() == 11); @@ -1955,7 +1978,7 @@ void tst_QQuickListView::spacing() QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QTRY_VERIFY(item); - QTRY_VERIFY(item->y() == i*30); + QTRY_COMPARE(item->y(), qreal(i*30)); } listview->setSpacing(0); @@ -2261,7 +2284,7 @@ void tst_QQuickListView::sectionsDelegate_headerVisibility() listview->setCurrentIndex(20); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); QTRY_VERIFY(qFuzzyCompare(listview->contentY(), 200.0)); - QTRY_VERIFY(listview->isMoving() == false); + QTRY_VERIFY(!listview->isMoving()); listview->setCurrentIndex(0); QTRY_VERIFY(qFuzzyIsNull(listview->contentY())); @@ -2682,7 +2705,7 @@ void tst_QQuickListView::currentIndex() listview->setCurrentIndex(20); QTRY_VERIFY(listview->verticalVelocity() != 0.0); listview->setCurrentIndex(0); - QTRY_VERIFY(listview->verticalVelocity() == 0.0); + QTRY_COMPARE(listview->verticalVelocity(), 0.0); // footer should become visible if it is out of view, and then current index is set to count-1 window->rootObject()->setProperty("showFooter", true); @@ -2704,7 +2727,7 @@ void tst_QQuickListView::currentIndex() // turn off auto highlight listview->setHighlightFollowsCurrentItem(false); - QVERIFY(listview->highlightFollowsCurrentItem() == false); + QVERIFY(!listview->highlightFollowsCurrentItem()); QVERIFY(listview->highlightItem()); qreal hlPos = listview->highlightItem()->y(); @@ -2713,9 +2736,12 @@ void tst_QQuickListView::currentIndex() QTRY_COMPARE(listview->highlightItem()->y(), hlPos); // insert item before currentIndex + window->rootObject()->setProperty("currentItemChangedCount", QVariant(0)); listview->setCurrentIndex(28); + QTRY_COMPARE(window->rootObject()->property("currentItemChangedCount").toInt(), 1); model.insertItem(0, "Foo", "1111"); QTRY_COMPARE(window->rootObject()->property("current").toInt(), 29); + QCOMPARE(window->rootObject()->property("currentItemChangedCount").toInt(), 1); // check removing highlight by setting currentIndex to -1; listview->setCurrentIndex(-1); @@ -2808,7 +2834,7 @@ void tst_QQuickListView::keyNavigation() window->requestActivate(); QTest::qWaitForWindowActive(window); - QTRY_VERIFY(qGuiApp->focusWindow() == window); + QTRY_COMPARE(qGuiApp->focusWindow(), window); QTest::keyClick(window, forwardsKey); QCOMPARE(listview->currentIndex(), 1); @@ -2917,7 +2943,7 @@ void tst_QQuickListView::itemList() QQmlObjectModel *model = window->rootObject()->findChild<QQmlObjectModel*>("itemModel"); QTRY_VERIFY(model != 0); - QTRY_VERIFY(model->count() == 3); + QTRY_COMPARE(model->count(), 3); QTRY_COMPARE(listview->currentIndex(), 0); QQuickItem *item = findItem<QQuickItem>(contentItem, "item1"); @@ -2958,7 +2984,7 @@ void tst_QQuickListView::itemListFlicker() QQmlObjectModel *model = window->rootObject()->findChild<QQmlObjectModel*>("itemModel"); QTRY_VERIFY(model != 0); - QTRY_VERIFY(model->count() == 3); + QTRY_COMPARE(model->count(), 3); QTRY_COMPARE(listview->currentIndex(), 0); QQuickItem *item; @@ -3024,14 +3050,14 @@ void tst_QQuickListView::cacheBuffer() QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QTRY_VERIFY(item); - QTRY_VERIFY(item->y() == i*20); + QTRY_COMPARE(item->y(), qreal(i*20)); } QQmlIncubationController controller; window->engine()->setIncubationController(&controller); testObject->setCacheBuffer(200); - QTRY_VERIFY(listview->cacheBuffer() == 200); + QTRY_COMPARE(listview->cacheBuffer(), 200); // items will be created one at a time for (int i = itemCount; i < qMin(itemCount+10,model.count()); ++i) { @@ -3057,7 +3083,7 @@ void tst_QQuickListView::cacheBuffer() QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QTRY_VERIFY(item); - QTRY_VERIFY(item->y() == i*20); + QTRY_COMPARE(item->y(), qreal(i*20)); } // move view and confirm items in view are visible immediately and outside are created async @@ -3067,7 +3093,7 @@ void tst_QQuickListView::cacheBuffer() QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QVERIFY(item); - QVERIFY(item->y() == i*20); + QCOMPARE(item->y(), qreal(i*20)); } QVERIFY(findItem<QQuickItem>(listview, "wrapper", 32) == 0); @@ -3528,7 +3554,7 @@ void tst_QQuickListView::QTBUG_11105() QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QTRY_VERIFY(item); - QTRY_VERIFY(item->y() == i*20); + QTRY_COMPARE(item->y(), qreal(i*20)); } listview->positionViewAtIndex(20, QQuickListView::Beginning); @@ -3622,7 +3648,7 @@ void tst_QQuickListView::header() QQuickText *header = 0; QTRY_VERIFY(header = findItem<QQuickText>(contentItem, "header")); - QVERIFY(header == listview->headerItem()); + QCOMPARE(header, listview->headerItem()); QCOMPARE(header->width(), 100.); QCOMPARE(header->height(), 30.); @@ -3660,7 +3686,7 @@ void tst_QQuickListView::header() header = findItem<QQuickText>(contentItem, "header2"); QVERIFY(header); - QVERIFY(header == listview->headerItem()); + QCOMPARE(header, listview->headerItem()); QCOMPARE(header->position(), changedHeaderPos); QCOMPARE(header->width(), 50.); @@ -3811,7 +3837,7 @@ void tst_QQuickListView::headerChangesViewport() QQuickText *header = 0; QTRY_VERIFY(header = findItem<QQuickText>(contentItem, "header")); - QVERIFY(header == listview->headerItem()); + QCOMPARE(header, listview->headerItem()); QCOMPARE(header->height(), 20.); QCOMPARE(listview->contentHeight(), 20.); @@ -3862,7 +3888,7 @@ void tst_QQuickListView::footer() QQuickText *footer = findItem<QQuickText>(contentItem, "footer"); QVERIFY(footer); - QVERIFY(footer == listview->footerItem()); + QCOMPARE(footer, listview->footerItem()); QCOMPARE(footer->position(), initialFooterPos); QCOMPARE(footer->width(), 100.); @@ -3922,7 +3948,7 @@ void tst_QQuickListView::footer() footer = findItem<QQuickText>(contentItem, "footer2"); QVERIFY(footer); - QVERIFY(footer == listview->footerItem()); + QCOMPARE(footer, listview->footerItem()); QCOMPARE(footer->position(), changedFooterPos); QCOMPARE(footer->width(), 50.); @@ -4155,11 +4181,11 @@ void tst_QQuickListView::resetModel_headerFooter() // A reset should not force a new header or footer to be created. QQuickItem *newHeader = findItem<QQuickItem>(contentItem, "header"); - QVERIFY(newHeader == header); + QCOMPARE(newHeader, header); QCOMPARE(header->y(), -header->height()); QQuickItem *newFooter = findItem<QQuickItem>(contentItem, "footer"); - QVERIFY(newFooter == footer); + QCOMPARE(newFooter, footer); QCOMPARE(footer->y(), 30.*4); delete window; @@ -4664,7 +4690,7 @@ void tst_QQuickListView::indexAt_itemAt() QVERIFY(item); } QCOMPARE(listview->indexAt(x,y), index); - QVERIFY(listview->itemAt(x,y) == item); + QCOMPARE(listview->itemAt(x,y), item); releaseView(window); delete testObject; @@ -4828,7 +4854,7 @@ void tst_QQuickListView::rightToLeft() QQmlObjectModel *model = window->rootObject()->findChild<QQmlObjectModel*>("itemModel"); QTRY_VERIFY(model != 0); - QTRY_VERIFY(model->count() == 3); + QTRY_COMPARE(model->count(), 3); QTRY_COMPARE(listview->currentIndex(), 0); // initial position at first item, right edge aligned @@ -4893,7 +4919,7 @@ void tst_QQuickListView::test_mirroring() foreach (const QString objectName, objectNames) QCOMPARE(findItem<QQuickItem>(listviewA, objectName)->x(), findItem<QQuickItem>(listviewB, objectName)->x()); - QVERIFY(listviewB->layoutDirection() == listviewB->effectiveLayoutDirection()); + QCOMPARE(listviewB->layoutDirection(), listviewB->effectiveLayoutDirection()); QQuickItemPrivate::get(listviewB)->setLayoutMirror(true); QVERIFY(listviewB->layoutDirection() != listviewB->effectiveLayoutDirection()); @@ -5034,7 +5060,7 @@ void tst_QQuickListView::marginsResize() // flick past the end and check content pos still settles on correct extents flick(window, flickStart, flickEnd, 180); - QTRY_VERIFY(listview->isMoving() == false); + QTRY_VERIFY(!listview->isMoving()); if (orientation == QQuickListView::Vertical) QTRY_COMPARE(listview->contentY(), end); else @@ -5049,7 +5075,7 @@ void tst_QQuickListView::marginsResize() // flick past the beginning and check content pos still settles on correct extents flick(window, flickEnd, flickStart, 180); - QTRY_VERIFY(listview->isMoving() == false); + QTRY_VERIFY(!listview->isMoving()); if (orientation == QQuickListView::Vertical) QTRY_COMPARE(listview->contentY(), start); else @@ -5199,6 +5225,37 @@ void tst_QQuickListView::snapToItem() releaseView(window); } +void tst_QQuickListView::snapOneItemResize_QTBUG_43555() +{ + QQuickView *window = createView(); + window->resize(QSize(100, 320)); + window->setResizeMode(QQuickView::SizeRootObjectToView); + QQuickViewTestUtil::moveMouseAway(window); + + window->setSource(testFileUrl("snapOneItemResize.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickListView *listview = qobject_cast<QQuickListView*>(window->rootObject()); + QTRY_VERIFY(listview != 0); + + QSignalSpy currentIndexSpy(listview, SIGNAL(currentIndexChanged())); + + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QTRY_COMPARE(listview->currentIndex(), 5); + currentIndexSpy.clear(); + + window->resize(QSize(400, 320)); + + QTRY_COMPARE(int(listview->width()), 400); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + + QTRY_COMPARE(listview->currentIndex(), 5); + QCOMPARE(currentIndexSpy.count(), 0); + + delete window; +} + void tst_QQuickListView::qAbstractItemModel_package_items() { items<QaimModel>(testFileUrl("listviewtest-package.qml")); @@ -5546,6 +5603,32 @@ void tst_QQuickListView::snapOneItem() releaseView(window); } +void tst_QQuickListView::snapOneItemCurrentIndexRemoveAnimation() +{ + QQuickView *window = createView(); + + window->setSource(testFileUrl("snapOneItemCurrentIndexRemoveAnimation.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickListView *listview = qobject_cast<QQuickListView*>(window->rootObject()); + QTRY_VERIFY(listview != 0); + + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + QTRY_COMPARE(listview->currentIndex(), 0); + QSignalSpy currentIndexSpy(listview, SIGNAL(currentIndexChanged())); + + QMetaObject::invokeMethod(window->rootObject(), "removeItemZero"); + QTRY_COMPARE(listview->property("transitionsRun").toInt(), 1); + + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + + QCOMPARE(listview->currentIndex(), 0); + QCOMPARE(currentIndexSpy.count(), 0); + + delete window; +} + void tst_QQuickListView::attachedProperties_QTBUG_32836() { QQuickView *window = createView(); @@ -7006,7 +7089,7 @@ void tst_QQuickListView::matchIndexLists(const QVariantList &indexLists, const Q void tst_QQuickListView::matchItemsAndIndexes(const QVariantMap &items, const QaimModel &model, const QList<int> &expectedIndexes) { for (QVariantMap::const_iterator it = items.begin(); it != items.end(); ++it) { - QVERIFY(it.value().type() == QVariant::Int); + QCOMPARE(it.value().type(), QVariant::Int); QString name = it.key(); int itemIndex = it.value().toInt(); QVERIFY2(expectedIndexes.contains(itemIndex), QTest::toString(QString("Index %1 not found in expectedIndexes").arg(itemIndex))); @@ -7020,7 +7103,7 @@ void tst_QQuickListView::matchItemsAndIndexes(const QVariantMap &items, const Qa void tst_QQuickListView::matchItemLists(const QVariantList &itemLists, const QList<QQuickItem *> &expectedItems) { for (int i=0; i<itemLists.count(); i++) { - QVERIFY(itemLists[i].type() == QVariant::List); + QCOMPARE(itemLists[i].type(), QVariant::List); QVariantList current = itemLists[i].toList(); for (int j=0; j<current.count(); j++) { QQuickItem *o = qobject_cast<QQuickItem*>(current[j].value<QObject*>()); @@ -7062,7 +7145,7 @@ void tst_QQuickListView::flickBeyondBounds() QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QTRY_VERIFY(item); - QTRY_VERIFY(item->y() == i*45); + QTRY_COMPARE(item->y(), qreal(i*45)); } delete window; @@ -7398,7 +7481,7 @@ void tst_QQuickListView::stickyPositioning() QFETCH(QPointF, headerPos); QFETCH(QPointF, footerPos); - QQuickView *window = createView(); + QQuickView *window = getView(); QaimModel model; for (int i = 0; i < 20; i++) @@ -7441,7 +7524,7 @@ void tst_QQuickListView::stickyPositioning() QCOMPARE(actualPos, footerPos); } - delete window; + releaseView(window); } void tst_QQuickListView::stickyPositioning_data() @@ -7468,7 +7551,7 @@ void tst_QQuickListView::stickyPositioning_data() QTest::newRow("top header") << "stickyPositioning-header.qml" << Qt::Vertical << Qt::LeftToRight << QQuickListView::TopToBottom << 0 << QQuickItemView::Beginning << QList<QPointF>() - << QPointF(0,-10) << QPointF(); + << QPointF(0,0) << QPointF(); QTest::newRow("top header: 1/2 up") << "stickyPositioning-header.qml" << Qt::Vertical << Qt::LeftToRight << QQuickListView::TopToBottom @@ -7495,7 +7578,7 @@ void tst_QQuickListView::stickyPositioning_data() QTest::newRow("top footer") << "stickyPositioning-footer.qml" << Qt::Vertical << Qt::LeftToRight << QQuickListView::BottomToTop << 19 << QQuickItemView::End << QList<QPointF>() - << QPointF() << QPointF(0,-10); + << QPointF() << QPointF(0,0); QTest::newRow("top footer: 1/2 up") << "stickyPositioning-footer.qml" << Qt::Vertical << Qt::LeftToRight << QQuickListView::BottomToTop @@ -7522,7 +7605,7 @@ void tst_QQuickListView::stickyPositioning_data() QTest::newRow("bottom header") << "stickyPositioning-header.qml" << Qt::Vertical << Qt::LeftToRight << QQuickListView::BottomToTop << 0 << QQuickItemView::Beginning << QList<QPointF>() - << QPointF(0,100) << QPointF(); + << QPointF(0,90) << QPointF(); QTest::newRow("bottom header: 1/2 down") << "stickyPositioning-header.qml" << Qt::Vertical << Qt::LeftToRight << QQuickListView::BottomToTop @@ -7549,7 +7632,7 @@ void tst_QQuickListView::stickyPositioning_data() QTest::newRow("bottom footer") << "stickyPositioning-footer.qml" << Qt::Vertical << Qt::LeftToRight << QQuickListView::TopToBottom << 19 << QQuickItemView::End << QList<QPointF>() - << QPointF() << QPointF(0,100); + << QPointF() << QPointF(0,90); QTest::newRow("bottom footer: 1/2 down") << "stickyPositioning-footer.qml" << Qt::Vertical << Qt::LeftToRight << QQuickListView::TopToBottom @@ -7576,7 +7659,7 @@ void tst_QQuickListView::stickyPositioning_data() QTest::newRow("top header & bottom footer") << "stickyPositioning-both.qml" << Qt::Vertical << Qt::LeftToRight << QQuickListView::TopToBottom << 0 << QQuickItemView::Beginning << QList<QPointF>() - << QPointF(0,-10) << QPointF(0,90); + << QPointF(0,0) << QPointF(0,100); QTest::newRow("top header & bottom footer: 1/2 up") << "stickyPositioning-both.qml" << Qt::Vertical << Qt::LeftToRight << QQuickListView::TopToBottom @@ -7629,7 +7712,7 @@ void tst_QQuickListView::stickyPositioning_data() QTest::newRow("left header") << "stickyPositioning-header.qml" << Qt::Horizontal << Qt::LeftToRight << QQuickListView::TopToBottom << 0 << QQuickItemView::Beginning << QList<QPointF>() - << QPointF(-10,0) << QPointF(); + << QPointF(0,0) << QPointF(); QTest::newRow("left header: 1/2 left") << "stickyPositioning-header.qml" << Qt::Horizontal << Qt::LeftToRight << QQuickListView::TopToBottom @@ -7656,7 +7739,7 @@ void tst_QQuickListView::stickyPositioning_data() QTest::newRow("left footer") << "stickyPositioning-footer.qml" << Qt::Horizontal << Qt::RightToLeft << QQuickListView::TopToBottom << 19 << QQuickItemView::End << QList<QPointF>() - << QPointF() << QPointF(-10,0); + << QPointF() << QPointF(0,0); QTest::newRow("left footer: 1/2 left") << "stickyPositioning-footer.qml" << Qt::Horizontal << Qt::RightToLeft << QQuickListView::TopToBottom @@ -7683,7 +7766,7 @@ void tst_QQuickListView::stickyPositioning_data() QTest::newRow("right header") << "stickyPositioning-header.qml" << Qt::Horizontal << Qt::RightToLeft << QQuickListView::TopToBottom << 0 << QQuickItemView::Beginning << QList<QPointF>() - << QPointF(100,0) << QPointF(); + << QPointF(90,0) << QPointF(); QTest::newRow("right header: 1/2 right") << "stickyPositioning-header.qml" << Qt::Horizontal << Qt::RightToLeft << QQuickListView::TopToBottom @@ -7710,7 +7793,7 @@ void tst_QQuickListView::stickyPositioning_data() QTest::newRow("right footer") << "stickyPositioning-footer.qml" << Qt::Horizontal << Qt::LeftToRight << QQuickListView::TopToBottom << 19 << QQuickItemView::End << QList<QPointF>() - << QPointF() << QPointF(100,0); + << QPointF() << QPointF(90,0); QTest::newRow("right footer: 1/2 right") << "stickyPositioning-footer.qml" << Qt::Horizontal << Qt::LeftToRight << QQuickListView::TopToBottom @@ -7737,7 +7820,7 @@ void tst_QQuickListView::stickyPositioning_data() QTest::newRow("left header & right footer") << "stickyPositioning-both.qml" << Qt::Horizontal << Qt::LeftToRight << QQuickListView::TopToBottom << 0 << QQuickItemView::Beginning << QList<QPointF>() - << QPointF(-10,0) << QPointF(90,0); + << QPointF(0,0) << QPointF(100,0); QTest::newRow("left header & right footer: 1/2 left") << "stickyPositioning-both.qml" << Qt::Horizontal << Qt::LeftToRight << QQuickListView::TopToBottom @@ -7856,7 +7939,7 @@ void tst_QQuickListView::QTBUG_38209() // simulate mouse flick flick(window.data(), QPoint(200, 200), QPoint(200, 50), 100); - QTRY_VERIFY(listview->isMoving() == false); + QTRY_VERIFY(!listview->isMoving()); qreal contentY = listview->contentY(); // flick down @@ -8063,6 +8146,328 @@ void tst_QQuickListView::jsArrayChange() QCOMPARE(spy.count(), 1); } +static bool compareObjectModel(QQuickListView *listview, QQmlObjectModel *model) +{ + if (listview->count() != model->count()) + return false; + for (int i = 0; i < listview->count(); ++i) { + listview->setCurrentIndex(i); + if (listview->currentItem() != model->get(i)) + return false; + } + return true; +} + +void tst_QQuickListView::objectModel() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("objectmodel.qml")); + + QQuickListView *listview = qobject_cast<QQuickListView *>(component.create()); + QVERIFY(listview); + + QQmlObjectModel *model = listview->model().value<QQmlObjectModel *>(); + QVERIFY(model); + + listview->setCurrentIndex(0); + QVERIFY(listview->currentItem()); + QCOMPARE(listview->currentItem()->property("color").toString(), QColor("red").name()); + + listview->setCurrentIndex(1); + QVERIFY(listview->currentItem()); + QCOMPARE(listview->currentItem()->property("color").toString(), QColor("green").name()); + + listview->setCurrentIndex(2); + QVERIFY(listview->currentItem()); + QCOMPARE(listview->currentItem()->property("color").toString(), QColor("blue").name()); + + QQuickItem *item0 = new QQuickItem(listview); + item0->setSize(QSizeF(20, 20)); + model->append(item0); + QCOMPARE(model->count(), 4); + QVERIFY(compareObjectModel(listview, model)); + + QQuickItem *item1 = new QQuickItem(listview); + item1->setSize(QSizeF(20, 20)); + model->insert(0, item1); + QCOMPARE(model->count(), 5); + QVERIFY(compareObjectModel(listview, model)); + + model->move(1, 2, 3); + QVERIFY(compareObjectModel(listview, model)); + + model->remove(2, 2); + QCOMPARE(model->count(), 3); + QVERIFY(compareObjectModel(listview, model)); + + model->clear(); + QCOMPARE(model->count(), 0); + QCOMPARE(listview->count(), 0); + + delete listview; +} + +void tst_QQuickListView::contentHeightWithDelayRemove_data() +{ + QTest::addColumn<bool>("useDelayRemove"); + QTest::addColumn<QByteArray>("removeFunc"); + QTest::addColumn<int>("countDelta"); + QTest::addColumn<qreal>("contentHeightDelta"); + + QTest::newRow("remove without delayRemove") + << false + << QByteArray("takeOne") + << -1 + << qreal(-1 * 100.0); + + QTest::newRow("remove with delayRemove") + << true + << QByteArray("takeOne") + << -1 + << qreal(-1 * 100.0); + + QTest::newRow("remove with multiple delayRemove") + << true + << QByteArray("takeThree") + << -3 + << qreal(-3 * 100.0); + + QTest::newRow("clear with delayRemove") + << true + << QByteArray("takeAll") + << -5 + << qreal(-5 * 100.0); +} + +void tst_QQuickListView::contentHeightWithDelayRemove() +{ + QFETCH(bool, useDelayRemove); + QFETCH(QByteArray, removeFunc); + QFETCH(int, countDelta); + QFETCH(qreal, contentHeightDelta); + + QQuickView *window = createView(); + window->setSource(testFileUrl("contentHeightWithDelayRemove.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickListView *listview = window->rootObject()->findChild<QQuickListView*>(); + QTRY_VERIFY(listview != 0); + + const int initialCount(listview->count()); + const int eventualCount(initialCount + countDelta); + + const qreal initialContentHeight(listview->contentHeight()); + const int eventualContentHeight(qRound(initialContentHeight + contentHeightDelta)); + + listview->setProperty("useDelayRemove", useDelayRemove); + QMetaObject::invokeMethod(window->rootObject(), removeFunc.constData()); + QTest::qWait(50); + QCOMPARE(listview->count(), eventualCount); + + if (useDelayRemove) { + QCOMPARE(qRound(listview->contentHeight()), qRound(initialContentHeight)); + QTRY_COMPARE(qRound(listview->contentHeight()), eventualContentHeight); + } else { + QCOMPARE(qRound(listview->contentHeight()), eventualContentHeight); + } + + delete window; +} + +void tst_QQuickListView::QTBUG_48044_currentItemNotVisibleAfterTransition() +{ + QQuickView *window = createView(); + window->setSource(testFileUrl("qtbug48044.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickListView *listview = window->rootObject()->findChild<QQuickListView*>(); + QTRY_VERIFY(listview != 0); + + // Expand 2nd header + listview->setProperty("transitionsDone", QVariant(false)); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, 75)); + QTRY_VERIFY(listview->property("transitionsDone").toBool()); + + // Flick listview to the bottom + flick(window, QPoint(window->width() / 2, 400), QPoint(window->width() / 2, 0), 100); + QTRY_VERIFY(!listview->isMoving()); + + // Expand 3rd header + listview->setProperty("transitionsDone", QVariant(false)); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() - 25)); + QTRY_VERIFY(listview->property("transitionsDone").toBool()); + + // Check current item is what we expect + QCOMPARE(listview->currentIndex(), 2); + QQuickItem *currentItem = listview->currentItem(); + QVERIFY(currentItem); + QVERIFY(currentItem->isVisible()); + + // This is the actual test + QQuickItemPrivate *currentPriv = QQuickItemPrivate::get(currentItem); + QVERIFY(!currentPriv->culled); +} + +static bool testVisibleItems(const QQuickItemViewPrivate *priv, bool *nonUnique, FxViewItem **failItem, int *expectedIdx) +{ + QHash<QQuickItem*, int> uniqueItems; + + int skip = 0; + for (int i = 0; i < priv->visibleItems.count(); ++i) { + FxViewItem *item = priv->visibleItems.at(i); + if (!item) { + *failItem = Q_NULLPTR; + return false; + } +#if 0 + qDebug() << "\t" << item->index + << item->item + << item->position() + << (!item->item || QQuickItemPrivate::get(item->item)->culled ? "hidden" : "visible"); +#endif + if (item->index == -1) { + ++skip; + } else if (item->index != priv->visibleIndex + i - skip) { + *nonUnique = false; + *failItem = item; + *expectedIdx = priv->visibleIndex + i - skip; + return false; + } else if (uniqueItems.contains(item->item)) { + *nonUnique = true; + *failItem = item; + *expectedIdx = uniqueItems.find(item->item).value(); + return false; + } + + uniqueItems.insert(item->item, item->index); + } + + return true; +} + +class QTBUG_48870_Model : public QAbstractListModel +{ + Q_OBJECT + +public: + + QTBUG_48870_Model() + : QAbstractListModel() + , m_rowCount(20) + { + QTimer *t = new QTimer(this); + t->setInterval(500); + t->start(); + + qsrand(qHash(QDateTime::currentDateTime())); + connect(t, &QTimer::timeout, this, &QTBUG_48870_Model::updateModel); + } + + int rowCount(const QModelIndex &) const + { + return m_rowCount; + } + + QVariant data(const QModelIndex &, int) const + { + return QVariant(); + } + +public Q_SLOTS: + void updateModel() + { + if (m_rowCount > 10) { + for (int i = 0; i < 10; ++i) { + int rnum = qrand() % m_rowCount; + beginRemoveRows(QModelIndex(), rnum, rnum); + m_rowCount--; + endRemoveRows(); + } + } + if (m_rowCount < 20) { + for (int i = 0; i < 10; ++i) { + int rnum = qrand() % m_rowCount; + beginInsertRows(QModelIndex(), rnum, rnum); + m_rowCount++; + endInsertRows(); + } + } + } + +private: + int m_rowCount; +}; + +void tst_QQuickListView::QTBUG_48870_fastModelUpdates() +{ + QTBUG_48870_Model model; + + QQuickView *window = createView(); + QVERIFY(window); + QQmlContext *ctxt = window->rootContext(); + QVERIFY(ctxt); + ctxt->setContextProperty("testModel", &model); + + window->setSource(testFileUrl("qtbug48870.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItemViewPrivate *priv = QQuickItemViewPrivate::get(listview); + bool nonUnique; + FxViewItem *item = Q_NULLPTR; + int expectedIdx; + QVERIFY(testVisibleItems(priv, &nonUnique, &item, &expectedIdx)); + + for (int i = 0; i < 10; i++) { + QTest::qWait(100); + QVERIFY2(testVisibleItems(priv, &nonUnique, &item, &expectedIdx), + qPrintable(!item ? QString("Unexpected null item") + : nonUnique ? QString("Non-unique item at %1 and %2").arg(item->index).arg(expectedIdx) + : QString("Found index %1, expected index is %3").arg(item->index).arg(expectedIdx))); + if (i % 3 != 0) { + if (i & 1) + flick(window, QPoint(100, 200), QPoint(100, 0), 100); + else + flick(window, QPoint(100, 200), QPoint(100, 400), 100); + } + } + + delete window; +} + +// infinite loop in overlay header positioning due to undesired rounding in QQuickFlickablePrivate::fixup() +void tst_QQuickListView::QTBUG_50105() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("qtbug50105.qml")); + + QScopedPointer<QQuickWindow> window(qobject_cast<QQuickWindow *>(component.create())); + QVERIFY(window.data()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); +} + +void tst_QQuickListView::QTBUG_50097_stickyHeader_positionViewAtIndex() +{ + QQuickView *window = createView(); + window->setSource(testFileUrl("qtbug50097.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickListView *listview = qobject_cast<QQuickListView*>(window->rootObject()); + QVERIFY(listview != 0); + QTRY_COMPARE(listview->contentY(), -100.0); // the header size, since the header is overlaid + listview->setProperty("currentPage", 2); + QTRY_COMPARE(listview->contentY(), 400.0); // a full page of items down, sans the original negative header position + listview->setProperty("currentPage", 1); + QTRY_COMPARE(listview->contentY(), -100.0); // back to the same position: header visible, items not under the header. +} + QTEST_MAIN(tst_QQuickListView) #include "tst_qquicklistview.moc" diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp index 3dd2551d9d..f4fab1d79f 100644 --- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp +++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp @@ -236,7 +236,7 @@ void tst_QQuickLoader::clear() QCOMPARE(loader->progress(), 1.0); QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1); - QTRY_VERIFY(loader->item() == 0); + QTRY_VERIFY(!loader->item()); QCOMPARE(loader->progress(), 0.0); QCOMPARE(loader->status(), QQuickLoader::Null); QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 0); @@ -256,7 +256,7 @@ void tst_QQuickLoader::clear() loader->setSourceComponent(0); - QVERIFY(loader->item() == 0); + QVERIFY(!loader->item()); QCOMPARE(loader->progress(), 0.0); QCOMPARE(loader->status(), QQuickLoader::Null); QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 0); @@ -276,7 +276,7 @@ void tst_QQuickLoader::clear() QMetaObject::invokeMethod(item, "clear"); - QVERIFY(loader->item() == 0); + QVERIFY(!loader->item()); QCOMPARE(loader->progress(), 0.0); QCOMPARE(loader->status(), QQuickLoader::Null); QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 0); @@ -435,9 +435,7 @@ void tst_QQuickLoader::noResize() void tst_QQuickLoader::networkRequestUrl() { - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(dataDirectory()); + ThreadedTestHTTPServer server(dataDirectory()); QQmlComponent component(&engine); const QString qml = "import QtQuick 2.0\nLoader { property int signalCount : 0; source: \"" + server.baseUrl().toString() + "/Rect120x60.qml\"; onLoaded: signalCount += 1 }"; @@ -447,7 +445,7 @@ void tst_QQuickLoader::networkRequestUrl() QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create()); QVERIFY(loader != 0); - QTRY_VERIFY(loader->status() == QQuickLoader::Ready); + QTRY_COMPARE(loader->status(), QQuickLoader::Ready); QVERIFY(loader->item()); QCOMPARE(loader->progress(), 1.0); @@ -460,9 +458,7 @@ void tst_QQuickLoader::networkRequestUrl() /* XXX Component waits until all dependencies are loaded. Is this actually possible? */ void tst_QQuickLoader::networkComponent() { - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(dataDirectory(), TestHTTPServer::Delay); + ThreadedTestHTTPServer server(dataDirectory(), TestHTTPServer::Delay); QQmlComponent component(&engine); const QString qml = "import QtQuick 2.0\n" @@ -471,8 +467,9 @@ void tst_QQuickLoader::networkComponent() " Component { id: comp; NW.Rect120x60 {} }\n" " Loader { sourceComponent: comp } }"; component.setData(qml.toUtf8(), dataDirectory()); - QCOMPARE(component.status(), QQmlComponent::Loading); - server.sendDelayedItem(); + // The component may be loaded synchronously or asynchronously, so we cannot test for + // status == Loading here. Also, it makes no sense to instruct the server to send here + // because in the synchronous case we're already done loading. QTRY_COMPARE(component.status(), QQmlComponent::Ready); QQuickItem *item = qobject_cast<QQuickItem*>(component.create()); @@ -480,7 +477,7 @@ void tst_QQuickLoader::networkComponent() QQuickLoader *loader = qobject_cast<QQuickLoader*>(item->children().at(1)); QVERIFY(loader); - QTRY_VERIFY(loader->status() == QQuickLoader::Ready); + QTRY_COMPARE(loader->status(), QQuickLoader::Ready); QVERIFY(loader->item()); QCOMPARE(loader->progress(), 1.0); @@ -492,9 +489,7 @@ void tst_QQuickLoader::networkComponent() void tst_QQuickLoader::failNetworkRequest() { - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(dataDirectory()); + ThreadedTestHTTPServer server(dataDirectory()); QTest::ignoreMessage(QtWarningMsg, QString(server.baseUrl().toString() + "/IDontExist.qml: File not found").toUtf8()); @@ -505,9 +500,9 @@ void tst_QQuickLoader::failNetworkRequest() QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create()); QVERIFY(loader != 0); - QTRY_VERIFY(loader->status() == QQuickLoader::Error); + QTRY_COMPARE(loader->status(), QQuickLoader::Error); - QVERIFY(loader->item() == 0); + QVERIFY(!loader->item()); QCOMPARE(loader->progress(), 1.0); QCOMPARE(loader->property("did_load").toInt(), 123); QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 0); @@ -525,11 +520,11 @@ void tst_QQuickLoader::active() QQuickLoader *loader = object->findChild<QQuickLoader*>("loader"); QVERIFY(loader->active() == false); // set manually to false - QVERIFY(loader->item() == 0); + QVERIFY(!loader->item()); QMetaObject::invokeMethod(object, "doSetSourceComponent"); - QVERIFY(loader->item() == 0); + QVERIFY(!loader->item()); QMetaObject::invokeMethod(object, "doSetSource"); - QVERIFY(loader->item() == 0); + QVERIFY(!loader->item()); QMetaObject::invokeMethod(object, "doSetActive"); QVERIFY(loader->item() != 0); @@ -598,7 +593,7 @@ void tst_QQuickLoader::active() QVERIFY(loader->item() != 0); int currItemChangedCount = loader->property("itemChangedCount").toInt(); QMetaObject::invokeMethod(object, "doSetInactive"); - QVERIFY(loader->item() == 0); + QVERIFY(!loader->item()); QCOMPARE(loader->property("itemChangedCount").toInt(), (currItemChangedCount+1)); delete object; @@ -708,9 +703,7 @@ void tst_QQuickLoader::initialPropertyValues() QFETCH(QStringList, propertyNames); QFETCH(QVariantList, propertyValues); - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(dataDirectory()); + ThreadedTestHTTPServer server(dataDirectory()); foreach (const QString &warning, expectedWarnings) QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); @@ -781,7 +774,7 @@ void tst_QQuickLoader::initialPropertyValuesError() QVERIFY(object != 0); QQuickLoader *loader = object->findChild<QQuickLoader*>("loader"); QVERIFY(loader != 0); - QVERIFY(loader->item() == 0); + QVERIFY(!loader->item()); delete object; } @@ -803,7 +796,7 @@ void tst_QQuickLoader::deleteComponentCrash() QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); QCoreApplication::processEvents(); QTRY_COMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1); - QVERIFY(loader->source() == testFileUrl("BlueRect.qml")); + QCOMPARE(loader->source(), testFileUrl("BlueRect.qml")); delete item; } @@ -833,7 +826,7 @@ void tst_QQuickLoader::vmeErrors() QTest::ignoreMessage(QtWarningMsg, err.toLatin1().constData()); QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create()); QVERIFY(loader); - QVERIFY(loader->item() == 0); + QVERIFY(!loader->item()); delete loader; } @@ -1098,7 +1091,7 @@ void tst_QQuickLoader::parented() QQuickItem *item = root->findChild<QQuickItem*>("comp"); QVERIFY(item); - QVERIFY(item->parentItem() == root); + QCOMPARE(item->parentItem(), root); QCOMPARE(item->width(), 300.); QCOMPARE(item->height(), 300.); diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp index 5bdc6f415a..82c053d76a 100644 --- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp +++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp @@ -169,7 +169,7 @@ void tst_QQuickMouseArea::dragProperties() // target QQuickItem *blackRect = window.rootObject()->findChild<QQuickItem*>("blackrect"); QVERIFY(blackRect != 0); - QVERIFY(blackRect == drag->target()); + QCOMPARE(blackRect, drag->target()); QQuickItem *rootItem = qobject_cast<QQuickItem*>(window.rootObject()); QVERIFY(rootItem != 0); QSignalSpy targetSpy(drag, SIGNAL(targetChanged())); @@ -267,14 +267,14 @@ void tst_QQuickMouseArea::resetDrag() // target QQuickItem *blackRect = window.rootObject()->findChild<QQuickItem*>("blackrect"); QVERIFY(blackRect != 0); - QVERIFY(blackRect == drag->target()); + QCOMPARE(blackRect, drag->target()); QQuickItem *rootItem = qobject_cast<QQuickItem*>(window.rootObject()); QVERIFY(rootItem != 0); QSignalSpy targetSpy(drag, SIGNAL(targetChanged())); QVERIFY(drag->target() != 0); window.rootContext()->setContextProperty("haveTarget", QVariant(false)); QCOMPARE(targetSpy.count(),1); - QVERIFY(drag->target() == 0); + QVERIFY(!drag->target()); } void tst_QQuickMouseArea::dragging() @@ -300,7 +300,7 @@ void tst_QQuickMouseArea::dragging() // target QQuickItem *blackRect = window.rootObject()->findChild<QQuickItem*>("blackrect"); QVERIFY(blackRect != 0); - QVERIFY(blackRect == drag->target()); + QCOMPARE(blackRect, drag->target()); QVERIFY(!drag->active()); @@ -347,7 +347,7 @@ void tst_QQuickMouseArea::dragSmoothed() mouseRegion->setAcceptedButtons(Qt::LeftButton); QQuickItem *blackRect = window.rootObject()->findChild<QQuickItem*>("blackrect"); QVERIFY(blackRect != 0); - QVERIFY(blackRect == drag->target()); + QCOMPARE(blackRect, drag->target()); QVERIFY(!drag->active()); QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100)); QVERIFY(!drag->active()); @@ -393,7 +393,7 @@ void tst_QQuickMouseArea::dragThreshold() mouseRegion->setAcceptedButtons(Qt::LeftButton); QQuickItem *blackRect = window.rootObject()->findChild<QQuickItem*>("blackrect"); QVERIFY(blackRect != 0); - QVERIFY(blackRect == drag->target()); + QCOMPARE(blackRect, drag->target()); QVERIFY(!drag->active()); QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100)); QVERIFY(!drag->active()); @@ -451,7 +451,7 @@ void tst_QQuickMouseArea::invalidDrag() // target QQuickItem *blackRect = window.rootObject()->findChild<QQuickItem*>("blackrect"); QVERIFY(blackRect != 0); - QVERIFY(blackRect == drag->target()); + QCOMPARE(blackRect, drag->target()); QVERIFY(!drag->active()); @@ -501,7 +501,7 @@ void tst_QQuickMouseArea::cancelDragging() // target QQuickItem *blackRect = window.rootObject()->findChild<QQuickItem*>("blackrect"); QVERIFY(blackRect != 0); - QVERIFY(blackRect == drag->target()); + QCOMPARE(blackRect, drag->target()); QVERIFY(!drag->active()); @@ -655,7 +655,7 @@ void tst_QQuickMouseArea::noOnClickedWithPressAndHold() QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); QGuiApplication::sendEvent(&window, &pressEvent); - QVERIFY(mouseArea->pressedButtons() == Qt::LeftButton); + QCOMPARE(mouseArea->pressedButtons(), Qt::LeftButton); QVERIFY(!window.rootObject()->property("clicked").toBool()); QVERIFY(!window.rootObject()->property("held").toBool()); @@ -1281,7 +1281,7 @@ void tst_QQuickMouseArea::disableAfterPress() // target QQuickItem *blackRect = window.rootObject()->findChild<QQuickItem*>("blackrect"); QVERIFY(blackRect != 0); - QVERIFY(blackRect == drag->target()); + QCOMPARE(blackRect, drag->target()); QVERIFY(!drag->active()); @@ -1574,7 +1574,7 @@ void tst_QQuickMouseArea::changeAxis() // target QQuickItem *blackRect = view.rootObject()->findChild<QQuickItem*>("blackrect"); QVERIFY(blackRect != 0); - QVERIFY(blackRect == drag->target()); + QCOMPARE(blackRect, drag->target()); QVERIFY(!drag->active()); diff --git a/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST b/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST new file mode 100644 index 0000000000..1777af9e0c --- /dev/null +++ b/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST @@ -0,0 +1,2 @@ +[inFlickable] +* diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp index e69ebfa8fe..4da4767d7b 100644 --- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp +++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp @@ -719,7 +719,7 @@ void tst_QQuickMultiPointTouchArea::inFlickable() QTest::mouseMove(window.data(), p1); QQuickTouchUtils::flush(window.data()); - QVERIFY(flickable->contentY() == 0); + QCOMPARE(flickable->contentY(), qreal(0)); QCOMPARE(point11->pressed(), true); QCOMPARE(point12->pressed(), true); @@ -1186,14 +1186,14 @@ void tst_QQuickMultiPointTouchArea::mouseInteraction() QPoint p1 = QPoint(100, 100); QTest::mousePress(view.data(), (Qt::MouseButton) buttons, 0, p1); QCOMPARE(area->property("touchCount").toInt(), accept); - QCOMPARE(point1->pressed(), accept); + QCOMPARE(point1->pressed(), accept != 0); p1 += QPoint(10, 10); QTest::mouseMove(view.data(), p1); - QCOMPARE(point1->pressed(), accept); + QCOMPARE(point1->pressed(), accept != 0); QCOMPARE(area->property("touchCount").toInt(), accept); p1 += QPoint(10, 10); QTest::mouseMove(view.data(), p1); - QCOMPARE(point1->pressed(), accept); + QCOMPARE(point1->pressed(), accept != 0); QCOMPARE(area->property("touchCount").toInt(), accept); QTest::mouseRelease(view.data(), (Qt::MouseButton) buttons); QCOMPARE(point1->pressed(), false); diff --git a/tests/auto/quick/qquickpathview/data/customAttribute.qml b/tests/auto/quick/qquickpathview/data/customAttribute.qml new file mode 100644 index 0000000000..bd4c9fd1de --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/customAttribute.qml @@ -0,0 +1,58 @@ +import QtQuick 2.4 + +PathView { + width: 200 + height: 600 + + pathItemCount: 7 + + model: ListModel { + ListElement { color: "salmon" } + ListElement { color: "seagreen" } + ListElement { color: "navy" } + ListElement { color: "goldenrod" } + } + path: Path { + startX: width / 2; startY: -100 + PathAttribute { name: "BEGIN" } + + PathLine { relativeX: 0; y: height / 2 } + PathAttribute { name: "BEGIN" } + + PathLine { relativeX: 0; y: height + 100 } + PathAttribute { name: "BEGIN" } + } + delegate: Rectangle { + width: 200 + height: 200 + color: model.color + opacity: PathView.transparency + } + + Component { + id: attributeComponent + PathAttribute {} + } + + function addAttribute(name, values) { + var valueIndex = 0 + var elements = [] + for (var i = 0; i < path.pathElements.length; ++i) { + elements.push(path.pathElements[i]) + + if (path.pathElements[i].name === "BEGIN") { + if (values[valueIndex] !== undefined) { + var attribute = attributeComponent.createObject(this, { "name": name, "value": values[valueIndex] }) + elements.push(attribute) + } + ++valueIndex + } + } + + console.log("??") + path.pathElements = elements + console.log("!!") + } + + Component.onCompleted: addAttribute("transparency", [0, 1, 0]) +} diff --git a/tests/auto/quick/qquickpathview/data/qtbug42716.qml b/tests/auto/quick/qquickpathview/data/qtbug42716.qml new file mode 100644 index 0000000000..81d52d5ea3 --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/qtbug42716.qml @@ -0,0 +1,111 @@ +import QtQuick 2.0 + +Rectangle { + //Note that this file was originally the manual reproduction, MouseAreas were left in. + id: qmlBrowser + + width: 500 + height: 350 + + ListModel { + id: myModel + ListElement { + name: "Bill Jones 0" + } + ListElement { + name: "Jane Doe 1" + } + ListElement { + name: "John Smith 2" + } + ListElement { + name: "Bill Jones 3" + } + ListElement { + name: "Jane Doe 4" + } + ListElement { + name: "John Smith 5" + } + ListElement { + name: "John Smith 6" + } + ListElement { + name: "John Smith 7" + } + } + + Component { + id: delegate + + Text { + id: nameText + height: 33 + width: parent.width + objectName: "delegate"+index + + text: "index: " + index + " text: " + name + font.pointSize: 16 + color: PathView.isCurrentItem ? "red" : "black" + } + } + + PathView { + id: contentList + objectName: "pathView" + anchors.fill: parent + + property int maxPathItemCount: 7 + property real itemHeight: 34 + + delegate: delegate + model: myModel + currentIndex: 5 + pathItemCount: maxPathItemCount + highlightMoveDuration: 0 + + path: Path { + startX: 30 + contentList.width / 2 + startY: 30 + PathLine { + relativeX: 0 + relativeY: contentList.itemHeight * contentList.maxPathItemCount + } + } + + focus: true + Keys.onLeftPressed: decrementCurrentIndex() + Keys.onRightPressed: incrementCurrentIndex() + } + + Column { + anchors.right: parent.right + Text { + text: "Go 1" + font.weight: Font.Bold + font.pixelSize: 24 + MouseArea { + anchors.fill: parent + onClicked: contentList.offset = 2.55882 + } + } + Text { + text: "Go 2" + font.weight: Font.Bold + font.pixelSize: 24 + MouseArea { + anchors.fill: parent + onClicked: contentList.offset = 0.0882353 + } + } + Text { + text: "Go 3" + font.weight: Font.Bold + font.pixelSize: 24 + MouseArea { + anchors.fill: parent + onClicked: contentList.offset = 0.99987 + } + } + } +} diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index 7db15522b5..fc5dd3bbca 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -140,6 +140,8 @@ private slots: void nestedinFlickable(); void flickableDelegate(); void jsArrayChange(); + void qtbug42716(); + void addCustomAttribute(); }; class TestObject : public QObject @@ -183,8 +185,8 @@ void tst_QQuickPathView::initValues() QQuickPathView *obj = qobject_cast<QQuickPathView*>(c.create()); QVERIFY(obj != 0); - QVERIFY(obj->path() == 0); - QVERIFY(obj->delegate() == 0); + QVERIFY(!obj->path()); + QVERIFY(!obj->delegate()); QCOMPARE(obj->model(), QVariant()); QCOMPARE(obj->currentIndex(), 0); QCOMPARE(obj->offset(), 0.); @@ -799,7 +801,7 @@ void tst_QQuickPathView::dataModel() QVERIFY(pathview != 0); QMetaObject::invokeMethod(window->rootObject(), "checkProperties"); - QVERIFY(testObject->error() == false); + QVERIFY(!testObject->error()); QQuickItem *item = findItem<QQuickItem>(pathview, "wrapper", 0); QVERIFY(item); @@ -828,14 +830,14 @@ void tst_QQuickPathView::dataModel() testObject->setPathItemCount(5); QMetaObject::invokeMethod(window->rootObject(), "checkProperties"); - QVERIFY(testObject->error() == false); + QVERIFY(!testObject->error()); QTRY_COMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), 5); QQuickRectangle *testItem = findItem<QQuickRectangle>(pathview, "wrapper", 4); QVERIFY(testItem != 0); testItem = findItem<QQuickRectangle>(pathview, "wrapper", 5); - QVERIFY(testItem == 0); + QVERIFY(!testItem); pathview->setCurrentIndex(1); QCOMPARE(pathview->currentIndex(), 1); @@ -1111,6 +1113,15 @@ void tst_QQuickPathView::setCurrentIndex() QCOMPARE(pathview->currentItem(), firstItem); QCOMPARE(firstItem->property("onPath"), QVariant(true)); + // check for bogus currentIndexChanged() signals + QSignalSpy currentIndexSpy(pathview, SIGNAL(currentIndexChanged())); + QVERIFY(currentIndexSpy.isValid()); + pathview->setHighlightMoveDuration(100); + pathview->setHighlightRangeMode(QQuickPathView::StrictlyEnforceRange); + pathview->setSnapMode(QQuickPathView::SnapToItem); + pathview->setCurrentIndex(3); + QTRY_COMPARE(pathview->currentIndex(), 3); + QCOMPARE(currentIndexSpy.count(), 1); } void tst_QQuickPathView::resetModel() @@ -1814,7 +1825,7 @@ void tst_QQuickPathView::cancelDrag() item->grabMouse(); // returns to a snap point. - QTRY_VERIFY(pathview->offset() == qFloor(pathview->offset())); + QTRY_COMPARE(pathview->offset(), qreal(qFloor(pathview->offset()))); QTRY_VERIFY(!pathview->isMoving()); QVERIFY(!pathview->isDragging()); QCOMPARE(draggingSpy.count(), 2); @@ -1897,7 +1908,7 @@ void tst_QQuickPathView::snapToItem() QVERIFY(pathview->isMoving()); QTRY_VERIFY_WITH_TIMEOUT(!pathview->isMoving(), 50000); - QVERIFY(pathview->offset() == qFloor(pathview->offset())); + QCOMPARE(pathview->offset(), qreal(qFloor(pathview->offset()))); if (enforceRange) QVERIFY(pathview->currentIndex() != currentIndex); @@ -2051,7 +2062,7 @@ void tst_QQuickPathView::indexAt_itemAt() QVERIFY(item); } QCOMPARE(pathview->indexAt(x,y), index); - QVERIFY(pathview->itemAt(x,y) == item); + QCOMPARE(pathview->itemAt(x,y), item); } @@ -2322,6 +2333,61 @@ void tst_QQuickPathView::jsArrayChange() QCOMPARE(spy.count(), 1); } +/* This bug was one where if you jump the list such that the sole missing item needed to be + * added in the middle of the list, it would instead move an item somewhere else in the list + * to the middle (messing it up very badly). + * + * The test checks correct visual order both before and after the jump. + */ +void tst_QQuickPathView::qtbug42716() +{ + QScopedPointer<QQuickView> window(createView()); + + window->setSource(testFileUrl("qtbug42716.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + QCOMPARE(window.data(), qGuiApp->focusWindow()); + + QQuickPathView *pathView = findItem<QQuickPathView>(window->rootObject(), "pathView"); + QVERIFY(pathView != 0); + + int order1[] = {5,6,7,0,1,2,3}; + int missing1 = 4; + int order2[] = {0,1,2,3,4,5,6}; + int missing2 = 7; + + qreal lastY = 0.0; + for (int i = 0; i<7; i++) { + QQuickItem *item = findItem<QQuickItem>(pathView, QString("delegate%1").arg(order1[i])); + QVERIFY(item); + QVERIFY(item->y() > lastY); + lastY = item->y(); + } + QQuickItem *itemMiss = findItem<QQuickItem>(pathView, QString("delegate%1").arg(missing1)); + QVERIFY(!itemMiss); + + pathView->setOffset(0.0882353); + //Note refill is delayed, needs time to take effect + QTest::qWait(100); + + lastY = 0.0; + for (int i = 0; i<7; i++) { + QQuickItem *item = findItem<QQuickItem>(pathView, QString("delegate%1").arg(order2[i])); + QVERIFY(item); + QVERIFY(item->y() > lastY); + lastY = item->y(); + } + itemMiss = findItem<QQuickItem>(pathView, QString("delegate%1").arg(missing2)); + QVERIFY(!itemMiss); +} + +void tst_QQuickPathView::addCustomAttribute() +{ + const QScopedPointer<QQuickView> window(createView()); + window->setSource(testFileUrl("customAttribute.qml")); + window->show(); +} + QTEST_MAIN(tst_QQuickPathView) #include "tst_qquickpathview.moc" diff --git a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp index 8063453993..3988a90aed 100644 --- a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp +++ b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp @@ -91,7 +91,7 @@ void tst_QQuickPinchArea::pinchProperties() // target QQuickItem *blackRect = window->rootObject()->findChild<QQuickItem*>("blackrect"); QVERIFY(blackRect != 0); - QVERIFY(blackRect == pinch->target()); + QCOMPARE(blackRect, pinch->target()); QQuickItem *rootItem = qobject_cast<QQuickItem*>(window->rootObject()); QVERIFY(rootItem != 0); QSignalSpy targetSpy(pinch, SIGNAL(targetChanged())); diff --git a/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp b/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp index b9f93a4dcf..0fc8a7f001 100644 --- a/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp +++ b/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp @@ -110,12 +110,14 @@ void tst_qquickpixmapcache::initTestCase() QVERIFY2(server.listen(), qPrintable(server.errorString())); +#ifndef QT_NO_BEARERMANAGEMENT // This avoids a race condition/deadlock bug in network config // manager when it is accessed by the HTTP server thread before // anything else. Bug report can be found at: // QTBUG-26355 QNetworkConfigurationManager cm; cm.updateConfigurations(); +#endif server.serveDirectory(testFile("http")); } @@ -146,7 +148,7 @@ void tst_qquickpixmapcache::single() QString expectedError; if (neterror) { - expectedError = "Error downloading " + target.toString() + " - server replied: Not found"; + expectedError = "Error transferring " + target.toString() + " - server replied: Not found"; } else if (!exists) { expectedError = "Cannot open: " + target.toString(); } @@ -159,10 +161,10 @@ void tst_qquickpixmapcache::single() if (incache) { QCOMPARE(pixmap.error(), expectedError); if (exists) { - QVERIFY(pixmap.status() == QQuickPixmap::Ready); + QCOMPARE(pixmap.status(), QQuickPixmap::Ready); QVERIFY(pixmap.width() > 0); } else { - QVERIFY(pixmap.status() == QQuickPixmap::Error); + QCOMPARE(pixmap.status(), QQuickPixmap::Error); QVERIFY(pixmap.width() <= 0); } } else { @@ -174,10 +176,10 @@ void tst_qquickpixmapcache::single() QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(getter.gotslot); if (exists) { - QVERIFY(pixmap.status() == QQuickPixmap::Ready); + QCOMPARE(pixmap.status(), QQuickPixmap::Ready); QVERIFY(pixmap.width() > 0); } else { - QVERIFY(pixmap.status() == QQuickPixmap::Error); + QCOMPARE(pixmap.status(), QQuickPixmap::Error); QVERIFY(pixmap.width() <= 0); } QCOMPARE(pixmap.error(), expectedError); @@ -259,7 +261,9 @@ void tst_qquickpixmapcache::parallel() } } - QCOMPARE(incache+slotters, targets.count()); + if (incache + slotters != targets.count()) + QFAIL(QString::fromLatin1("pixmap counts don't add up: %1 incache, %2 slotters, %3 total") + .arg(incache).arg(slotters).arg(targets.count()).toLatin1().constData()); if (cancel >= 0) { pixmaps.at(cancel)->clear(getters[cancel]); @@ -280,7 +284,12 @@ void tst_qquickpixmapcache::parallel() if (pending[i]) QVERIFY(getters[i]->gotslot); - QVERIFY(pixmap->isReady()); + if (!pixmap->isReady()) { + QFAIL(QString::fromLatin1("pixmap %1 not ready, status %2: %3") + .arg(pixmap->url().toString()).arg(pixmap->status()) + .arg(pixmap->error()).toLatin1().constData()); + + } QVERIFY(pixmap->width() > 0); delete getters[i]; } @@ -307,7 +316,7 @@ void tst_qquickpixmapcache::massive() QVERIFY(p2.isReady()); QVERIFY(p2.image().size() == QSize(10000, 1000)); - QVERIFY(p2.image().cacheKey() == cachekey); + QCOMPARE(p2.image().cacheKey(), cachekey); } // Confirm that massive images are removed from the cache when diff --git a/tests/auto/quick/qquickpositioners/data/allInvisible.qml b/tests/auto/quick/qquickpositioners/data/allInvisible.qml index 5894171434..3b95a5e1da 100644 --- a/tests/auto/quick/qquickpositioners/data/allInvisible.qml +++ b/tests/auto/quick/qquickpositioners/data/allInvisible.qml @@ -1,4 +1,4 @@ -import QtQuick 2.0 +import QtQuick 2.6 Item{ width: 400 @@ -41,4 +41,42 @@ Item{ visible: false } } + Grid{ + spacing: 20 + objectName: "grid" + Item{ + width: 0 + height: 20 + visible: false + } + Item{ + width: 20 + height: 0 + visible: false + } + Item{ + width: 20 + height: 20 + visible: false + } + } + Flow{ + spacing: 20 + objectName: "flow" + Item{ + width: 0 + height: 20 + visible: false + } + Item{ + width: 20 + height: 0 + visible: false + } + Item{ + width: 20 + height: 20 + visible: false + } + } } diff --git a/tests/auto/quick/qquickpositioners/data/flowtest-padding.qml b/tests/auto/quick/qquickpositioners/data/flowtest-padding.qml new file mode 100644 index 0000000000..a85e7a5c52 --- /dev/null +++ b/tests/auto/quick/qquickpositioners/data/flowtest-padding.qml @@ -0,0 +1,44 @@ +import QtQuick 2.6 + +Item { + width: 90 + height: 480 + property bool testRightToLeft: false + + Flow { + objectName: "flow" + width: parent.width + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight + padding: 1; topPadding: 2; leftPadding: 3; rightPadding: 4; bottomPadding: 5 + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "green" + width: 20 + height: 50 + } + Rectangle { + objectName: "three" + color: "blue" + width: 50 + height: 20 + } + Rectangle { + objectName: "four" + color: "cyan" + width: 50 + height: 50 + } + Rectangle { + objectName: "five" + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/quick/qquickpositioners/data/gridtest-padding.qml b/tests/auto/quick/qquickpositioners/data/gridtest-padding.qml new file mode 100644 index 0000000000..46244ecef5 --- /dev/null +++ b/tests/auto/quick/qquickpositioners/data/gridtest-padding.qml @@ -0,0 +1,47 @@ +import QtQuick 2.6 + +Item { + width: 640 + height: 480 + property bool testRightToLeft: false + property int testHAlignment: Grid.AlignLeft; + property int testVAlignment: Grid.AlignTop; + Grid { + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight + horizontalItemAlignment: testHAlignment + verticalItemAlignment: testVAlignment + objectName: "grid" + columns: 3 + padding: 1; topPadding: 1; leftPadding: 1; rightPadding: 1; bottomPadding: 1 + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "green" + width: 20 + height: 50 + } + Rectangle { + objectName: "three" + color: "blue" + width: 30 + height: 20 + } + Rectangle { + objectName: "four" + color: "cyan" + width: 50 + height: 50 + } + Rectangle { + objectName: "five" + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/quick/qquickpositioners/data/horizontal-padding.qml b/tests/auto/quick/qquickpositioners/data/horizontal-padding.qml new file mode 100644 index 0000000000..d320c4789f --- /dev/null +++ b/tests/auto/quick/qquickpositioners/data/horizontal-padding.qml @@ -0,0 +1,30 @@ +import QtQuick 2.6 + +Item { + width: 640 + height: 480 + property bool testRightToLeft: false + Row { + objectName: "row" + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight + padding: 1; topPadding: 1; leftPadding: 1; rightPadding: 1; bottomPadding: 1 + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "red" + width: 20 + height: 10 + } + Rectangle { + objectName: "three" + color: "red" + width: 40 + height: 20 + } + } +} diff --git a/tests/auto/quick/qquickpositioners/data/repeatertest-padding.qml b/tests/auto/quick/qquickpositioners/data/repeatertest-padding.qml new file mode 100644 index 0000000000..577d4ef0b7 --- /dev/null +++ b/tests/auto/quick/qquickpositioners/data/repeatertest-padding.qml @@ -0,0 +1,53 @@ +import QtQuick 2.6 + +Item { + width: 640 + height: 480 + Row { + padding: 1; topPadding: 2; leftPadding: 3; rightPadding: 4; bottomPadding: 5 + Repeater{ model: 3; + delegate: Component { + Rectangle { + color: "red" + width: 50 + height: 50 + z: { + if (index == 0) + return 2; + else if (index == 1) + return 1; + else + return 3; + } + objectName: { + if (index == 0) + return "one"; + else if (index == 1) + return "two"; + else + return "three"; + } + } + } + } + } + + //This crashed once (QTBUG-16959) because the repeater ended up on the end of the list + //If this grid just instantiates without crashing, then it has not regressed. + Grid { + id: grid + rows: 2 + flow: Grid.TopToBottom + + Repeater { + model: 13 + Rectangle { + color: "goldenrod" + width: 100 + height: 100 + radius: 10 + border.width: 1 + } + } + } +} diff --git a/tests/auto/quick/qquickpositioners/data/repeatertest.qml b/tests/auto/quick/qquickpositioners/data/repeatertest.qml index d90e1cf160..ae3d961c75 100644 --- a/tests/auto/quick/qquickpositioners/data/repeatertest.qml +++ b/tests/auto/quick/qquickpositioners/data/repeatertest.qml @@ -10,8 +10,22 @@ Item { color: "red" width: 50 height: 50 - z: {if(index == 0){2;}else if(index == 1){1;} else{3;}} - objectName: {if(index == 0){"one";}else if(index == 1){"two";} else{"three";}} + z: { + if (index == 0) + return 2; + else if (index == 1) + return 1; + else + return 3; + } + objectName: { + if (index == 0) + return "one"; + else if (index == 1) + return "two"; + else + return "three"; + } } } } diff --git a/tests/auto/quick/qquickpositioners/data/transitions-padding.qml b/tests/auto/quick/qquickpositioners/data/transitions-padding.qml new file mode 100644 index 0000000000..e3175c480c --- /dev/null +++ b/tests/auto/quick/qquickpositioners/data/transitions-padding.qml @@ -0,0 +1,239 @@ +import QtQuick 2.6 + +Rectangle { + id: root + width: 500 + height: 500 + + property int duration: 50 + + property real incrementalSize: 5 + + property int populateTransitionsDone + property int addTransitionsDone + property int displaceTransitionsDone + + property var targetTrans_items: new Object() + property var targetTrans_targetIndexes: new Array() + property var targetTrans_targetItems: new Array() + + property var displacedTrans_items: new Object() + property var displacedTrans_targetIndexes: new Array() + property var displacedTrans_targetItems: new Array() + + // for QQmlListProperty types + function copyList(propList) { + var temp = new Array() + for (var i=0; i<propList.length; i++) + temp.push(propList[i]) + return temp + } + + function checkPos(x, y, name) { + if (Qt.point(x, y) == targetItems_transitionFrom) + model_targetItems_transitionFrom.addItem(name, "") + if (Qt.point(x, y) == displacedItems_transitionVia) + model_displacedItems_transitionVia.addItem(name, "") + } + + Component.onCompleted: { + if (dynamicallyPopulate) { + for (var i=0; i<30; i++) + testModel.addItem("item " + i, "") + } + } + + Transition { + id: populateTransition + enabled: usePopulateTransition + + SequentialAnimation { + ScriptAction { + script: { + root.targetTrans_items[populateTransition.ViewTransition.item.nameData] = populateTransition.ViewTransition.index + root.targetTrans_targetIndexes.push(populateTransition.ViewTransition.targetIndexes) + root.targetTrans_targetItems.push(root.copyList(populateTransition.ViewTransition.targetItems)) + } + } + ParallelAnimation { + NumberAnimation { properties: "x"; from: targetItems_transitionFrom.x; duration: root.duration } + NumberAnimation { properties: "y"; from: targetItems_transitionFrom.y; duration: root.duration } + } + + ScriptAction { script: root.populateTransitionsDone += 1 } + } + } + + Transition { + id: addTransition + enabled: enableAddTransition + + SequentialAnimation { + ScriptAction { + script: { + root.targetTrans_items[addTransition.ViewTransition.item.nameData] = addTransition.ViewTransition.index + root.targetTrans_targetIndexes.push(addTransition.ViewTransition.targetIndexes) + root.targetTrans_targetItems.push(root.copyList(addTransition.ViewTransition.targetItems)) + } + } + ParallelAnimation { + NumberAnimation { properties: "x"; from: targetItems_transitionFrom.x; duration: root.duration } + NumberAnimation { properties: "y"; from: targetItems_transitionFrom.y; duration: root.duration } + } + + ScriptAction { script: root.addTransitionsDone += 1 } + } + } + + Transition { + id: displaced + + SequentialAnimation { + ScriptAction { + script: { + root.displacedTrans_items[displaced.ViewTransition.item.nameData] = displaced.ViewTransition.index + root.displacedTrans_targetIndexes.push(displaced.ViewTransition.targetIndexes) + root.displacedTrans_targetItems.push(root.copyList(displaced.ViewTransition.targetItems)) + } + } + ParallelAnimation { + NumberAnimation { properties: "x"; duration: root.duration; to: displacedItems_transitionVia.x } + NumberAnimation { properties: "y"; duration: root.duration; to: displacedItems_transitionVia.y } + } + NumberAnimation { properties: "x,y"; duration: root.duration } + + ScriptAction { script: root.displaceTransitionsDone += 1 } + } + + } + + Row { + objectName: "row" + + property int count: children.length - 1 // omit Repeater + + x: 50; y: 50 + width: 400; height: 400 + padding: 1; topPadding: 2; leftPadding: 3; rightPadding: 4; bottomPadding: 5 + Repeater { + objectName: "repeater" + model: testedPositioner == "row" ? testModel : undefined + Rectangle { + property string nameData: name + objectName: "wrapper" + width: 30 + index*root.incrementalSize + height: 30 + index*root.incrementalSize + border.width: 1 + Column { + Text { text: index } + Text { objectName: "name"; text: name } + Text { text: parent.parent.y } + } + onXChanged: root.checkPos(x, y, name) + onYChanged: root.checkPos(x, y, name) + } + } + + populate: populateTransition + add: addTransition + move: displaced + } + + Column { + objectName: "column" + + property int count: children.length - 1 // omit Repeater + + x: 50; y: 50 + width: 400; height: 400 + padding: 1; topPadding: 2; leftPadding: 3; rightPadding: 4; bottomPadding: 5 + Repeater { + objectName: "repeater" + model: testedPositioner == "column" ? testModel : undefined + Rectangle { + property string nameData: name + objectName: "wrapper" + width: 30 + index*root.incrementalSize + height: 30 + index*root.incrementalSize + border.width: 1 + Column { + Text { text: index } + Text { objectName: "name"; text: name } + Text { text: parent.parent.y } + } + onXChanged: root.checkPos(x, y, name) + onYChanged: root.checkPos(x, y, name) + } + } + + populate: populateTransition + add: addTransition + move: displaced + } + + Grid { + objectName: "grid" + + property int count: children.length - 1 // omit Repeater + + x: 50; y: 50 + width: 400; height: 400 + padding: 1; topPadding: 2; leftPadding: 3; rightPadding: 4; bottomPadding: 5 + Repeater { + objectName: "repeater" + model: testedPositioner == "grid" ? testModel : undefined + Rectangle { + property string nameData: name + objectName: "wrapper" + width: 30 + index*root.incrementalSize + height: 30 + index*root.incrementalSize + border.width: 1 + Column { + Text { text: index } + Text { objectName: "name"; text: name } + Text { text: parent.parent.y } + } + + onXChanged: root.checkPos(x, y, name) + onYChanged: root.checkPos(x, y, name) + } + } + + populate: populateTransition + add: addTransition + move: displaced + } + + Flow { + objectName: "flow" + + property int count: children.length - 1 // omit Repeater + + x: 50; y: 50 + width: 400; height: 400 + padding: 1; topPadding: 2; leftPadding: 3; rightPadding: 4; bottomPadding: 5 + Repeater { + objectName: "repeater" + model: testedPositioner == "flow" ? testModel : undefined + Rectangle { + property string nameData: name + objectName: "wrapper" + width: 30 + index*root.incrementalSize + height: 30 + index*root.incrementalSize + border.width: 1 + Column { + Text { text: index } + Text { objectName: "name"; text: name } + Text { text: parent.parent.x + " " + parent.parent.y } + } + onXChanged: root.checkPos(x, y, name) + onYChanged: root.checkPos(x, y, name) + } + } + + populate: populateTransition + add: addTransition + move: displaced + } +} + diff --git a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp index 3c44041ca5..69359503fe 100644 --- a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp +++ b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp @@ -53,33 +53,50 @@ public: private slots: void test_horizontal(); + void test_horizontal_padding(); void test_horizontal_rtl(); void test_horizontal_spacing(); void test_horizontal_spacing_rightToLeft(); void test_horizontal_animated(); + void test_horizontal_animated_padding(); void test_horizontal_animated_rightToLeft(); + void test_horizontal_animated_rightToLeft_padding(); void test_horizontal_animated_disabled(); + void test_horizontal_animated_disabled_padding(); void test_vertical(); + void test_vertical_padding(); void test_vertical_spacing(); void test_vertical_animated(); + void test_vertical_animated_padding(); void test_grid(); + void test_grid_padding(); void test_grid_topToBottom(); void test_grid_rightToLeft(); void test_grid_spacing(); void test_grid_row_column_spacing(); void test_grid_animated(); + void test_grid_animated_padding(); void test_grid_animated_rightToLeft(); + void test_grid_animated_rightToLeft_padding(); void test_grid_zero_columns(); void test_grid_H_alignment(); + void test_grid_H_alignment_padding(); void test_grid_V_alignment(); + void test_grid_V_alignment_padding(); void test_propertychanges(); void test_repeater(); + void test_repeater_padding(); void test_flow(); + void test_flow_padding(); void test_flow_rightToLeft(); void test_flow_topToBottom(); + void test_flow_topToBottom_padding(); void test_flow_resize(); + void test_flow_resize_padding(); void test_flow_resize_rightToLeft(); + void test_flow_resize_rightToLeft_padding(); void test_flow_implicit_resize(); + void test_flow_implicit_resize_padding(); void test_conflictinganchors(); void test_mirroring(); void test_allInvisible(); @@ -198,18 +215,25 @@ void tst_qquickpositioners::addTransitions_grid_data() // (adding items further down the grid can cause displace transitions at // previous indexes, since grid is auto-resized to tightly fit all of its items) + QTest::addColumn<QString>("qmlFile"); QTest::addColumn<int>("initialItemCount"); QTest::addColumn<int>("insertionIndex"); QTest::addColumn<int>("insertionCount"); QTest::addColumn<ListRange>("expectedDisplacedIndexes"); - QTest::newRow("add one @ start") << 10 << 0 << 1 << ListRange(0, 9); - QTest::newRow("add one @ middle") << 10 << 5 << 1 << ListRange(3, 3) + ListRange(5, 9); - QTest::newRow("add one @ end") << 10 << 10 << 1 << ListRange(3, 3) + ListRange(7, 7); + QTest::newRow("add one @ start") << "transitions.qml" << 10 << 0 << 1 << ListRange(0, 9); + QTest::newRow("add one @ middle") << "transitions.qml" << 10 << 5 << 1 << ListRange(3, 3) + ListRange(5, 9); + QTest::newRow("add one @ end") << "transitions.qml" << 10 << 10 << 1 << ListRange(3, 3) + ListRange(7, 7); + QTest::newRow("padding, add one @ start") << "transitions-padding.qml" << 10 << 0 << 1 << ListRange(0, 9); + QTest::newRow("padding, add one @ middle") << "transitions-padding.qml" << 10 << 5 << 1 << ListRange(3, 3) + ListRange(5, 9); + QTest::newRow("padding, add one @ end") << "transitions-padding.qml" << 10 << 10 << 1 << ListRange(3, 3) + ListRange(7, 7); - QTest::newRow("add multiple @ start") << 10 << 0 << 3 << ListRange(0, 9); - QTest::newRow("add multiple @ middle") << 10 << 5 << 3 << ListRange(1, 3) + ListRange(5, 9); - QTest::newRow("add multiple @ end") << 10 << 10 << 3 << ListRange(1, 3) + ListRange(5, 7) + ListRange(9, 9); + QTest::newRow("add multiple @ start") << "transitions.qml" << 10 << 0 << 3 << ListRange(0, 9); + QTest::newRow("add multiple @ middle") << "transitions.qml" << 10 << 5 << 3 << ListRange(1, 3) + ListRange(5, 9); + QTest::newRow("add multiple @ end") << "transitions.qml" << 10 << 10 << 3 << ListRange(1, 3) + ListRange(5, 7) + ListRange(9, 9); + QTest::newRow("padding, add multiple @ start") << "transitions-padding.qml" << 10 << 0 << 3 << ListRange(0, 9); + QTest::newRow("padding, add multiple @ middle") << "transitions-padding.qml" << 10 << 5 << 3 << ListRange(1, 3) + ListRange(5, 9); + QTest::newRow("padding, add multiple @ end") << "transitions-padding.qml" << 10 << 10 << 3 << ListRange(1, 3) + ListRange(5, 7) + ListRange(9, 9); } void tst_qquickpositioners::addTransitions_flow() @@ -253,17 +277,24 @@ void tst_qquickpositioners::moveTransitions_grid_data() // (removing items further down the grid can cause displace transitions at // previous indexes, since grid is auto-resized to tightly fit all of its items) + QTest::addColumn<QString>("qmlFile"); QTest::addColumn<int>("initialItemCount"); QTest::addColumn<ListChange>("change"); QTest::addColumn<ListRange>("expectedDisplacedIndexes"); - QTest::newRow("remove one @ start") << 10 << ListChange::remove(0, 1) << ListRange(1, 9); - QTest::newRow("remove one @ middle") << 10 << ListChange::remove(4, 1) << ListRange(2, 3) + ListRange(5, 9); - QTest::newRow("remove one @ end") << 10 << ListChange::remove(9, 1) << ListRange(2, 3) + ListRange(6, 7); + QTest::newRow("remove one @ start") << "transitions.qml" << 10 << ListChange::remove(0, 1) << ListRange(1, 9); + QTest::newRow("remove one @ middle") << "transitions.qml" << 10 << ListChange::remove(4, 1) << ListRange(2, 3) + ListRange(5, 9); + QTest::newRow("remove one @ end") << "transitions.qml" << 10 << ListChange::remove(9, 1) << ListRange(2, 3) + ListRange(6, 7); + QTest::newRow("padding, remove one @ start") << "transitions-padding.qml" << 10 << ListChange::remove(0, 1) << ListRange(1, 9); + QTest::newRow("padding, remove one @ middle") << "transitions-padding.qml" << 10 << ListChange::remove(4, 1) << ListRange(2, 3) + ListRange(5, 9); + QTest::newRow("padding, remove one @ end") << "transitions-padding.qml" << 10 << ListChange::remove(9, 1) << ListRange(2, 3) + ListRange(6, 7); - QTest::newRow("remove multiple @ start") << 10 << ListChange::remove(0, 3) << ListRange(3, 9); - QTest::newRow("remove multiple @ middle") << 10 << ListChange::remove(4, 3) << ListRange(1, 3) + ListRange(7, 9); - QTest::newRow("remove multiple @ end") << 10 << ListChange::remove(7, 3) << ListRange(1, 3) + ListRange(5, 6); + QTest::newRow("remove multiple @ start") << "transitions.qml" << 10 << ListChange::remove(0, 3) << ListRange(3, 9); + QTest::newRow("remove multiple @ middle") << "transitions.qml" << 10 << ListChange::remove(4, 3) << ListRange(1, 3) + ListRange(7, 9); + QTest::newRow("remove multiple @ end") << "transitions.qml" << 10 << ListChange::remove(7, 3) << ListRange(1, 3) + ListRange(5, 6); + QTest::newRow("padding, remove multiple @ start") << "transitions-padding.qml" << 10 << ListChange::remove(0, 3) << ListRange(3, 9); + QTest::newRow("padding, remove multiple @ middle") << "transitions-padding.qml" << 10 << ListChange::remove(4, 3) << ListRange(1, 3) + ListRange(7, 9); + QTest::newRow("padding, remove multiple @ end") << "transitions-padding.qml" << 10 << ListChange::remove(7, 3) << ListRange(1, 3) + ListRange(5, 6); } void tst_qquickpositioners::moveTransitions_flow() @@ -305,6 +336,185 @@ void tst_qquickpositioners::test_horizontal() QQuickItem *row = window->rootObject()->findChild<QQuickItem*>("row"); QCOMPARE(row->width(), 110.0); QCOMPARE(row->height(), 50.0); + + // test padding + row->setProperty("padding", 1); + row->setProperty("topPadding", 2); + row->setProperty("leftPadding", 3); + row->setProperty("rightPadding", 4); + row->setProperty("bottomPadding", 5); + + QTRY_COMPARE(row->width(), 117.0); + QCOMPARE(row->height(), 57.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 73.0); + QCOMPARE(three->y(), 2.0); +} + +void tst_qquickpositioners::test_horizontal_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("horizontal.qml"))); + + window->rootObject()->setProperty("testRightToLeft", false); + + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 70.0); + QCOMPARE(three->y(), 0.0); + + QQuickItem *row = window->rootObject()->findChild<QQuickItem*>("row"); + QCOMPARE(row->width(), 110.0); + QCOMPARE(row->height(), 50.0); + + QQuickRow *obj = qobject_cast<QQuickRow*>(row); + QVERIFY(obj != 0); + + QCOMPARE(row->property("padding").toDouble(), 0.0); + QCOMPARE(row->property("topPadding").toDouble(), 0.0); + QCOMPARE(row->property("leftPadding").toDouble(), 0.0); + QCOMPARE(row->property("rightPadding").toDouble(), 0.0); + QCOMPARE(row->property("bottomPadding").toDouble(), 0.0); + + obj->setPadding(1.0); + + QCOMPARE(row->property("padding").toDouble(), 1.0); + QCOMPARE(row->property("topPadding").toDouble(), 1.0); + QCOMPARE(row->property("leftPadding").toDouble(), 1.0); + QCOMPARE(row->property("rightPadding").toDouble(), 1.0); + QCOMPARE(row->property("bottomPadding").toDouble(), 1.0); + + QTRY_COMPARE(row->width(), 112.0); + QCOMPARE(row->height(), 52.0); + + QCOMPARE(one->x(), 1.0); + QCOMPARE(one->y(), 1.0); + QCOMPARE(two->x(), 51.0); + QCOMPARE(two->y(), 1.0); + QCOMPARE(three->x(), 71.0); + QCOMPARE(three->y(), 1.0); + + obj->setTopPadding(2.0); + + QCOMPARE(row->property("padding").toDouble(), 1.0); + QCOMPARE(row->property("topPadding").toDouble(), 2.0); + QCOMPARE(row->property("leftPadding").toDouble(), 1.0); + QCOMPARE(row->property("rightPadding").toDouble(), 1.0); + QCOMPARE(row->property("bottomPadding").toDouble(), 1.0); + + QTRY_COMPARE(row->height(), 53.0); + QCOMPARE(row->width(), 112.0); + + QCOMPARE(one->x(), 1.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 51.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 71.0); + QCOMPARE(three->y(), 2.0); + + obj->setLeftPadding(3.0); + + QCOMPARE(row->property("padding").toDouble(), 1.0); + QCOMPARE(row->property("topPadding").toDouble(), 2.0); + QCOMPARE(row->property("leftPadding").toDouble(), 3.0); + QCOMPARE(row->property("rightPadding").toDouble(), 1.0); + QCOMPARE(row->property("bottomPadding").toDouble(), 1.0); + + QTRY_COMPARE(row->width(), 114.0); + QCOMPARE(row->height(), 53.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 73.0); + QCOMPARE(three->y(), 2.0); + + obj->setRightPadding(4.0); + + QCOMPARE(row->property("padding").toDouble(), 1.0); + QCOMPARE(row->property("topPadding").toDouble(), 2.0); + QCOMPARE(row->property("leftPadding").toDouble(), 3.0); + QCOMPARE(row->property("rightPadding").toDouble(), 4.0); + QCOMPARE(row->property("bottomPadding").toDouble(), 1.0); + + QTRY_COMPARE(row->width(), 117.0); + QCOMPARE(row->height(), 53.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 73.0); + QCOMPARE(three->y(), 2.0); + + obj->setBottomPadding(5.0); + + QCOMPARE(row->property("padding").toDouble(), 1.0); + QCOMPARE(row->property("topPadding").toDouble(), 2.0); + QCOMPARE(row->property("leftPadding").toDouble(), 3.0); + QCOMPARE(row->property("rightPadding").toDouble(), 4.0); + QCOMPARE(row->property("bottomPadding").toDouble(), 5.0); + + QTRY_COMPARE(row->height(), 57.0); + QCOMPARE(row->width(), 117.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 73.0); + QCOMPARE(three->y(), 2.0); + + obj->resetBottomPadding(); + QCOMPARE(row->property("bottomPadding").toDouble(), 1.0); + QTRY_COMPARE(row->height(), 53.0); + QCOMPARE(row->width(), 117.0); + + obj->resetRightPadding(); + QCOMPARE(row->property("rightPadding").toDouble(), 1.0); + QTRY_COMPARE(row->width(), 114.0); + QCOMPARE(row->height(), 53.0); + + obj->resetLeftPadding(); + QCOMPARE(row->property("leftPadding").toDouble(), 1.0); + QTRY_COMPARE(row->width(), 112.0); + QCOMPARE(row->height(), 53.0); + + obj->resetTopPadding(); + QCOMPARE(row->property("topPadding").toDouble(), 1.0); + QTRY_COMPARE(row->height(), 52.0); + QCOMPARE(row->width(), 112.0); + + obj->resetPadding(); + QCOMPARE(row->property("padding").toDouble(), 0.0); + QCOMPARE(row->property("topPadding").toDouble(), 0.0); + QCOMPARE(row->property("leftPadding").toDouble(), 0.0); + QCOMPARE(row->property("rightPadding").toDouble(), 0.0); + QCOMPARE(row->property("bottomPadding").toDouble(), 0.0); + QTRY_COMPARE(row->height(), 50.0); + QCOMPARE(row->width(), 110.0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 70.0); + QCOMPARE(three->y(), 0.0); } void tst_qquickpositioners::test_horizontal_rtl() @@ -333,6 +543,36 @@ void tst_qquickpositioners::test_horizontal_rtl() QCOMPARE(row->width(), 110.0); QCOMPARE(row->height(), 50.0); + // test padding + row->setProperty("padding", 1); + row->setProperty("topPadding", 2); + row->setProperty("leftPadding", 3); + row->setProperty("rightPadding", 4); + row->setProperty("bottomPadding", 5); + + QTRY_COMPARE(row->width(), 117.0); + QCOMPARE(row->height(), 57.0); + + QCOMPARE(one->x(), 63.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 43.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 2.0); + + row->setProperty("topPadding", 0); + row->setProperty("leftPadding", 0); + row->setProperty("rightPadding", 0); + row->setProperty("bottomPadding", 0); + row->setProperty("padding", 0); + + QTRY_COMPARE(one->x(), 60.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 40.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 0.0); + // Change the width of the row and check that items stay to the right row->setWidth(200); QTRY_COMPARE(one->x(), 150.0); @@ -342,6 +582,18 @@ void tst_qquickpositioners::test_horizontal_rtl() QCOMPARE(three->x(), 90.0); QCOMPARE(three->y(), 0.0); + row->setProperty("padding", 1); + row->setProperty("topPadding", 2); + row->setProperty("leftPadding", 3); + row->setProperty("rightPadding", 4); + row->setProperty("bottomPadding", 5); + + QTRY_COMPARE(one->x(), 146.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 126.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 86.0); + QCOMPARE(three->y(), 2.0); } void tst_qquickpositioners::test_horizontal_spacing() @@ -370,6 +622,22 @@ void tst_qquickpositioners::test_horizontal_spacing() QCOMPARE(row->width(), 130.0); QCOMPARE(row->height(), 50.0); + // test padding + row->setProperty("padding", 1); + row->setProperty("topPadding", 2); + row->setProperty("leftPadding", 3); + row->setProperty("rightPadding", 4); + row->setProperty("bottomPadding", 5); + + QTRY_COMPARE(row->width(), 137.0); + QCOMPARE(row->height(), 57.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 63.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 93.0); + QCOMPARE(three->y(), 2.0); } void tst_qquickpositioners::test_horizontal_spacing_rightToLeft() @@ -391,13 +659,29 @@ void tst_qquickpositioners::test_horizontal_spacing_rightToLeft() QCOMPARE(one->y(), 0.0); QCOMPARE(two->x(), 50.0); QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 00.0); + QCOMPARE(three->x(), 0.0); QCOMPARE(three->y(), 0.0); QQuickItem *row = window->rootObject()->findChild<QQuickItem*>("row"); QCOMPARE(row->width(), 130.0); QCOMPARE(row->height(), 50.0); + // test padding + row->setProperty("padding", 1); + row->setProperty("topPadding", 2); + row->setProperty("leftPadding", 3); + row->setProperty("rightPadding", 4); + row->setProperty("bottomPadding", 5); + + QTRY_COMPARE(row->width(), 137.0); + QCOMPARE(row->height(), 57.0); + + QCOMPARE(one->x(), 83.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 2.0); } void tst_qquickpositioners::test_horizontal_animated() @@ -453,6 +737,70 @@ void tst_qquickpositioners::test_horizontal_animated() } +void tst_qquickpositioners::test_horizontal_animated_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("horizontal-animated.qml"), false)); + + window->rootObject()->setProperty("testRightToLeft", false); + + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + + //Note that they animate in + QCOMPARE(one->x(), -100.0); + QCOMPARE(two->x(), -100.0); + QCOMPARE(three->x(), -100.0); + + QVERIFY(QTest::qWaitForWindowExposed(window.data())); //It may not relayout until the next frame, so it needs to be drawn + + QQuickItem *row = window->rootObject()->findChild<QQuickItem*>("row"); + QVERIFY(row); + QCOMPARE(row->width(), 100.0); + QCOMPARE(row->height(), 50.0); + + // test padding + row->setProperty("padding", 1); + row->setProperty("topPadding", 2); + row->setProperty("leftPadding", 3); + row->setProperty("rightPadding", 4); + row->setProperty("bottomPadding", 5); + + QTRY_COMPARE(row->width(), 107.0); + QCOMPARE(row->height(), 57.0); + + //QTRY_COMPARE used instead of waiting for the expected time of animation completion + //Note that this means the duration of the animation is NOT tested + + QTRY_COMPARE(one->x(), 3.0); + QTRY_COMPARE(one->y(), 2.0); + QTRY_COMPARE(two->isVisible(), false); + QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet + QTRY_COMPARE(two->y(), 0.0); + QTRY_COMPARE(three->x(), 53.0); + QTRY_COMPARE(three->y(), 2.0); + + //Add 'two' + two->setVisible(true); + QTRY_COMPARE(two->isVisible(), true); + QTRY_COMPARE(row->width(), 157.0); + QTRY_COMPARE(row->height(), 57.0); + + QTest::qWait(0);//Let the animation start + QVERIFY(two->x() >= -100.0 && two->x() < 53.0); + QVERIFY(three->x() >= 53.0 && three->x() < 103.0); + + QTRY_COMPARE(two->y(), 2.0); + QTRY_COMPARE(two->x(), 53.0); + QTRY_COMPARE(three->x(), 103.0); + +} + void tst_qquickpositioners::test_horizontal_animated_rightToLeft() { QScopedPointer<QQuickView> window(createView(testFile("horizontal-animated.qml"), false)); @@ -508,6 +856,72 @@ void tst_qquickpositioners::test_horizontal_animated_rightToLeft() } +void tst_qquickpositioners::test_horizontal_animated_rightToLeft_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("horizontal-animated.qml"), false)); + + window->rootObject()->setProperty("testRightToLeft", true); + + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + + //Note that they animate in + QCOMPARE(one->x(), -100.0); + QCOMPARE(two->x(), -100.0); + QCOMPARE(three->x(), -100.0); + + QVERIFY(QTest::qWaitForWindowExposed(window.data())); //It may not relayout until the next frame, so it needs to be drawn + + QQuickItem *row = window->rootObject()->findChild<QQuickItem*>("row"); + QVERIFY(row); + QCOMPARE(row->width(), 100.0); + QCOMPARE(row->height(), 50.0); + + // test padding + row->setProperty("padding", 1); + row->setProperty("topPadding", 2); + row->setProperty("leftPadding", 3); + row->setProperty("rightPadding", 4); + row->setProperty("bottomPadding", 5); + + QTRY_COMPARE(row->width(), 107.0); + QCOMPARE(row->height(), 57.0); + + //QTRY_COMPARE used instead of waiting for the expected time of animation completion + //Note that this means the duration of the animation is NOT tested + + QTRY_COMPARE(one->x(), 53.0); + QTRY_COMPARE(one->y(), 2.0); + QTRY_COMPARE(two->isVisible(), false); + QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet + QTRY_COMPARE(two->y(), 0.0); + QTRY_COMPARE(three->x(), 3.0); + QTRY_COMPARE(three->y(), 2.0); + + //Add 'two' + two->setVisible(true); + QTRY_COMPARE(two->isVisible(), true); + + // New size should propagate after visible change + QTRY_COMPARE(row->width(), 157.0); + QTRY_COMPARE(row->height(), 57.0); + + QTest::qWait(0);//Let the animation start + QVERIFY(one->x() >= 53.0 && one->x() < 100); + QVERIFY(two->x() >= -100.0 && two->x() < 53.0); + + QTRY_COMPARE(one->x(), 103.0); + QTRY_COMPARE(two->y(), 2.0); + QTRY_COMPARE(two->x(), 53.0); + +} + void tst_qquickpositioners::test_horizontal_animated_disabled() { QScopedPointer<QQuickView> window(createView(testFile("horizontal-animated-disabled.qml"))); @@ -526,6 +940,54 @@ void tst_qquickpositioners::test_horizontal_animated_disabled() qApp->processEvents(); + // test padding + row->setProperty("padding", 1); + row->setProperty("topPadding", 2); + row->setProperty("leftPadding", 3); + row->setProperty("rightPadding", 4); + row->setProperty("bottomPadding", 5); + + QTRY_COMPARE(row->width(), 107.0); + QCOMPARE(row->height(), 57.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->isVisible(), false); + QCOMPARE(two->x(), -100.0);//Not 'in' yet + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 53.0); + QCOMPARE(three->y(), 2.0); + + //Add 'two' + two->setVisible(true); + QCOMPARE(two->isVisible(), true); + QTRY_COMPARE(row->width(), 157.0); + QTRY_COMPARE(row->height(), 57.0); + + QTRY_COMPARE(two->y(), 2.0); + QTRY_COMPARE(two->x(), 53.0); + QTRY_COMPARE(three->x(), 103.0); + +} + +void tst_qquickpositioners::test_horizontal_animated_disabled_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("horizontal-animated-disabled.qml"))); + + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + + QQuickItem *row = window->rootObject()->findChild<QQuickItem*>("row"); + QVERIFY(row); + + qApp->processEvents(); + QCOMPARE(one->x(), 0.0); QCOMPARE(one->y(), 0.0); QCOMPARE(two->isVisible(), false); @@ -547,6 +1009,7 @@ void tst_qquickpositioners::test_horizontal_animated_disabled() void tst_qquickpositioners::populateTransitions(const QString &positionerObjectName) { + QFETCH(QString, qmlFile); QFETCH(bool, dynamicallyPopulate); QFETCH(bool, usePopulateTransition); @@ -574,7 +1037,7 @@ void tst_qquickpositioners::populateTransitions(const QString &positionerObjectN ctxt->setContextProperty("targetItems_transitionFrom", targetItems_transitionFrom); ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia); ctxt->setContextProperty("testedPositioner", positionerObjectName); - window->setSource(testFileUrl("transitions.qml")); + window->setSource(testFileUrl(qmlFile)); QQuickItem *positioner = window->rootObject()->findChild<QQuickItem*>(positionerObjectName); QVERIFY(positioner); @@ -619,18 +1082,24 @@ void tst_qquickpositioners::populateTransitions(const QString &positionerObjectN void tst_qquickpositioners::populateTransitions_data() { + QTest::addColumn<QString>("qmlFile"); QTest::addColumn<bool>("dynamicallyPopulate"); QTest::addColumn<bool>("usePopulateTransition"); - QTest::newRow("statically populate") << false << true; - QTest::newRow("statically populate, no populate transition") << false << false; + QTest::newRow("statically populate") << "transitions.qml" << false << true; + QTest::newRow("statically populate, no populate transition") << "transitions.qml" << false << false; + QTest::newRow("padding, statically populate") << "transitions-padding.qml" << false << true; + QTest::newRow("padding, statically populate, no populate transition") << "transitions-padding.qml" << false << false; - QTest::newRow("dynamically populate") << true << true; - QTest::newRow("dynamically populate, no populate transition") << true << false; + QTest::newRow("dynamically populate") << "transitions.qml" << true << true; + QTest::newRow("dynamically populate, no populate transition") << "transitions.qml" << true << false; + QTest::newRow("padding, dynamically populate") << "transitions-padding.qml" << true << true; + QTest::newRow("padding, dynamically populate, no populate transition") << "transitions-padding.qml" << true << false; } void tst_qquickpositioners::addTransitions(const QString &positionerObjectName) { + QFETCH(QString, qmlFile); QFETCH(int, initialItemCount); QFETCH(int, insertionIndex); QFETCH(int, insertionCount); @@ -654,7 +1123,7 @@ void tst_qquickpositioners::addTransitions(const QString &positionerObjectName) ctxt->setContextProperty("targetItems_transitionFrom", targetItems_transitionFrom); ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia); ctxt->setContextProperty("testedPositioner", QString()); - window->setSource(testFileUrl("transitions.qml")); + window->setSource(testFileUrl(qmlFile)); window->show(); QTest::qWaitForWindowExposed(window.data()); qApp->processEvents(); @@ -729,22 +1198,30 @@ void tst_qquickpositioners::addTransitions_data() { // If this data changes, update addTransitions_grid_data() also + QTest::addColumn<QString>("qmlFile"); QTest::addColumn<int>("initialItemCount"); QTest::addColumn<int>("insertionIndex"); QTest::addColumn<int>("insertionCount"); QTest::addColumn<ListRange>("expectedDisplacedIndexes"); - QTest::newRow("add one @ start") << 10 << 0 << 1 << ListRange(0, 9); - QTest::newRow("add one @ middle") << 10 << 5 << 1 << ListRange(5, 9); - QTest::newRow("add one @ end") << 10 << 10 << 1 << ListRange(); + QTest::newRow("add one @ start") << "transitions.qml" << 10 << 0 << 1 << ListRange(0, 9); + QTest::newRow("add one @ middle") << "transitions.qml" << 10 << 5 << 1 << ListRange(5, 9); + QTest::newRow("add one @ end") << "transitions.qml" << 10 << 10 << 1 << ListRange(); + QTest::newRow("padding, add one @ start") << "transitions-padding.qml" << 10 << 0 << 1 << ListRange(0, 9); + QTest::newRow("padding, add one @ middle") << "transitions-padding.qml" << 10 << 5 << 1 << ListRange(5, 9); + QTest::newRow("padding, add one @ end") << "transitions-padding.qml" << 10 << 10 << 1 << ListRange(); - QTest::newRow("add multiple @ start") << 10 << 0 << 3 << ListRange(0, 9); - QTest::newRow("add multiple @ middle") << 10 << 5 << 3 << ListRange(5, 9); - QTest::newRow("add multiple @ end") << 10 << 10 << 3 << ListRange(); + QTest::newRow("add multiple @ start") << "transitions.qml" << 10 << 0 << 3 << ListRange(0, 9); + QTest::newRow("add multiple @ middle") << "transitions.qml" << 10 << 5 << 3 << ListRange(5, 9); + QTest::newRow("add multiple @ end") << "transitions.qml" << 10 << 10 << 3 << ListRange(); + QTest::newRow("padding, add multiple @ start") << "transitions-padding.qml" << 10 << 0 << 3 << ListRange(0, 9); + QTest::newRow("padding, add multiple @ middle") << "transitions-padding.qml" << 10 << 5 << 3 << ListRange(5, 9); + QTest::newRow("padding, add multiple @ end") << "transitions-padding.qml" << 10 << 10 << 3 << ListRange(); } void tst_qquickpositioners::moveTransitions(const QString &positionerObjectName) { + QFETCH(QString, qmlFile); QFETCH(int, initialItemCount); QFETCH(ListChange, change); QFETCH(ListRange, expectedDisplacedIndexes); @@ -769,7 +1246,7 @@ void tst_qquickpositioners::moveTransitions(const QString &positionerObjectName) ctxt->setContextProperty("targetItems_transitionFrom", targetItems_transitionFrom); ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia); ctxt->setContextProperty("testedPositioner", QString()); - window->setSource(testFileUrl("transitions.qml")); + window->setSource(testFileUrl(qmlFile)); window->show(); QTest::qWaitForWindowExposed(window.data()); qApp->processEvents(); @@ -840,27 +1317,36 @@ void tst_qquickpositioners::moveTransitions_data() { // If this data changes, update moveTransitions_grid_data() also + QTest::addColumn<QString>("qmlFile"); QTest::addColumn<int>("initialItemCount"); QTest::addColumn<ListChange>("change"); QTest::addColumn<ListRange>("expectedDisplacedIndexes"); - QTest::newRow("remove one @ start") << 10 << ListChange::remove(0, 1) << ListRange(1, 9); - QTest::newRow("remove one @ middle") << 10 << ListChange::remove(4, 1) << ListRange(5, 9); - QTest::newRow("remove one @ end") << 10 << ListChange::remove(9, 1) << ListRange(); + QTest::newRow("remove one @ start") << "transitions.qml" << 10 << ListChange::remove(0, 1) << ListRange(1, 9); + QTest::newRow("remove one @ middle") << "transitions.qml" << 10 << ListChange::remove(4, 1) << ListRange(5, 9); + QTest::newRow("remove one @ end") << "transitions.qml" << 10 << ListChange::remove(9, 1) << ListRange(); + QTest::newRow("padding, remove one @ start") << "transitions-padding.qml" << 10 << ListChange::remove(0, 1) << ListRange(1, 9); + QTest::newRow("padding, remove one @ middle") << "transitions-padding.qml" << 10 << ListChange::remove(4, 1) << ListRange(5, 9); + QTest::newRow("padding, remove one @ end") << "transitions-padding.qml" << 10 << ListChange::remove(9, 1) << ListRange(); - QTest::newRow("remove multiple @ start") << 10 << ListChange::remove(0, 3) << ListRange(3, 9); - QTest::newRow("remove multiple @ middle") << 10 << ListChange::remove(4, 3) << ListRange(7, 9); - QTest::newRow("remove multiple @ end") << 10 << ListChange::remove(7, 3) << ListRange(); + QTest::newRow("remove multiple @ start") << "transitions.qml" << 10 << ListChange::remove(0, 3) << ListRange(3, 9); + QTest::newRow("remove multiple @ middle") << "transitions.qml" << 10 << ListChange::remove(4, 3) << ListRange(7, 9); + QTest::newRow("remove multiple @ end") << "transitions.qml" << 10 << ListChange::remove(7, 3) << ListRange(); + QTest::newRow("padding, remove multiple @ start") << "transitions-padding.qml" << 10 << ListChange::remove(0, 3) << ListRange(3, 9); + QTest::newRow("padding, remove multiple @ middle") << "transitions-padding.qml" << 10 << ListChange::remove(4, 3) << ListRange(7, 9); + QTest::newRow("padding, remove multiple @ end") << "transitions-padding.qml" << 10 << ListChange::remove(7, 3) << ListRange(); } - void tst_qquickpositioners::checkItemPositions(QQuickItem *positioner, QaimModel *model, qreal incrementalSize) { QVERIFY(model->count() > 0); + + QQuickBasePositioner *p = qobject_cast<QQuickBasePositioner*>(positioner); + qreal padding = 0; qreal currentSize = 30; - qreal rowX = 0; - qreal rowY = 0; + qreal rowX = p->leftPadding(); + qreal rowY = p->topPadding(); for (int i=0; i<model->count(); ++i) { QQuickItem *item = findItem<QQuickItem>(positioner, "wrapper", i); @@ -870,11 +1356,11 @@ void tst_qquickpositioners::checkItemPositions(QQuickItem *positioner, QaimModel QCOMPARE(item->height(), currentSize); if (qobject_cast<QQuickRow*>(positioner)) { - QCOMPARE(item->x(), (i * 30.0) + padding); - QCOMPARE(item->y(), 0.0); + QCOMPARE(item->x(), (i * 30.0) + padding + p->leftPadding()); + QCOMPARE(item->y(), p->topPadding()); } else if (qobject_cast<QQuickColumn*>(positioner)) { - QCOMPARE(item->x(), 0.0); - QCOMPARE(item->y(), (i * 30.0) + padding); + QCOMPARE(item->x(), p->leftPadding()); + QCOMPARE(item->y(), (i * 30.0) + padding + p->topPadding()); } else if (qobject_cast<QQuickGrid*>(positioner)) { int columns = 4; int rows = qCeil(model->count() / qreal(columns)); @@ -886,20 +1372,20 @@ void tst_qquickpositioners::checkItemPositions(QQuickItem *positioner, QaimModel QVERIFY(finalAlignedRowItem); QCOMPARE(item->x(), finalAlignedRowItem->x()); } else { - QCOMPARE(item->x(), 0.0); + QCOMPARE(item->x(), p->leftPadding()); } if (i / columns > 0) { QQuickItem *prevRowLastItem = findItem<QQuickItem>(positioner, "wrapper", (i/columns * columns) - 1); QVERIFY(prevRowLastItem); QCOMPARE(item->y(), prevRowLastItem->y() + prevRowLastItem->height()); } else { - QCOMPARE(item->y(), 0.0); + QCOMPARE(item->y(), p->topPadding()); } } else if (qobject_cast<QQuickFlow*>(positioner)) { if (rowX + item->width() > positioner->width()) { QQuickItem *prevItem = findItem<QQuickItem>(positioner, "wrapper", i-1); QVERIFY(prevItem); - rowX = 0; + rowX = p->leftPadding(); rowY = prevItem->y() + prevItem->height(); } QCOMPARE(item->x(), rowX); @@ -942,6 +1428,183 @@ void tst_qquickpositioners::test_vertical() QCOMPARE(column->height(), 80.0); QCOMPARE(column->width(), 50.0); + // test padding + column->setProperty("padding", 1); + column->setProperty("topPadding", 2); + column->setProperty("leftPadding", 3); + column->setProperty("rightPadding", 4); + column->setProperty("bottomPadding", 5); + + QTRY_COMPARE(column->height(), 87.0); + QCOMPARE(column->width(), 57.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 3.0); + QCOMPARE(two->y(), 52.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 62.0); +} + +void tst_qquickpositioners::test_vertical_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("vertical.qml"))); + + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 0.0); + QCOMPARE(two->y(), 50.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 60.0); + + QQuickItem *column = window->rootObject()->findChild<QQuickItem*>("column"); + QVERIFY(column); + QCOMPARE(column->height(), 80.0); + QCOMPARE(column->width(), 50.0); + + QQuickColumn *obj = qobject_cast<QQuickColumn*>(column); + QVERIFY(obj != 0); + + QCOMPARE(column->property("padding").toDouble(), 0.0); + QCOMPARE(column->property("topPadding").toDouble(), 0.0); + QCOMPARE(column->property("leftPadding").toDouble(), 0.0); + QCOMPARE(column->property("rightPadding").toDouble(), 0.0); + QCOMPARE(column->property("bottomPadding").toDouble(), 0.0); + + obj->setPadding(1.0); + + QCOMPARE(column->property("padding").toDouble(), 1.0); + QCOMPARE(column->property("topPadding").toDouble(), 1.0); + QCOMPARE(column->property("leftPadding").toDouble(), 1.0); + QCOMPARE(column->property("rightPadding").toDouble(), 1.0); + QCOMPARE(column->property("bottomPadding").toDouble(), 1.0); + + QTRY_COMPARE(column->height(), 82.0); + QCOMPARE(column->width(), 52.0); + + QCOMPARE(one->x(), 1.0); + QCOMPARE(one->y(), 1.0); + QCOMPARE(two->x(), 1.0); + QCOMPARE(two->y(), 51.0); + QCOMPARE(three->x(), 1.0); + QCOMPARE(three->y(), 61.0); + + obj->setTopPadding(2.0); + + QCOMPARE(column->property("padding").toDouble(), 1.0); + QCOMPARE(column->property("topPadding").toDouble(), 2.0); + QCOMPARE(column->property("leftPadding").toDouble(), 1.0); + QCOMPARE(column->property("rightPadding").toDouble(), 1.0); + QCOMPARE(column->property("bottomPadding").toDouble(), 1.0); + + QTRY_COMPARE(column->height(), 83.0); + QCOMPARE(column->width(), 52.0); + + QCOMPARE(one->x(), 1.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 1.0); + QCOMPARE(two->y(), 52.0); + QCOMPARE(three->x(), 1.0); + QCOMPARE(three->y(), 62.0); + + obj->setLeftPadding(3.0); + + QCOMPARE(column->property("padding").toDouble(), 1.0); + QCOMPARE(column->property("topPadding").toDouble(), 2.0); + QCOMPARE(column->property("leftPadding").toDouble(), 3.0); + QCOMPARE(column->property("rightPadding").toDouble(), 1.0); + QCOMPARE(column->property("bottomPadding").toDouble(), 1.0); + + QTRY_COMPARE(column->width(), 54.0); + QCOMPARE(column->height(), 83.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 3.0); + QCOMPARE(two->y(), 52.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 62.0); + + obj->setRightPadding(4.0); + + QCOMPARE(column->property("padding").toDouble(), 1.0); + QCOMPARE(column->property("topPadding").toDouble(), 2.0); + QCOMPARE(column->property("leftPadding").toDouble(), 3.0); + QCOMPARE(column->property("rightPadding").toDouble(), 4.0); + QCOMPARE(column->property("bottomPadding").toDouble(), 1.0); + + QTRY_COMPARE(column->width(), 57.0); + QCOMPARE(column->height(), 83.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 3.0); + QCOMPARE(two->y(), 52.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 62.0); + + obj->setBottomPadding(5.0); + + QCOMPARE(column->property("padding").toDouble(), 1.0); + QCOMPARE(column->property("topPadding").toDouble(), 2.0); + QCOMPARE(column->property("leftPadding").toDouble(), 3.0); + QCOMPARE(column->property("rightPadding").toDouble(), 4.0); + QCOMPARE(column->property("bottomPadding").toDouble(), 5.0); + + QTRY_COMPARE(column->height(), 87.0); + QCOMPARE(column->width(), 57.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 3.0); + QCOMPARE(two->y(), 52.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 62.0); + + obj->resetBottomPadding(); + QCOMPARE(column->property("bottomPadding").toDouble(), 1.0); + QTRY_COMPARE(column->height(), 83.0); + QCOMPARE(column->width(), 57.0); + + obj->resetRightPadding(); + QCOMPARE(column->property("rightPadding").toDouble(), 1.0); + QTRY_COMPARE(column->width(), 54.0); + QCOMPARE(column->height(), 83.0); + + obj->resetLeftPadding(); + QCOMPARE(column->property("leftPadding").toDouble(), 1.0); + QTRY_COMPARE(column->width(), 52.0); + QCOMPARE(column->height(), 83.0); + + obj->resetTopPadding(); + QCOMPARE(column->property("topPadding").toDouble(), 1.0); + QTRY_COMPARE(column->height(), 82.0); + QCOMPARE(column->width(), 52.0); + + obj->resetPadding(); + QCOMPARE(column->property("padding").toDouble(), 0.0); + QCOMPARE(column->property("topPadding").toDouble(), 0.0); + QCOMPARE(column->property("leftPadding").toDouble(), 0.0); + QCOMPARE(column->property("rightPadding").toDouble(), 0.0); + QCOMPARE(column->property("bottomPadding").toDouble(), 0.0); + QTRY_COMPARE(column->height(), 80.0); + QCOMPARE(column->width(), 50.0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 0.0); + QCOMPARE(two->y(), 50.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 60.0); } void tst_qquickpositioners::test_vertical_spacing() @@ -968,6 +1631,22 @@ void tst_qquickpositioners::test_vertical_spacing() QCOMPARE(column->height(), 100.0); QCOMPARE(column->width(), 50.0); + // test padding + column->setProperty("padding", 1); + column->setProperty("topPadding", 2); + column->setProperty("leftPadding", 3); + column->setProperty("rightPadding", 4); + column->setProperty("bottomPadding", 5); + + QTRY_COMPARE(column->height(), 107.0); + QCOMPARE(column->width(), 57.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 3.0); + QCOMPARE(two->y(), 62.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 82.0); } void tst_qquickpositioners::test_vertical_animated() @@ -1019,6 +1698,66 @@ void tst_qquickpositioners::test_vertical_animated() } +void tst_qquickpositioners::test_vertical_animated_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("vertical-animated.qml"), false)); + + //Note that they animate in + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QVERIFY(one != 0); + QCOMPARE(one->y(), -100.0); + + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + QCOMPARE(two->y(), -100.0); + + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + QCOMPARE(three->y(), -100.0); + + QVERIFY(QTest::qWaitForWindowExposed(window.data())); //It may not relayout until the next frame, so it needs to be drawn + + QQuickItem *column = window->rootObject()->findChild<QQuickItem*>("column"); + QVERIFY(column); + QCOMPARE(column->height(), 100.0); + QCOMPARE(column->width(), 50.0); + + // test padding + column->setProperty("padding", 1); + column->setProperty("topPadding", 2); + column->setProperty("leftPadding", 3); + column->setProperty("rightPadding", 4); + column->setProperty("bottomPadding", 5); + + QTRY_COMPARE(column->height(), 107.0); + QCOMPARE(column->width(), 57.0); + + //QTRY_COMPARE used instead of waiting for the expected time of animation completion + //Note that this means the duration of the animation is NOT tested + + QTRY_COMPARE(one->y(), 2.0); + QTRY_COMPARE(one->x(), 3.0); + QTRY_COMPARE(two->isVisible(), false); + QTRY_COMPARE(two->y(), -100.0);//Not 'in' yet + QTRY_COMPARE(two->x(), 0.0); + QTRY_COMPARE(three->y(), 52.0); + QTRY_COMPARE(three->x(), 3.0); + + //Add 'two' + two->setVisible(true); + QTRY_COMPARE(two->isVisible(), true); + QTRY_COMPARE(column->height(), 157.0); + QTRY_COMPARE(column->width(), 57.0); + QTest::qWait(0);//Let the animation start + QVERIFY(two->y() >= -100.0 && two->y() < 52.0); + QVERIFY(three->y() >= 52.0 && three->y() < 102.0); + + QTRY_COMPARE(two->x(), 3.0); + QTRY_COMPARE(two->y(), 52.0); + QTRY_COMPARE(three->y(), 102.0); + +} + void tst_qquickpositioners::test_grid() { QScopedPointer<QQuickView> window(createView(testFile("gridtest.qml"))); @@ -1050,6 +1789,214 @@ void tst_qquickpositioners::test_grid() QCOMPARE(grid->width(), 100.0); QCOMPARE(grid->height(), 100.0); + // test padding + grid->setProperty("padding", 1); + grid->setProperty("topPadding", 2); + grid->setProperty("leftPadding", 3); + grid->setProperty("rightPadding", 4); + grid->setProperty("bottomPadding", 5); + + QTRY_COMPARE(grid->width(), 107.0); + QCOMPARE(grid->height(), 107.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 73.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 52.0); + QCOMPARE(five->x(), 53.0); + QCOMPARE(five->y(), 52.0); +} + +void tst_qquickpositioners::test_grid_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("gridtest.qml"))); + + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QVERIFY(one != 0); + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + QQuickRectangle *four = window->rootObject()->findChild<QQuickRectangle*>("four"); + QVERIFY(four != 0); + QQuickRectangle *five = window->rootObject()->findChild<QQuickRectangle*>("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 70.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 50.0); + QCOMPARE(five->x(), 50.0); + QCOMPARE(five->y(), 50.0); + + QQuickGrid *grid = window->rootObject()->findChild<QQuickGrid*>("grid"); + QCOMPARE(grid->flow(), QQuickGrid::LeftToRight); + QCOMPARE(grid->width(), 100.0); + QCOMPARE(grid->height(), 100.0); + + QCOMPARE(grid->property("padding").toDouble(), 0.0); + QCOMPARE(grid->property("topPadding").toDouble(), 0.0); + QCOMPARE(grid->property("leftPadding").toDouble(), 0.0); + QCOMPARE(grid->property("rightPadding").toDouble(), 0.0); + QCOMPARE(grid->property("bottomPadding").toDouble(), 0.0); + + grid->setPadding(1.0); + + QCOMPARE(grid->property("padding").toDouble(), 1.0); + QCOMPARE(grid->property("topPadding").toDouble(), 1.0); + QCOMPARE(grid->property("leftPadding").toDouble(), 1.0); + QCOMPARE(grid->property("rightPadding").toDouble(), 1.0); + QCOMPARE(grid->property("bottomPadding").toDouble(), 1.0); + + QTRY_COMPARE(grid->width(), 102.0); + QCOMPARE(grid->height(), 102.0); + + QCOMPARE(one->x(), 1.0); + QCOMPARE(one->y(), 1.0); + QCOMPARE(two->x(), 51.0); + QCOMPARE(two->y(), 1.0); + QCOMPARE(three->x(), 71.0); + QCOMPARE(three->y(), 1.0); + QCOMPARE(four->x(), 1.0); + QCOMPARE(four->y(), 51.0); + QCOMPARE(five->x(), 51.0); + QCOMPARE(five->y(), 51.0); + + grid->setTopPadding(2.0); + + QCOMPARE(grid->property("padding").toDouble(), 1.0); + QCOMPARE(grid->property("topPadding").toDouble(), 2.0); + QCOMPARE(grid->property("leftPadding").toDouble(), 1.0); + QCOMPARE(grid->property("rightPadding").toDouble(), 1.0); + QCOMPARE(grid->property("bottomPadding").toDouble(), 1.0); + + QTRY_COMPARE(grid->height(), 103.0); + QCOMPARE(grid->width(), 102.0); + + QCOMPARE(one->x(), 1.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 51.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 71.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 1.0); + QCOMPARE(four->y(), 52.0); + QCOMPARE(five->x(), 51.0); + QCOMPARE(five->y(), 52.0); + + grid->setLeftPadding(3.0); + + QCOMPARE(grid->property("padding").toDouble(), 1.0); + QCOMPARE(grid->property("topPadding").toDouble(), 2.0); + QCOMPARE(grid->property("leftPadding").toDouble(), 3.0); + QCOMPARE(grid->property("rightPadding").toDouble(), 1.0); + QCOMPARE(grid->property("bottomPadding").toDouble(), 1.0); + + QTRY_COMPARE(grid->width(), 104.0); + QCOMPARE(grid->height(), 103.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 73.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 52.0); + QCOMPARE(five->x(), 53.0); + QCOMPARE(five->y(), 52.0); + + grid->setRightPadding(4.0); + + QCOMPARE(grid->property("padding").toDouble(), 1.0); + QCOMPARE(grid->property("topPadding").toDouble(), 2.0); + QCOMPARE(grid->property("leftPadding").toDouble(), 3.0); + QCOMPARE(grid->property("rightPadding").toDouble(), 4.0); + QCOMPARE(grid->property("bottomPadding").toDouble(), 1.0); + + QTRY_COMPARE(grid->width(), 107.0); + QCOMPARE(grid->height(), 103.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 73.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 52.0); + QCOMPARE(five->x(), 53.0); + QCOMPARE(five->y(), 52.0); + + grid->setBottomPadding(5.0); + + QCOMPARE(grid->property("padding").toDouble(), 1.0); + QCOMPARE(grid->property("topPadding").toDouble(), 2.0); + QCOMPARE(grid->property("leftPadding").toDouble(), 3.0); + QCOMPARE(grid->property("rightPadding").toDouble(), 4.0); + QCOMPARE(grid->property("bottomPadding").toDouble(), 5.0); + + QTRY_COMPARE(grid->height(), 107.0); + QCOMPARE(grid->width(), 107.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 73.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 52.0); + QCOMPARE(five->x(), 53.0); + QCOMPARE(five->y(), 52.0); + + grid->resetBottomPadding(); + QCOMPARE(grid->property("bottomPadding").toDouble(), 1.0); + QTRY_COMPARE(grid->height(), 103.0); + QCOMPARE(grid->width(), 107.0); + + grid->resetRightPadding(); + QCOMPARE(grid->property("rightPadding").toDouble(), 1.0); + QTRY_COMPARE(grid->width(), 104.0); + QCOMPARE(grid->height(), 103.0); + + grid->resetLeftPadding(); + QCOMPARE(grid->property("leftPadding").toDouble(), 1.0); + QTRY_COMPARE(grid->width(), 102.0); + QCOMPARE(grid->height(), 103.0); + + grid->resetTopPadding(); + QCOMPARE(grid->property("topPadding").toDouble(), 1.0); + QTRY_COMPARE(grid->height(), 102.0); + QCOMPARE(grid->width(), 102.0); + + grid->resetPadding(); + QCOMPARE(grid->property("padding").toDouble(), 0.0); + QCOMPARE(grid->property("topPadding").toDouble(), 0.0); + QCOMPARE(grid->property("leftPadding").toDouble(), 0.0); + QCOMPARE(grid->property("rightPadding").toDouble(), 0.0); + QCOMPARE(grid->property("bottomPadding").toDouble(), 0.0); + QTRY_COMPARE(grid->height(), 100.0); + QCOMPARE(grid->width(), 100.0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 70.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 50.0); + QCOMPARE(five->x(), 50.0); + QCOMPARE(five->y(), 50.0); } void tst_qquickpositioners::test_grid_topToBottom() @@ -1083,6 +2030,26 @@ void tst_qquickpositioners::test_grid_topToBottom() QCOMPARE(grid->width(), 100.0); QCOMPARE(grid->height(), 120.0); + // test padding + grid->setProperty("padding", 1); + grid->setProperty("topPadding", 2); + grid->setProperty("leftPadding", 3); + grid->setProperty("rightPadding", 4); + grid->setProperty("bottomPadding", 5); + + QTRY_COMPARE(grid->width(), 107.0); + QCOMPARE(grid->height(), 127.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 3.0); + QCOMPARE(two->y(), 52.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 102.0); + QCOMPARE(four->x(), 53.0); + QCOMPARE(four->y(), 2.0); + QCOMPARE(five->x(), 53.0); + QCOMPARE(five->y(), 52.0); } void tst_qquickpositioners::test_grid_rightToLeft() @@ -1118,6 +2085,44 @@ void tst_qquickpositioners::test_grid_rightToLeft() QCOMPARE(grid->width(), 100.0); QCOMPARE(grid->height(), 100.0); + // test padding + grid->setProperty("padding", 1); + grid->setProperty("topPadding", 2); + grid->setProperty("leftPadding", 3); + grid->setProperty("rightPadding", 4); + grid->setProperty("bottomPadding", 5); + + QTRY_COMPARE(grid->width(), 107.0); + QCOMPARE(grid->height(), 107.0); + + QCOMPARE(one->x(), 53.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 33.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 53.0); + QCOMPARE(four->y(), 52.0); + QCOMPARE(five->x(), 43.0); + QCOMPARE(five->y(), 52.0); + + grid->setProperty("topPadding", 0); + grid->setProperty("leftPadding", 0); + grid->setProperty("rightPadding", 0); + grid->setProperty("bottomPadding", 0); + grid->setProperty("padding", 0); + + QTRY_COMPARE(one->x(), 50.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 30.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 50.0); + QCOMPARE(four->y(), 50.0); + QCOMPARE(five->x(), 40.0); + QCOMPARE(five->y(), 50.0); + // Change the width of the grid and check that items stay to the right grid->setWidth(200); QTRY_COMPARE(one->x(), 150.0); @@ -1131,6 +2136,22 @@ void tst_qquickpositioners::test_grid_rightToLeft() QCOMPARE(five->x(), 140.0); QCOMPARE(five->y(), 50.0); + grid->setProperty("padding", 1); + grid->setProperty("topPadding", 2); + grid->setProperty("leftPadding", 3); + grid->setProperty("rightPadding", 4); + grid->setProperty("bottomPadding", 5); + + QTRY_COMPARE(one->x(), 146.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 126.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 96.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 146.0); + QCOMPARE(four->y(), 52.0); + QCOMPARE(five->x(), 136.0); + QCOMPARE(five->y(), 52.0); } void tst_qquickpositioners::test_grid_spacing() @@ -1163,6 +2184,26 @@ void tst_qquickpositioners::test_grid_spacing() QCOMPARE(grid->width(), 128.0); QCOMPARE(grid->height(), 104.0); + // test padding + grid->setProperty("padding", 1); + grid->setProperty("topPadding", 2); + grid->setProperty("leftPadding", 3); + grid->setProperty("rightPadding", 4); + grid->setProperty("bottomPadding", 5); + + QTRY_COMPARE(grid->width(), 135.0); + QCOMPARE(grid->height(), 111.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 57.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 81.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 56.0); + QCOMPARE(five->x(), 57.0); + QCOMPARE(five->y(), 56.0); } void tst_qquickpositioners::test_grid_row_column_spacing() @@ -1195,6 +2236,26 @@ void tst_qquickpositioners::test_grid_row_column_spacing() QCOMPARE(grid->width(), 142.0); QCOMPARE(grid->height(), 107.0); + // test padding + grid->setProperty("padding", 1); + grid->setProperty("topPadding", 2); + grid->setProperty("leftPadding", 3); + grid->setProperty("rightPadding", 4); + grid->setProperty("bottomPadding", 5); + + QTRY_COMPARE(grid->width(), 149.0); + QCOMPARE(grid->height(), 114.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 64.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 95.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 59.0); + QCOMPARE(five->x(), 64.0); + QCOMPARE(five->y(), 59.0); } void tst_qquickpositioners::test_grid_animated() @@ -1281,6 +2342,100 @@ void tst_qquickpositioners::test_grid_animated() } +void tst_qquickpositioners::test_grid_animated_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("grid-animated.qml"), false)); + + window->rootObject()->setProperty("testRightToLeft", false); + + //Note that all animate in + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QVERIFY(one != 0); + QCOMPARE(one->x(), -100.0); + QCOMPARE(one->y(), -100.0); + + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + QCOMPARE(two->x(), -100.0); + QCOMPARE(two->y(), -100.0); + + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + QCOMPARE(three->x(), -100.0); + QCOMPARE(three->y(), -100.0); + + QQuickRectangle *four = window->rootObject()->findChild<QQuickRectangle*>("four"); + QVERIFY(four != 0); + QCOMPARE(four->x(), -100.0); + QCOMPARE(four->y(), -100.0); + + QQuickRectangle *five = window->rootObject()->findChild<QQuickRectangle*>("five"); + QVERIFY(five != 0); + QCOMPARE(five->x(), -100.0); + QCOMPARE(five->y(), -100.0); + + QVERIFY(QTest::qWaitForWindowExposed(window.data())); //It may not relayout until the next frame, so it needs to be drawn + + QQuickItem *grid = window->rootObject()->findChild<QQuickItem*>("grid"); + QVERIFY(grid); + QCOMPARE(grid->width(), 150.0); + QCOMPARE(grid->height(), 100.0); + + // test padding + grid->setProperty("padding", 1); + grid->setProperty("topPadding", 2); + grid->setProperty("leftPadding", 3); + grid->setProperty("rightPadding", 4); + grid->setProperty("bottomPadding", 5); + + QTRY_COMPARE(grid->width(), 157.0); + QCOMPARE(grid->height(), 107.0); + + //QTRY_COMPARE used instead of waiting for the expected time of animation completion + //Note that this means the duration of the animation is NOT tested + + QTRY_COMPARE(one->y(), 2.0); + QTRY_COMPARE(one->x(), 3.0); + QTRY_COMPARE(two->isVisible(), false); + QTRY_COMPARE(two->y(), -100.0); + QTRY_COMPARE(two->x(), -100.0); + QTRY_COMPARE(three->y(), 2.0); + QTRY_COMPARE(three->x(), 53.0); + QTRY_COMPARE(four->y(), 2.0); + QTRY_COMPARE(four->x(), 103.0); + QTRY_COMPARE(five->y(), 52.0); + QTRY_COMPARE(five->x(), 3.0); + + //Add 'two' + two->setVisible(true); + QCOMPARE(two->isVisible(), true); + QCOMPARE(grid->width(), 157.0); + QCOMPARE(grid->height(), 107.0); + QTest::qWait(0);//Let the animation start + QCOMPARE(two->x(), -100.0); + QCOMPARE(two->y(), -100.0); + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(three->x(), 53.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 103.0); + QCOMPARE(four->y(), 2.0); + QCOMPARE(five->x(), 3.0); + QCOMPARE(five->y(), 52.0); + //Let the animation complete + QTRY_COMPARE(two->x(), 53.0); + QTRY_COMPARE(two->y(), 2.0); + QTRY_COMPARE(one->x(), 3.0); + QTRY_COMPARE(one->y(), 2.0); + QTRY_COMPARE(three->x(), 103.0); + QTRY_COMPARE(three->y(), 2.0); + QTRY_COMPARE(four->x(), 3.0); + QTRY_COMPARE(four->y(), 52.0); + QTRY_COMPARE(five->x(), 53.0); + QTRY_COMPARE(five->y(), 52.0); + +} + void tst_qquickpositioners::test_grid_animated_rightToLeft() { QScopedPointer<QQuickView> window(createView(testFile("grid-animated.qml"), false)); @@ -1365,6 +2520,100 @@ void tst_qquickpositioners::test_grid_animated_rightToLeft() } +void tst_qquickpositioners::test_grid_animated_rightToLeft_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("grid-animated.qml"), false)); + + window->rootObject()->setProperty("testRightToLeft", true); + + //Note that all animate in + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QVERIFY(one != 0); + QCOMPARE(one->x(), -100.0); + QCOMPARE(one->y(), -100.0); + + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + QCOMPARE(two->x(), -100.0); + QCOMPARE(two->y(), -100.0); + + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + QCOMPARE(three->x(), -100.0); + QCOMPARE(three->y(), -100.0); + + QQuickRectangle *four = window->rootObject()->findChild<QQuickRectangle*>("four"); + QVERIFY(four != 0); + QCOMPARE(four->x(), -100.0); + QCOMPARE(four->y(), -100.0); + + QQuickRectangle *five = window->rootObject()->findChild<QQuickRectangle*>("five"); + QVERIFY(five != 0); + QCOMPARE(five->x(), -100.0); + QCOMPARE(five->y(), -100.0); + + QVERIFY(QTest::qWaitForWindowExposed(window.data())); //It may not relayout until the next frame, so it needs to be drawn + + QQuickItem *grid = window->rootObject()->findChild<QQuickItem*>("grid"); + QVERIFY(grid); + QCOMPARE(grid->width(), 150.0); + QCOMPARE(grid->height(), 100.0); + + // test padding + grid->setProperty("padding", 1); + grid->setProperty("topPadding", 2); + grid->setProperty("leftPadding", 3); + grid->setProperty("rightPadding", 4); + grid->setProperty("bottomPadding", 5); + + QTRY_COMPARE(grid->width(), 157.0); + QCOMPARE(grid->height(), 107.0); + + //QTRY_COMPARE used instead of waiting for the expected time of animation completion + //Note that this means the duration of the animation is NOT tested + + QTRY_COMPARE(one->y(), 2.0); + QTRY_COMPARE(one->x(), 103.0); + QTRY_COMPARE(two->isVisible(), false); + QTRY_COMPARE(two->y(), -100.0); + QTRY_COMPARE(two->x(), -100.0); + QTRY_COMPARE(three->y(), 2.0); + QTRY_COMPARE(three->x(), 53.0); + QTRY_COMPARE(four->y(), 2.0); + QTRY_COMPARE(four->x(), 3.0); + QTRY_COMPARE(five->y(), 52.0); + QTRY_COMPARE(five->x(), 103.0); + + //Add 'two' + two->setVisible(true); + QCOMPARE(two->isVisible(), true); + QCOMPARE(grid->width(), 157.0); + QCOMPARE(grid->height(), 107.0); + QTest::qWait(0);//Let the animation start + QCOMPARE(two->x(), -100.0); + QCOMPARE(two->y(), -100.0); + QCOMPARE(one->x(), 103.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(three->x(), 53.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 2.0); + QCOMPARE(five->x(), 103.0); + QCOMPARE(five->y(), 52.0); + //Let the animation complete + QTRY_COMPARE(two->x(), 53.0); + QTRY_COMPARE(two->y(), 2.0); + QTRY_COMPARE(one->x(), 103.0); + QTRY_COMPARE(one->y(), 2.0); + QTRY_COMPARE(three->x(), 3.0); + QTRY_COMPARE(three->y(), 2.0); + QTRY_COMPARE(four->x(), 103.0); + QTRY_COMPARE(four->y(), 52.0); + QTRY_COMPARE(five->x(), 53.0); + QTRY_COMPARE(five->y(), 52.0); + +} + void tst_qquickpositioners::test_grid_zero_columns() { QScopedPointer<QQuickView> window(createView(testFile("gridzerocolumns.qml"))); @@ -1395,6 +2644,26 @@ void tst_qquickpositioners::test_grid_zero_columns() QCOMPARE(grid->width(), 170.0); QCOMPARE(grid->height(), 60.0); + // test padding + grid->setProperty("padding", 1); + grid->setProperty("topPadding", 2); + grid->setProperty("leftPadding", 3); + grid->setProperty("rightPadding", 4); + grid->setProperty("bottomPadding", 5); + + QTRY_COMPARE(grid->width(), 177.0); + QCOMPARE(grid->height(), 67.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 73.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 123.0); + QCOMPARE(four->y(), 2.0); + QCOMPARE(five->x(), 3.0); + QCOMPARE(five->y(), 52.0); } void tst_qquickpositioners::test_grid_H_alignment() @@ -1476,6 +2745,95 @@ void tst_qquickpositioners::test_grid_H_alignment() } +void tst_qquickpositioners::test_grid_H_alignment_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("gridtest.qml"))); + + window->rootObject()->setProperty("testHAlignment", QQuickGrid::AlignHCenter); + + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QVERIFY(one != 0); + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + QQuickRectangle *four = window->rootObject()->findChild<QQuickRectangle*>("four"); + QVERIFY(four != 0); + QQuickRectangle *five = window->rootObject()->findChild<QQuickRectangle*>("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 70.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 50.0); + QCOMPARE(five->x(), 55.0); + QCOMPARE(five->y(), 50.0); + + QQuickItem *grid = window->rootObject()->findChild<QQuickItem*>("grid"); + QCOMPARE(grid->width(), 100.0); + QCOMPARE(grid->height(), 100.0); + + // test padding + grid->setProperty("padding", 1); + grid->setProperty("topPadding", 2); + grid->setProperty("leftPadding", 3); + grid->setProperty("rightPadding", 4); + grid->setProperty("bottomPadding", 5); + + QTRY_COMPARE(grid->width(), 107.0); + QCOMPARE(grid->height(), 107.0); + + window->rootObject()->setProperty("testHAlignment", QQuickGrid::AlignRight); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 73.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 52.0); + QCOMPARE(five->x(), 63.0); + QCOMPARE(five->y(), 52.0); + QCOMPARE(grid->width(), 107.0); + QCOMPARE(grid->height(), 107.0); + + window->rootObject()->setProperty("testRightToLeft", true); + + QCOMPARE(one->x(), 53.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 33.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 53.0); + QCOMPARE(four->y(), 52.0); + QCOMPARE(five->x(), 33.0); + QCOMPARE(five->y(), 52.0); + QCOMPARE(grid->width(), 107.0); + QCOMPARE(grid->height(), 107.0); + + window->rootObject()->setProperty("testHAlignment", QQuickGrid::AlignHCenter); + + QCOMPARE(one->x(), 53.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 33.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 2.0); + QCOMPARE(four->x(), 53.0); + QCOMPARE(four->y(), 52.0); + QCOMPARE(five->x(), 38.0); + QCOMPARE(five->y(), 52.0); + QCOMPARE(grid->width(), 107.0); + QCOMPARE(grid->height(), 107.0); + +} + void tst_qquickpositioners::test_grid_V_alignment() { QScopedPointer<QQuickView> window(createView(testFile("gridtest.qml"))); @@ -1519,6 +2877,63 @@ void tst_qquickpositioners::test_grid_V_alignment() } +void tst_qquickpositioners::test_grid_V_alignment_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("gridtest.qml"))); + + window->rootObject()->setProperty("testVAlignment", QQuickGrid::AlignVCenter); + + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QVERIFY(one != 0); + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + QQuickRectangle *four = window->rootObject()->findChild<QQuickRectangle*>("four"); + QVERIFY(four != 0); + QQuickRectangle *five = window->rootObject()->findChild<QQuickRectangle*>("five"); + QVERIFY(five != 0); + + QQuickItem *grid = window->rootObject()->findChild<QQuickItem*>("grid"); + QCOMPARE(grid->width(), 100.0); + QCOMPARE(grid->height(), 100.0); + + // test padding + grid->setProperty("padding", 1); + grid->setProperty("topPadding", 2); + grid->setProperty("leftPadding", 3); + grid->setProperty("rightPadding", 4); + grid->setProperty("bottomPadding", 5); + + QTRY_COMPARE(grid->width(), 107.0); + QCOMPARE(grid->height(), 107.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 73.0); + QCOMPARE(three->y(), 17.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 52.0); + QCOMPARE(five->x(), 53.0); + QCOMPARE(five->y(), 72.0); + + window->rootObject()->setProperty("testVAlignment", QQuickGrid::AlignBottom); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 73.0); + QCOMPARE(three->y(), 32.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 52.0); + QCOMPARE(five->x(), 53.0); + QCOMPARE(five->y(), 92.0); + +} + void tst_qquickpositioners::test_propertychanges() { QScopedPointer<QQuickView> window(createView(testFile("propertychangestest.qml"))); @@ -1599,6 +3014,28 @@ void tst_qquickpositioners::test_repeater() } +void tst_qquickpositioners::test_repeater_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("repeatertest-padding.qml"))); + + QQuickRectangle *one = findItem<QQuickRectangle>(window->contentItem(), "one"); + QVERIFY(one != 0); + + QQuickRectangle *two = findItem<QQuickRectangle>(window->contentItem(), "two"); + QVERIFY(two != 0); + + QQuickRectangle *three = findItem<QQuickRectangle>(window->contentItem(), "three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 103.0); + QCOMPARE(three->y(), 2.0); + +} + void tst_qquickpositioners::test_flow() { QScopedPointer<QQuickView> window(createView(testFile("flowtest.qml"))); @@ -1632,6 +3069,219 @@ void tst_qquickpositioners::test_flow() QCOMPARE(flow->width(), 90.0); QCOMPARE(flow->height(), 120.0); + // test padding + flow->setProperty("padding", 1); + flow->setProperty("topPadding", 2); + flow->setProperty("leftPadding", 3); + flow->setProperty("rightPadding", 4); + flow->setProperty("bottomPadding", 5); + + QTRY_COMPARE(flow->height(), 127.0); + QCOMPARE(flow->width(), 90.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 52.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 72.0); + QCOMPARE(five->x(), 53.0); + QCOMPARE(five->y(), 72.0); +} + +void tst_qquickpositioners::test_flow_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("flowtest.qml"))); + + window->rootObject()->setProperty("testRightToLeft", false); + + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QVERIFY(one != 0); + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + QQuickRectangle *four = window->rootObject()->findChild<QQuickRectangle*>("four"); + QVERIFY(four != 0); + QQuickRectangle *five = window->rootObject()->findChild<QQuickRectangle*>("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 50.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 70.0); + QCOMPARE(five->x(), 50.0); + QCOMPARE(five->y(), 70.0); + + QQuickItem *flow = window->rootObject()->findChild<QQuickItem*>("flow"); + QVERIFY(flow); + QCOMPARE(flow->width(), 90.0); + QCOMPARE(flow->height(), 120.0); + + QQuickFlow *obj = qobject_cast<QQuickFlow*>(flow); + QVERIFY(obj != 0); + + QCOMPARE(flow->property("padding").toDouble(), 0.0); + QCOMPARE(flow->property("topPadding").toDouble(), 0.0); + QCOMPARE(flow->property("leftPadding").toDouble(), 0.0); + QCOMPARE(flow->property("rightPadding").toDouble(), 0.0); + QCOMPARE(flow->property("bottomPadding").toDouble(), 0.0); + + obj->setPadding(1.0); + + QCOMPARE(flow->property("padding").toDouble(), 1.0); + QCOMPARE(flow->property("topPadding").toDouble(), 1.0); + QCOMPARE(flow->property("leftPadding").toDouble(), 1.0); + QCOMPARE(flow->property("rightPadding").toDouble(), 1.0); + QCOMPARE(flow->property("bottomPadding").toDouble(), 1.0); + + QTRY_COMPARE(flow->height(), 122.0); + QCOMPARE(flow->width(), 90.0); + + QCOMPARE(one->x(), 1.0); + QCOMPARE(one->y(), 1.0); + QCOMPARE(two->x(), 51.0); + QCOMPARE(two->y(), 1.0); + QCOMPARE(three->x(), 1.0); + QCOMPARE(three->y(), 51.0); + QCOMPARE(four->x(), 1.0); + QCOMPARE(four->y(), 71.0); + QCOMPARE(five->x(), 51.0); + QCOMPARE(five->y(), 71.0); + + obj->setTopPadding(2.0); + + QCOMPARE(flow->property("padding").toDouble(), 1.0); + QCOMPARE(flow->property("topPadding").toDouble(), 2.0); + QCOMPARE(flow->property("leftPadding").toDouble(), 1.0); + QCOMPARE(flow->property("rightPadding").toDouble(), 1.0); + QCOMPARE(flow->property("bottomPadding").toDouble(), 1.0); + + QTRY_COMPARE(flow->height(), 123.0); + QCOMPARE(flow->width(), 90.0); + + QCOMPARE(one->x(), 1.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 51.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 1.0); + QCOMPARE(three->y(), 52.0); + QCOMPARE(four->x(), 1.0); + QCOMPARE(four->y(), 72.0); + QCOMPARE(five->x(), 51.0); + QCOMPARE(five->y(), 72.0); + + obj->setLeftPadding(3.0); + + QCOMPARE(flow->property("padding").toDouble(), 1.0); + QCOMPARE(flow->property("topPadding").toDouble(), 2.0); + QCOMPARE(flow->property("leftPadding").toDouble(), 3.0); + QCOMPARE(flow->property("rightPadding").toDouble(), 1.0); + QCOMPARE(flow->property("bottomPadding").toDouble(), 1.0); + + QCOMPARE(flow->height(), 123.0); + QCOMPARE(flow->width(), 90.0); + + QTRY_COMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 52.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 72.0); + QCOMPARE(five->x(), 53.0); + QCOMPARE(five->y(), 72.0); + + obj->setRightPadding(4.0); + + QCOMPARE(flow->property("padding").toDouble(), 1.0); + QCOMPARE(flow->property("topPadding").toDouble(), 2.0); + QCOMPARE(flow->property("leftPadding").toDouble(), 3.0); + QCOMPARE(flow->property("rightPadding").toDouble(), 4.0); + QCOMPARE(flow->property("bottomPadding").toDouble(), 1.0); + + QCOMPARE(flow->height(), 123.0); + QCOMPARE(flow->width(), 90.0); + + QTRY_COMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 52.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 72.0); + QCOMPARE(five->x(), 53.0); + QCOMPARE(five->y(), 72.0); + + obj->setBottomPadding(5.0); + + QCOMPARE(flow->property("padding").toDouble(), 1.0); + QCOMPARE(flow->property("topPadding").toDouble(), 2.0); + QCOMPARE(flow->property("leftPadding").toDouble(), 3.0); + QCOMPARE(flow->property("rightPadding").toDouble(), 4.0); + QCOMPARE(flow->property("bottomPadding").toDouble(), 5.0); + + QTRY_COMPARE(flow->height(), 127.0); + QCOMPARE(flow->width(), 90.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 3.0); + QCOMPARE(three->y(), 52.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 72.0); + QCOMPARE(five->x(), 53.0); + QCOMPARE(five->y(), 72.0); + + obj->resetBottomPadding(); + QCOMPARE(flow->property("bottomPadding").toDouble(), 1.0); + QTRY_COMPARE(flow->height(), 123.0); + QCOMPARE(flow->width(), 90.0); + + obj->resetRightPadding(); + QCOMPARE(flow->property("rightPadding").toDouble(), 1.0); + QTRY_COMPARE(flow->height(), 123.0); + QCOMPARE(flow->width(), 90.0); + + obj->resetLeftPadding(); + QCOMPARE(flow->property("leftPadding").toDouble(), 1.0); + QTRY_COMPARE(flow->height(), 123.0); + QCOMPARE(flow->width(), 90.0); + + obj->resetTopPadding(); + QCOMPARE(flow->property("topPadding").toDouble(), 1.0); + QTRY_COMPARE(flow->height(), 122.0); + QCOMPARE(flow->width(), 90.0); + + obj->resetPadding(); + QCOMPARE(flow->property("padding").toDouble(), 0.0); + QCOMPARE(flow->property("topPadding").toDouble(), 0.0); + QCOMPARE(flow->property("leftPadding").toDouble(), 0.0); + QCOMPARE(flow->property("rightPadding").toDouble(), 0.0); + QCOMPARE(flow->property("bottomPadding").toDouble(), 0.0); + QTRY_COMPARE(flow->height(), 120.0); + QCOMPARE(flow->width(), 90.0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 50.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 70.0); + QCOMPARE(five->x(), 50.0); + QCOMPARE(five->y(), 70.0); } void tst_qquickpositioners::test_flow_rightToLeft() @@ -1667,6 +3317,26 @@ void tst_qquickpositioners::test_flow_rightToLeft() QCOMPARE(flow->width(), 90.0); QCOMPARE(flow->height(), 120.0); + // test padding + flow->setProperty("padding", 1); + flow->setProperty("topPadding", 2); + flow->setProperty("leftPadding", 3); + flow->setProperty("rightPadding", 4); + flow->setProperty("bottomPadding", 5); + + QTRY_COMPARE(flow->height(), 127.0); + QCOMPARE(flow->width(), 90.0); + + QCOMPARE(one->x(), 36.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 16.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 36.0); + QCOMPARE(three->y(), 52.0); + QCOMPARE(four->x(), 36.0); + QCOMPARE(four->y(), 72.0); + QCOMPARE(five->x(), 26.0); + QCOMPARE(five->y(), 72.0); } void tst_qquickpositioners::test_flow_topToBottom() @@ -1693,7 +3363,7 @@ void tst_qquickpositioners::test_flow_topToBottom() QCOMPARE(three->x(), 50.0); QCOMPARE(three->y(), 50.0); QCOMPARE(four->x(), 100.0); - QCOMPARE(four->y(), 00.0); + QCOMPARE(four->y(), 0.0); QCOMPARE(five->x(), 100.0); QCOMPARE(five->y(), 50.0); @@ -1721,6 +3391,79 @@ void tst_qquickpositioners::test_flow_topToBottom() } +void tst_qquickpositioners::test_flow_topToBottom_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("flowtest-toptobottom.qml"))); + + window->rootObject()->setProperty("testRightToLeft", false); + + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QVERIFY(one != 0); + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + QQuickRectangle *four = window->rootObject()->findChild<QQuickRectangle*>("four"); + QVERIFY(four != 0); + QQuickRectangle *five = window->rootObject()->findChild<QQuickRectangle*>("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 50.0); + QCOMPARE(three->y(), 50.0); + QCOMPARE(four->x(), 100.0); + QCOMPARE(four->y(), 0.0); + QCOMPARE(five->x(), 100.0); + QCOMPARE(five->y(), 50.0); + + QQuickItem *flow = window->rootObject()->findChild<QQuickItem*>("flow"); + QVERIFY(flow); + QCOMPARE(flow->height(), 90.0); + QCOMPARE(flow->width(), 150.0); + + // test padding + flow->setProperty("padding", 1); + flow->setProperty("topPadding", 2); + flow->setProperty("leftPadding", 3); + flow->setProperty("rightPadding", 4); + flow->setProperty("bottomPadding", 5); + + QTRY_COMPARE(flow->width(), 157.0); + QCOMPARE(flow->height(), 90.0); + + QCOMPARE(one->x(), 3.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 53.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 53.0); + QCOMPARE(three->y(), 52.0); + QCOMPARE(four->x(), 103.0); + QCOMPARE(four->y(), 2.0); + QCOMPARE(five->x(), 103.0); + QCOMPARE(five->y(), 52.0); + + window->rootObject()->setProperty("testRightToLeft", true); + + QVERIFY(flow); + QTRY_COMPARE(flow->width(), 157.0); + QCOMPARE(flow->height(), 90.0); + + QCOMPARE(one->x(), 103.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 83.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 53.0); + QCOMPARE(three->y(), 52.0); + QCOMPARE(four->x(), 3.0); + QCOMPARE(four->y(), 2.0); + QCOMPARE(five->x(), 43.0); + QCOMPARE(five->y(), 52.0); + +} + void tst_qquickpositioners::test_flow_resize() { QScopedPointer<QQuickView> window(createView(testFile("flowtest.qml"))); @@ -1754,6 +3497,39 @@ void tst_qquickpositioners::test_flow_resize() } +void tst_qquickpositioners::test_flow_resize_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("flowtest-padding.qml"))); + + QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject()); + QVERIFY(root); + root->setWidth(125); + root->setProperty("testRightToLeft", false); + + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QVERIFY(one != 0); + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + QQuickRectangle *four = window->rootObject()->findChild<QQuickRectangle*>("four"); + QVERIFY(four != 0); + QQuickRectangle *five = window->rootObject()->findChild<QQuickRectangle*>("five"); + QVERIFY(five != 0); + + QTRY_COMPARE(one->x(), 3.0); + QTRY_COMPARE(one->y(), 2.0); + QTRY_COMPARE(two->x(), 53.0); + QTRY_COMPARE(two->y(), 2.0); + QTRY_COMPARE(three->x(), 3.0); + QTRY_COMPARE(three->y(), 52.0); + QTRY_COMPARE(four->x(), 53.0); + QTRY_COMPARE(four->y(), 52.0); + QTRY_COMPARE(five->x(), 103.0); + QTRY_COMPARE(five->y(), 52.0); + +} + void tst_qquickpositioners::test_flow_resize_rightToLeft() { QScopedPointer<QQuickView> window(createView(testFile("flowtest.qml"))); @@ -1787,6 +3563,39 @@ void tst_qquickpositioners::test_flow_resize_rightToLeft() } +void tst_qquickpositioners::test_flow_resize_rightToLeft_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("flowtest-padding.qml"))); + + QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject()); + QVERIFY(root); + root->setWidth(125); + root->setProperty("testRightToLeft", true); + + QQuickRectangle *one = window->rootObject()->findChild<QQuickRectangle*>("one"); + QTRY_VERIFY(one != 0); + QQuickRectangle *two = window->rootObject()->findChild<QQuickRectangle*>("two"); + QVERIFY(two != 0); + QQuickRectangle *three = window->rootObject()->findChild<QQuickRectangle*>("three"); + QVERIFY(three != 0); + QQuickRectangle *four = window->rootObject()->findChild<QQuickRectangle*>("four"); + QVERIFY(four != 0); + QQuickRectangle *five = window->rootObject()->findChild<QQuickRectangle*>("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 71.0); + QCOMPARE(one->y(), 2.0); + QCOMPARE(two->x(), 51.0); + QCOMPARE(two->y(), 2.0); + QCOMPARE(three->x(), 71.0); + QCOMPARE(three->y(), 52.0); + QCOMPARE(four->x(), 21.0); + QCOMPARE(four->y(), 52.0); + QCOMPARE(five->x(), 11.0); + QCOMPARE(five->y(), 52.0); + +} + void tst_qquickpositioners::test_flow_implicit_resize() { QScopedPointer<QQuickView> window(createView(testFile("flow-testimplicitsize.qml"))); @@ -1815,6 +3624,44 @@ void tst_qquickpositioners::test_flow_implicit_resize() } +void tst_qquickpositioners::test_flow_implicit_resize_padding() +{ + QScopedPointer<QQuickView> window(createView(testFile("flow-testimplicitsize.qml"))); + QVERIFY(window->rootObject() != 0); + + QQuickFlow *flow = window->rootObject()->findChild<QQuickFlow*>("flow"); + QVERIFY(flow != 0); + + QCOMPARE(flow->width(), 100.0); + QCOMPARE(flow->height(), 120.0); + + // test padding + flow->setProperty("padding", 1); + flow->setProperty("topPadding", 2); + flow->setProperty("leftPadding", 3); + flow->setProperty("rightPadding", 4); + flow->setProperty("bottomPadding", 5); + + QTRY_COMPARE(flow->width(), 107.0); + QCOMPARE(flow->height(), 127.0); + + window->rootObject()->setProperty("flowLayout", 0); + QCOMPARE(flow->flow(), QQuickFlow::LeftToRight); + QCOMPARE(flow->width(), 227.0); + QCOMPARE(flow->height(), 57.0); + + window->rootObject()->setProperty("flowLayout", 1); + QCOMPARE(flow->flow(), QQuickFlow::TopToBottom); + QCOMPARE(flow->width(), 107.0); + QCOMPARE(flow->height(), 127.0); + + window->rootObject()->setProperty("flowLayout", 2); + QCOMPARE(flow->layoutDirection(), Qt::RightToLeft); + QCOMPARE(flow->width(), 227.0); + QCOMPARE(flow->height(), 57.0); + +} + void tst_qquickpositioners::test_conflictinganchors() { QQmlTestMessageHandler messageHandler; @@ -1924,7 +3771,9 @@ void tst_qquickpositioners::test_conflictinganchors() void tst_qquickpositioners::test_mirroring() { QList<QString> qmlFiles; - qmlFiles << "horizontal.qml" << "gridtest.qml" << "flowtest.qml"; + qmlFiles << "horizontal.qml" << "horizontal-padding.qml" + << "gridtest.qml" << "gridtest-padding.qml" + << "flowtest.qml" << "flowtest-padding.qml"; QList<QString> objectNames; objectNames << "one" << "two" << "three" << "four" << "five"; @@ -1942,8 +3791,8 @@ void tst_qquickpositioners::test_mirroring() // LTR != RTL foreach (const QString objectName, objectNames) { - // horizontal.qml only has three items - if (qmlFile == QString("horizontal.qml") && objectName == QString("four")) + // horizontal.qml and horizontal-padding.qml only have three items + if (qmlFile.startsWith(QString("horizontal")) && objectName == QString("four")) break; QQuickItem *itemA = rootA->findChild<QQuickItem*>(objectName); QQuickItem *itemB = rootB->findChild<QQuickItem*>(objectName); @@ -1957,8 +3806,8 @@ void tst_qquickpositioners::test_mirroring() // RTL == mirror foreach (const QString objectName, objectNames) { - // horizontal.qml only has three items - if (qmlFile == QString("horizontal.qml") && objectName == QString("four")) + // horizontal.qml and horizontal-padding.qml only have three items + if (qmlFile.startsWith(QString("horizontal")) && objectName == QString("four")) break; QQuickItem *itemA = rootA->findChild<QQuickItem*>(objectName); QQuickItem *itemB = rootB->findChild<QQuickItem*>(objectName); @@ -1978,8 +3827,8 @@ void tst_qquickpositioners::test_mirroring() // LTR == RTL + mirror foreach (const QString objectName, objectNames) { - // horizontal.qml only has three items - if (qmlFile == QString("horizontal.qml") && objectName == QString("four")) + // horizontal.qml and horizontal-padding.qml only have three items + if (qmlFile.startsWith(QString("horizontal")) && objectName == QString("four")) break; QQuickItem *itemA = rootA->findChild<QQuickItem*>(objectName); QQuickItem *itemB = rootB->findChild<QQuickItem*>(objectName); @@ -1998,12 +3847,63 @@ void tst_qquickpositioners::test_allInvisible() QQuickRow *row = window->rootObject()->findChild<QQuickRow*>("row"); QVERIFY(row != 0); - QVERIFY(row->width() == 0); - QVERIFY(row->height() == 0); + QCOMPARE(row->width(), qreal(0)); + QCOMPARE(row->height(), qreal(0)); + + // test padding + row->setProperty("padding", 1); + row->setProperty("topPadding", 2); + row->setProperty("leftPadding", 3); + row->setProperty("rightPadding", 4); + row->setProperty("bottomPadding", 5); + + QTRY_COMPARE(row->height(), 7.0); + QCOMPARE(row->width(), 7.0); + QQuickColumn *column = window->rootObject()->findChild<QQuickColumn*>("column"); QVERIFY(column != 0); - QVERIFY(column->width() == 0); - QVERIFY(column->height() == 0); + QCOMPARE(column->width(), qreal(0)); + QCOMPARE(column->height(), qreal(0)); + + // test padding + column->setProperty("padding", 1); + column->setProperty("topPadding", 2); + column->setProperty("leftPadding", 3); + column->setProperty("rightPadding", 4); + column->setProperty("bottomPadding", 5); + + QTRY_COMPARE(column->height(), 7.0); + QCOMPARE(column->width(), 7.0); + + QQuickGrid *grid = window->rootObject()->findChild<QQuickGrid*>("grid"); + QVERIFY(grid != 0); + QCOMPARE(grid->width(), qreal(0)); + QCOMPARE(grid->height(), qreal(0)); + + // test padding + grid->setProperty("padding", 1); + grid->setProperty("topPadding", 2); + grid->setProperty("leftPadding", 3); + grid->setProperty("rightPadding", 4); + grid->setProperty("bottomPadding", 5); + + QTRY_COMPARE(grid->height(), 7.0); + QCOMPARE(grid->width(), 7.0); + + QQuickFlow *flow = window->rootObject()->findChild<QQuickFlow*>("flow"); + QVERIFY(flow != 0); + QCOMPARE(flow->width(), qreal(0)); + QCOMPARE(flow->height(), qreal(0)); + + // test padding + flow->setProperty("padding", 1); + flow->setProperty("topPadding", 2); + flow->setProperty("leftPadding", 3); + flow->setProperty("rightPadding", 4); + flow->setProperty("bottomPadding", 5); + + QTRY_COMPARE(flow->height(), 7.0); + QCOMPARE(flow->width(), 7.0); } void tst_qquickpositioners::test_attachedproperties() @@ -2017,30 +3917,30 @@ void tst_qquickpositioners::test_attachedproperties() QVERIFY(greenRect != 0); int posIndex = greenRect->property("posIndex").toInt(); - QVERIFY(posIndex == 0); + QCOMPARE(posIndex, 0); bool isFirst = greenRect->property("isFirstItem").toBool(); - QVERIFY(isFirst == true); + QVERIFY(isFirst); bool isLast = greenRect->property("isLastItem").toBool(); - QVERIFY(isLast == false); + QVERIFY(!isLast); QQuickRectangle *yellowRect = window->rootObject()->findChild<QQuickRectangle *>("yellowRect"); QVERIFY(yellowRect != 0); posIndex = yellowRect->property("posIndex").toInt(); - QVERIFY(posIndex == -1); + QCOMPARE(posIndex, -1); isFirst = yellowRect->property("isFirstItem").toBool(); - QVERIFY(isFirst == false); + QVERIFY(!isFirst); isLast = yellowRect->property("isLastItem").toBool(); - QVERIFY(isLast == false); + QVERIFY(!isLast); yellowRect->metaObject()->invokeMethod(yellowRect, "onDemandPositioner"); posIndex = yellowRect->property("posIndex").toInt(); - QVERIFY(posIndex == 1); + QCOMPARE(posIndex, 1); isFirst = yellowRect->property("isFirstItem").toBool(); - QVERIFY(isFirst == false); + QVERIFY(!isFirst); isLast = yellowRect->property("isLastItem").toBool(); - QVERIFY(isLast == true); + QVERIFY(isLast); } @@ -2066,46 +3966,46 @@ void tst_qquickpositioners::test_attachedproperties_dynamic() QVERIFY(rect0 != 0); int posIndex = rect0->property("index").toInt(); - QVERIFY(posIndex == 0); + QCOMPARE(posIndex, 0); bool isFirst = rect0->property("firstItem").toBool(); - QVERIFY(isFirst == true); + QVERIFY(isFirst); bool isLast = rect0->property("lastItem").toBool(); - QVERIFY(isLast == false); + QVERIFY(!isLast); QQuickRectangle *rect1 = window->rootObject()->findChild<QQuickRectangle *>("rect1"); QVERIFY(rect1 != 0); posIndex = rect1->property("index").toInt(); - QVERIFY(posIndex == 1); + QCOMPARE(posIndex, 1); isFirst = rect1->property("firstItem").toBool(); - QVERIFY(isFirst == false); + QVERIFY(!isFirst); isLast = rect1->property("lastItem").toBool(); - QVERIFY(isLast == true); + QVERIFY(isLast); row->metaObject()->invokeMethod(row, "createSubRect"); - QTRY_VERIFY(rect1->property("index").toInt() == 1); - QTRY_VERIFY(rect1->property("firstItem").toBool() == false); - QTRY_VERIFY(rect1->property("lastItem").toBool() == false); + QTRY_COMPARE(rect1->property("index").toInt(), 1); + QTRY_VERIFY(!rect1->property("firstItem").toBool()); + QTRY_VERIFY(!rect1->property("lastItem").toBool()); QQuickRectangle *rect2 = window->rootObject()->findChild<QQuickRectangle *>("rect2"); QVERIFY(rect2 != 0); posIndex = rect2->property("index").toInt(); - QVERIFY(posIndex == 2); + QCOMPARE(posIndex, 2); isFirst = rect2->property("firstItem").toBool(); - QVERIFY(isFirst == false); + QVERIFY(!isFirst); isLast = rect2->property("lastItem").toBool(); - QVERIFY(isLast == true); + QVERIFY(isLast); row->metaObject()->invokeMethod(row, "destroySubRect"); QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); QCoreApplication::processEvents(); - QTRY_VERIFY(rect1->property("index").toInt() == 1); - QTRY_VERIFY(rect1->property("firstItem").toBool() == false); - QTRY_VERIFY(rect1->property("lastItem").toBool() == true); + QTRY_COMPARE(rect1->property("index").toInt(), 1); + QTRY_VERIFY(!rect1->property("firstItem").toBool()); + QTRY_VERIFY(rect1->property("lastItem").toBool()); } @@ -2138,7 +4038,7 @@ void tst_qquickpositioners::matchIndexLists(const QVariantList &indexLists, cons void tst_qquickpositioners::matchItemsAndIndexes(const QVariantMap &items, const QaimModel &model, const QList<int> &expectedIndexes) { for (QVariantMap::const_iterator it = items.begin(); it != items.end(); ++it) { - QVERIFY(it.value().type() == QVariant::Int); + QCOMPARE(it.value().type(), QVariant::Int); QString name = it.key(); int itemIndex = it.value().toInt(); QVERIFY2(expectedIndexes.contains(itemIndex), QTest::toString(QString("Index %1 not found in expectedIndexes").arg(itemIndex))); @@ -2152,7 +4052,7 @@ void tst_qquickpositioners::matchItemsAndIndexes(const QVariantMap &items, const void tst_qquickpositioners::matchItemLists(const QVariantList &itemLists, const QList<QQuickItem *> &expectedItems) { for (int i=0; i<itemLists.count(); i++) { - QVERIFY(itemLists[i].type() == QVariant::List); + QCOMPARE(itemLists[i].type(), QVariant::List); QVariantList current = itemLists[i].toList(); for (int j=0; j<current.count(); j++) { QQuickItem *o = qobject_cast<QQuickItem*>(current[j].value<QObject*>()); diff --git a/tests/auto/quick/qquickrepeater/data/modelCleared.qml b/tests/auto/quick/qquickrepeater/data/modelCleared.qml new file mode 100644 index 0000000000..1269e9bdf2 --- /dev/null +++ b/tests/auto/quick/qquickrepeater/data/modelCleared.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 + +Row { + spacing: 2 + height: 100 + + Repeater { + id: repeater + objectName: "repeater" + model: 10 + Rectangle { + color: "green" + width: 10; height: 50 + anchors.bottom: parent.bottom + } + } +} diff --git a/tests/auto/quick/qquickrepeater/data/objectmodel.qml b/tests/auto/quick/qquickrepeater/data/objectmodel.qml new file mode 100644 index 0000000000..780f53e802 --- /dev/null +++ b/tests/auto/quick/qquickrepeater/data/objectmodel.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 +import QtQml.Models 2.1 + +Row { + width: 360 + height: 360 + + Repeater { + objectName: "repeater" + model: ObjectModel { + Rectangle { + width: 20 + height: 20 + color: "red" + } + Rectangle { + width: 20 + height: 20 + color: "green" + } + Rectangle { + width: 20 + height: 20 + color: "blue" + } + } + } +} diff --git a/tests/auto/quick/qquickrepeater/data/stackingorder.qml b/tests/auto/quick/qquickrepeater/data/stackingorder.qml new file mode 100644 index 0000000000..41dadca0df --- /dev/null +++ b/tests/auto/quick/qquickrepeater/data/stackingorder.qml @@ -0,0 +1,38 @@ +import QtQuick 2.0 + +Item { + id: root + property bool stackingOrderOk: true + + function verifyStackingOrder() { + var len = children.length + for (var i = 0; i < len; ++i) { + var expectedName; + if (i === 0) { + expectedName = "first" + } else if (i === len - 2) { + expectedName = "repeater" + } else if (i === len - 1) { + expectedName = "last" + } else { + expectedName = "middle" + (i - 1) + } + if (children[i].objectName !== expectedName) + stackingOrderOk = false + } + } + Item { + objectName: "first" + } + Repeater { + objectName: "repeater" + model: 1 + Item { + objectName: "middle" + index + Component.onCompleted: { verifyStackingOrder();} + } + } + Item { + objectName: "last" + } +} diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp index b2039bd323..a34001b23a 100644 --- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp +++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp @@ -41,6 +41,7 @@ #include <private/qquickrepeater_p.h> #include <QtQuick/private/qquicktext_p.h> #include <QtQml/private/qqmllistmodel_p.h> +#include <QtQml/private/qqmlobjectmodel_p.h> #include "../../shared/util.h" #include "../shared/viewtestutil.h" @@ -67,6 +68,7 @@ private slots: void resetModel(); void modelChanged(); void modelReset(); + void modelCleared(); void properties(); void asynchronous(); void initParent(); @@ -76,6 +78,8 @@ private slots: void jsArrayChange(); void clearRemovalOrder(); void destroyCount(); + void stackingOrder(); + void objectModel(); }; class TestObject : public QObject @@ -128,7 +132,7 @@ void tst_QQuickRepeater::numberModel() QVERIFY(!repeater->itemAt(repeater->count())); QMetaObject::invokeMethod(window->rootObject(), "checkProperties"); - QVERIFY(testObject->error() == false); + QVERIFY(!testObject->error()); delete testObject; delete window; @@ -440,19 +444,19 @@ void tst_QQuickRepeater::itemModel() testObject->setUseModel(true); QMetaObject::invokeMethod(window->rootObject(), "checkProperties"); - QVERIFY(testObject->error() == false); + QVERIFY(!testObject->error()); QCOMPARE(container->childItems().count(), 4); - QVERIFY(qobject_cast<QObject*>(container->childItems().at(0))->objectName() == "item1"); - QVERIFY(qobject_cast<QObject*>(container->childItems().at(1))->objectName() == "item2"); - QVERIFY(qobject_cast<QObject*>(container->childItems().at(2))->objectName() == "item3"); - QVERIFY(container->childItems().at(3) == repeater); + QCOMPARE(qobject_cast<QObject*>(container->childItems().at(0))->objectName(), QLatin1String("item1")); + QCOMPARE(qobject_cast<QObject*>(container->childItems().at(1))->objectName(), QLatin1String("item2")); + QCOMPARE(qobject_cast<QObject*>(container->childItems().at(2))->objectName(), QLatin1String("item3")); + QCOMPARE(container->childItems().at(3), repeater); QMetaObject::invokeMethod(window->rootObject(), "switchModel"); QCOMPARE(container->childItems().count(), 3); - QVERIFY(qobject_cast<QObject*>(container->childItems().at(0))->objectName() == "item4"); - QVERIFY(qobject_cast<QObject*>(container->childItems().at(1))->objectName() == "item5"); - QVERIFY(container->childItems().at(2) == repeater); + QCOMPARE(qobject_cast<QObject*>(container->childItems().at(0))->objectName(), QLatin1String("item4")); + QCOMPARE(qobject_cast<QObject*>(container->childItems().at(1))->objectName(), QLatin1String("item5")); + QCOMPARE(container->childItems().at(2), repeater); testObject->setUseModel(false); QCOMPARE(container->childItems().count(), 1); @@ -631,6 +635,26 @@ void tst_QQuickRepeater::modelReset() QCOMPARE(addedSpy.count(), 0); } +// QTBUG-46828 +void tst_QQuickRepeater::modelCleared() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("modelCleared.qml")); + + QQuickItem *rootObject = qobject_cast<QQuickItem*>(component.create()); + QVERIFY(rootObject); + + QQuickRepeater *repeater = findItem<QQuickRepeater>(rootObject, "repeater"); + QVERIFY(repeater); + + // verify no error messages when the model is cleared and the items are destroyed + QQmlTestMessageHandler messageHandler; + repeater->setModel(0); + QVERIFY2(messageHandler.messages().isEmpty(), qPrintable(messageHandler.messageString())); + + delete rootObject; +} + void tst_QQuickRepeater::properties() { QQmlEngine engine; @@ -788,8 +812,8 @@ void tst_QQuickRepeater::invalidContextCrash() repeater->setParent(root.data()); QCOMPARE(root->children().count(), 2); - QVERIFY(root->children().at(0) == model); - QVERIFY(root->children().at(1) == repeater); + QCOMPARE(root->children().at(0), model); + QCOMPARE(root->children().at(1), repeater); // Delete the root object, which will invalidate/delete the QML context // and then delete the child QObjects, which may try to access the context. @@ -894,6 +918,82 @@ void tst_QQuickRepeater::destroyCount() QCOMPARE(repeater->property("componentCount").toInt(), 4); } +void tst_QQuickRepeater::stackingOrder() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("stackingorder.qml")); + + QQuickItem *rootObject = qobject_cast<QQuickItem*>(component.create()); + QVERIFY(rootObject); + + QQuickRepeater *repeater = findItem<QQuickRepeater>(rootObject, "repeater"); + QVERIFY(repeater); + int count = 1; + do { + bool stackingOrderOk = rootObject->property("stackingOrderOk").toBool(); + QVERIFY(stackingOrderOk); + repeater->setModel(QVariant(++count)); + } while (count < 3); +} + +static bool compareObjectModel(QQuickRepeater *repeater, QQmlObjectModel *model) +{ + if (repeater->count() != model->count()) + return false; + for (int i = 0; i < repeater->count(); ++i) { + if (repeater->itemAt(i) != model->get(i)) + return false; + } + return true; +} + +void tst_QQuickRepeater::objectModel() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("objectmodel.qml")); + + QQuickItem *positioner = qobject_cast<QQuickItem *>(component.create()); + QVERIFY(positioner); + + QQuickRepeater *repeater = findItem<QQuickRepeater>(positioner, "repeater"); + QVERIFY(repeater); + + QQmlObjectModel *model = repeater->model().value<QQmlObjectModel *>(); + QVERIFY(model); + + QVERIFY(repeater->itemAt(0)); + QVERIFY(repeater->itemAt(1)); + QVERIFY(repeater->itemAt(2)); + QCOMPARE(repeater->itemAt(0)->property("color").toString(), QColor("red").name()); + QCOMPARE(repeater->itemAt(1)->property("color").toString(), QColor("green").name()); + QCOMPARE(repeater->itemAt(2)->property("color").toString(), QColor("blue").name()); + + QQuickItem *item0 = new QQuickItem(positioner); + item0->setSize(QSizeF(20, 20)); + model->append(item0); + QCOMPARE(model->count(), 4); + QVERIFY(compareObjectModel(repeater, model)); + + QQuickItem *item1 = new QQuickItem(positioner); + item1->setSize(QSizeF(20, 20)); + model->insert(0, item1); + QCOMPARE(model->count(), 5); + QVERIFY(compareObjectModel(repeater, model)); + + model->move(1, 2, 3); + QVERIFY(compareObjectModel(repeater, model)); + + model->remove(2, 2); + QCOMPARE(model->count(), 3); + QVERIFY(compareObjectModel(repeater, model)); + + model->clear(); + QCOMPARE(model->count(), 0); + QCOMPARE(repeater->count(), 0); + + delete positioner; +} + QTEST_MAIN(tst_QQuickRepeater) #include "tst_qquickrepeater.moc" diff --git a/tests/auto/quick/qquicksmoothedanimation/tst_qquicksmoothedanimation.cpp b/tests/auto/quick/qquicksmoothedanimation/tst_qquicksmoothedanimation.cpp index 04fdc4ecf7..10e91c455b 100644 --- a/tests/auto/quick/qquicksmoothedanimation/tst_qquicksmoothedanimation.cpp +++ b/tests/auto/quick/qquicksmoothedanimation/tst_qquicksmoothedanimation.cpp @@ -130,9 +130,9 @@ void tst_qquicksmoothedanimation::simpleAnimation() animation->setProperty("x"); animation->setTo(200); animation->setDuration(250); - QVERIFY(animation->target() == rect); - QVERIFY(animation->property() == "x"); - QVERIFY(animation->to() == 200); + QCOMPARE(animation->target(), rect); + QCOMPARE(animation->property(), QLatin1String("x")); + QCOMPARE(animation->to(), qreal(200)); animation->start(); QVERIFY(animation->isRunning()); QTest::qWait(animation->duration()); @@ -147,7 +147,7 @@ void tst_qquicksmoothedanimation::simpleAnimation() QVERIFY(animation->isRunning()); QVERIFY(animation->isPaused()); animation->setCurrentTime(125); - QVERIFY(animation->currentTime() == 125); + QCOMPARE(animation->currentTime(), 125); QCOMPARE(rect->x(), qreal(100)); } diff --git a/tests/auto/quick/qquickstates/tst_qquickstates.cpp b/tests/auto/quick/qquickstates/tst_qquickstates.cpp index 6c42a7a0ee..a375a55877 100644 --- a/tests/auto/quick/qquickstates/tst_qquickstates.cpp +++ b/tests/auto/quick/qquickstates/tst_qquickstates.cpp @@ -1241,7 +1241,7 @@ void tst_qquickstates::deletingState() QVERIFY(state != 0); delete state; - QVERIFY(sg->findState("blue") == 0); + QVERIFY(!sg->findState("blue")); //### should we warn that state doesn't exist sg->setState("blue"); @@ -1317,7 +1317,7 @@ void tst_qquickstates::illegalObjectCreation() QQmlComponent component(&engine, testFileUrl("illegalObj.qml")); QList<QQmlError> errors = component.errors(); - QVERIFY(errors.count() == 1); + QCOMPARE(errors.count(), 1); const QQmlError &error = errors.at(0); QCOMPARE(error.line(), 9); QCOMPARE(error.column(), 23); @@ -1637,7 +1637,7 @@ void tst_qquickstates::QTBUG_38492() void tst_qquickstates::revertListMemoryLeak() { - QWeakPointer<QQmlAbstractBinding> weakPtr; + QQmlAbstractBinding::Ptr bindingPtr; { QQmlEngine engine; @@ -1651,12 +1651,12 @@ void tst_qquickstates::revertListMemoryLeak() QQmlAbstractBinding *binding = state->bindingInRevertList(item, "height"); QVERIFY(binding); - weakPtr = QQmlAbstractBinding::getPointer(binding); - QVERIFY(!weakPtr.toStrongRef().isNull()); + bindingPtr = binding; + QVERIFY(bindingPtr->ref > 1); delete item; } - QVERIFY(weakPtr.toStrongRef().isNull()); + QVERIFY(bindingPtr->ref == 1); } QTEST_MAIN(tst_qquickstates) diff --git a/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp b/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp index 816440b191..4678f5fbb9 100644 --- a/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp +++ b/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp @@ -171,16 +171,16 @@ void tst_qquickstyledtext::textOutput() QCOMPARE(layout.text(), output); - QList<QTextLayout::FormatRange> layoutFormats = layout.additionalFormats(); + const QVector<QTextLayout::FormatRange> layoutFormats = layout.formats(); QCOMPARE(layoutFormats.count(), formats.count()); for (int i = 0; i < formats.count(); ++i) { QCOMPARE(layoutFormats.at(i).start, formats.at(i).start); QCOMPARE(layoutFormats.at(i).length, formats.at(i).length); if (formats.at(i).type & Format::Bold) - QVERIFY(layoutFormats.at(i).format.fontWeight() == QFont::Bold); + QCOMPARE(layoutFormats.at(i).format.fontWeight(), int(QFont::Bold)); else - QVERIFY(layoutFormats.at(i).format.fontWeight() == QFont::Normal); + QCOMPARE(layoutFormats.at(i).format.fontWeight(), int(QFont::Normal)); QVERIFY(layoutFormats.at(i).format.fontItalic() == bool(formats.at(i).type & Format::Italic)); QVERIFY(layoutFormats.at(i).format.fontUnderline() == bool(formats.at(i).type & Format::Underline)); } @@ -200,7 +200,7 @@ void tst_qquickstyledtext::anchors() QCOMPARE(layout.text(), output); - QList<QTextLayout::FormatRange> layoutFormats = layout.additionalFormats(); + const QVector<QTextLayout::FormatRange> layoutFormats = layout.formats(); QCOMPARE(layoutFormats.count(), formats.count()); for (int i = 0; i < formats.count(); ++i) { diff --git a/tests/auto/quick/qquicksystempalette/tst_qquicksystempalette.cpp b/tests/auto/quick/qquicksystempalette/tst_qquicksystempalette.cpp index 5c0c5fd8d3..a4c4987ad9 100644 --- a/tests/auto/quick/qquicksystempalette/tst_qquicksystempalette.cpp +++ b/tests/auto/quick/qquicksystempalette/tst_qquicksystempalette.cpp @@ -97,7 +97,7 @@ void tst_qquicksystempalette::inactivePalette() QQuickSystemPalette *object = qobject_cast<QQuickSystemPalette*>(component.create()); QVERIFY(object != 0); - QVERIFY(object->colorGroup() == QQuickSystemPalette::Inactive); + QCOMPARE(object->colorGroup(), QQuickSystemPalette::Inactive); QPalette palette; palette.setCurrentColorGroup(QPalette::Inactive); @@ -127,7 +127,7 @@ void tst_qquicksystempalette::disabledPalette() QQuickSystemPalette *object = qobject_cast<QQuickSystemPalette*>(component.create()); QVERIFY(object != 0); - QVERIFY(object->colorGroup() == QQuickSystemPalette::Disabled); + QCOMPARE(object->colorGroup(), QQuickSystemPalette::Disabled); QPalette palette; palette.setCurrentColorGroup(QPalette::Disabled); diff --git a/tests/auto/quick/qquicktext/BLACKLIST b/tests/auto/quick/qquicktext/BLACKLIST new file mode 100644 index 0000000000..0c65f1e245 --- /dev/null +++ b/tests/auto/quick/qquicktext/BLACKLIST @@ -0,0 +1,4 @@ +[dependentImplicitSizes] +* +[mouseSelection] +* diff --git a/tests/auto/quick/qquicktext/data/fontSizeMode.qml b/tests/auto/quick/qquicktext/data/fontSizeMode.qml index 84f7ce8d50..48e7c7b6d0 100644 --- a/tests/auto/quick/qquicktext/data/fontSizeMode.qml +++ b/tests/auto/quick/qquicktext/data/fontSizeMode.qml @@ -13,10 +13,10 @@ Item { id: myText objectName: "myText" width: 250 - height: 41 + height: 35 minimumPointSize: 8 minimumPixelSize: 8 - font.pixelSize: 30 + font.pixelSize: 25 font.family: "Helvetica" } } diff --git a/tests/auto/quick/qquicktext/data/hAlignImplicitWidth.qml b/tests/auto/quick/qquicktext/data/hAlignImplicitWidth.qml index 9c9318d3cc..45255691fb 100644 --- a/tests/auto/quick/qquicktext/data/hAlignImplicitWidth.qml +++ b/tests/auto/quick/qquicktext/data/hAlignImplicitWidth.qml @@ -1,7 +1,7 @@ import QtQuick 2.0 Rectangle { - width: 200 + width: 220 height: 100 Text { diff --git a/tests/auto/quick/qquicktext/data/padding.qml b/tests/auto/quick/qquicktext/data/padding.qml new file mode 100644 index 0000000000..ab0a37d041 --- /dev/null +++ b/tests/auto/quick/qquicktext/data/padding.qml @@ -0,0 +1,12 @@ +import QtQuick 2.6 + +Text { + width: 200; height: 200 + text: "Hello Qt" + + padding: 10 + topPadding: 20 + leftPadding: 30 + rightPadding: 40 + bottomPadding: 50 +} diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index eb9f7529fe..46eae89024 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -38,6 +38,7 @@ #include <QtQuick/private/qquicktext_p.h> #include <QtQuick/private/qquickmousearea_p.h> #include <private/qquicktext_p_p.h> +#include <private/qquicktextdocument_p.h> #include <private/qquickvaluetypes_p.h> #include <QFontMetrics> #include <qmath.h> @@ -148,6 +149,8 @@ private slots: void growFromZeroWidth(); + void padding(); + private: QStringList standard; QStringList richText; @@ -240,7 +243,7 @@ void tst_qquicktext::text() QVERIFY(textObject != 0); QCOMPARE(textObject->text(), QString("")); - QVERIFY(textObject->width() == 0); + QCOMPARE(textObject->width(), qreal(0)); delete textObject; } @@ -357,7 +360,7 @@ void tst_qquicktext::width() QVERIFY(doc != 0); QCOMPARE(int(textObject->width()), int(doc->idealWidth())); - QVERIFY(textObject->textFormat() == QQuickText::RichText); + QCOMPARE(textObject->textFormat(), QQuickText::RichText); delete textObject; } @@ -374,7 +377,7 @@ void tst_qquicktext::wrap() textHeight = textObject->height(); QVERIFY(textObject != 0); - QVERIFY(textObject->wrapMode() == QQuickText::WordWrap); + QCOMPARE(textObject->wrapMode(), QQuickText::WordWrap); QCOMPARE(textObject->width(), 300.); delete textObject; @@ -657,11 +660,11 @@ void tst_qquicktext::textFormat() QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); QVERIFY(textObject != 0); - QVERIFY(textObject->textFormat() == QQuickText::RichText); + QCOMPARE(textObject->textFormat(), QQuickText::RichText); QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); QVERIFY(textPrivate != 0); - QVERIFY(textPrivate->richText == true); + QVERIFY(textPrivate->richText); delete textObject; } @@ -671,11 +674,11 @@ void tst_qquicktext::textFormat() QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); QVERIFY(textObject != 0); - QVERIFY(textObject->textFormat() == QQuickText::AutoText); + QCOMPARE(textObject->textFormat(), QQuickText::AutoText); QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); QVERIFY(textPrivate != 0); - QVERIFY(textPrivate->styledText == true); + QVERIFY(textPrivate->styledText); delete textObject; } @@ -685,7 +688,7 @@ void tst_qquicktext::textFormat() QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); QVERIFY(textObject != 0); - QVERIFY(textObject->textFormat() == QQuickText::PlainText); + QCOMPARE(textObject->textFormat(), QQuickText::PlainText); delete textObject; } @@ -911,7 +914,7 @@ void tst_qquicktext::hAlignImplicitWidth() // Try to check whether alignment works by checking the number of black // pixels in the thirds of the grabbed image. - const int windowWidth = 200; + const int windowWidth = 220; const int textWidth = qCeil(text->implicitWidth()); QVERIFY2(textWidth < windowWidth, "System font too large."); const int sectionWidth = textWidth / 3; @@ -2047,8 +2050,8 @@ void tst_qquicktext::embeddedImages_data() QTest::newRow("local") << testFileUrl("embeddedImagesLocalRelative.qml") << ""; QTest::newRow("remote") << testFileUrl("embeddedImagesRemote.qml") << ""; QTest::newRow("remote-error") << testFileUrl("embeddedImagesRemoteError.qml") - << testFileUrl("embeddedImagesRemoteError.qml").toString()+":3:1: QML Text: Error downloading {{ServerBaseUrl}}/notexists.png - server replied: Not found"; - QTest::newRow("remote") << testFileUrl("embeddedImagesRemoteRelative.qml") << ""; + << testFileUrl("embeddedImagesRemoteError.qml").toString()+":3:1: QML Text: Error transferring {{ServerBaseUrl}}/notexists.png - server replied: Not found"; + QTest::newRow("remote-relative") << testFileUrl("embeddedImagesRemoteRelative.qml") << ""; } void tst_qquicktext::embeddedImages() @@ -2058,6 +2061,14 @@ void tst_qquicktext::embeddedImages() QFETCH(QUrl, qmlfile); QFETCH(QString, error); +#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) + if (qstrcmp(QTest::currentDataTag(), "remote") == 0 + || qstrcmp(QTest::currentDataTag(), "remote-error") == 0 + || qstrcmp(QTest::currentDataTag(), "remote-relative") == 0) { + QSKIP("Remote tests cause occasional hangs in the CI system -- QTBUG-45655"); + } +#endif + TestHTTPServer server; QVERIFY2(server.listen(), qPrintable(server.errorString())); server.serveDirectory(testFile("http")); @@ -2126,8 +2137,8 @@ void tst_qquicktext::lineHeight() QQuickText *myText = window->rootObject()->findChild<QQuickText*>("myText"); QVERIFY(myText != 0); - QVERIFY(myText->lineHeight() == 1); - QVERIFY(myText->lineHeightMode() == QQuickText::ProportionalHeight); + QCOMPARE(myText->lineHeight(), qreal(1)); + QCOMPARE(myText->lineHeightMode(), QQuickText::ProportionalHeight); qreal h = myText->height(); myText->setLineHeight(1.5); @@ -2197,12 +2208,12 @@ void tst_qquicktext::implicitSize() QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); QVERIFY(textObject->width() < textObject->implicitWidth()); - QVERIFY(textObject->height() == textObject->implicitHeight()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); QCOMPARE(textObject->property("iWidth").toReal(), textObject->implicitWidth()); textObject->resetWidth(); - QVERIFY(textObject->width() == textObject->implicitWidth()); - QVERIFY(textObject->height() == textObject->implicitHeight()); + QCOMPARE(textObject->width(), textObject->implicitWidth()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); delete textObject; } @@ -2738,7 +2749,7 @@ void tst_qquicktext::lineLaidOut() QVERIFY(r.x() == r.width() + 30); if (i >= 60) { QVERIFY(r.x() == r.width() * 2 + 60); - QVERIFY(r.height() == 20); + QCOMPARE(r.height(), qreal(20)); } } @@ -2916,7 +2927,7 @@ void tst_qquicktext::imgTagsAlign() QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); QVERIFY(textObject != 0); - QVERIFY(textObject->height() == imgHeight); + QCOMPARE(textObject->height(), qreal(imgHeight)); QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); QVERIFY(textPrivate != 0); @@ -2927,7 +2938,7 @@ void tst_qquicktext::imgTagsAlign() else if (align == "middle") QVERIFY(br.y() == imgHeight / 2.0 - br.height() / 2.0); else if (align == "top") - QVERIFY(br.y() == 0); + QCOMPARE(br.y(), qreal(0)); delete textObject; } @@ -2941,11 +2952,11 @@ void tst_qquicktext::imgTagsMultipleImages() QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); QVERIFY(textObject != 0); - QVERIFY(textObject->height() == 85); + QCOMPARE(textObject->height(), qreal(85)); QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); QVERIFY(textPrivate != 0); - QVERIFY(textPrivate->extra->visibleImgTags.count() == 2); + QCOMPARE(textPrivate->extra->visibleImgTags.count(), 2); delete textObject; } @@ -2958,9 +2969,9 @@ void tst_qquicktext::imgTagsElide() QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText); QVERIFY(textPrivate != 0); - QVERIFY(textPrivate->extra->visibleImgTags.count() == 0); + QCOMPARE(textPrivate->extra->visibleImgTags.count(), 0); myText->setMaximumLineCount(20); - QTRY_VERIFY(textPrivate->extra->visibleImgTags.count() == 1); + QTRY_COMPARE(textPrivate->extra->visibleImgTags.count(), 1); delete myText; delete window; @@ -2978,16 +2989,16 @@ void tst_qquicktext::imgTagsUpdates() QVERIFY(textPrivate != 0); myText->setText("This is a heart<img src=\"images/heart200.png\">."); - QVERIFY(textPrivate->extra->visibleImgTags.count() == 1); - QVERIFY(spy.count() == 1); + QCOMPARE(textPrivate->extra->visibleImgTags.count(), 1); + QCOMPARE(spy.count(), 1); myText->setMaximumLineCount(2); myText->setText("This is another heart<img src=\"images/heart200.png\">."); - QTRY_VERIFY(textPrivate->extra->visibleImgTags.count() == 1); + QTRY_COMPARE(textPrivate->extra->visibleImgTags.count(), 1); // if maximumLineCount is set and the img tag doesn't have an explicit size // we relayout twice. - QVERIFY(spy.count() == 3); + QCOMPARE(spy.count(), 3); delete myText; delete window; @@ -3634,19 +3645,19 @@ Q_DECLARE_METATYPE(ExpectedBaseline) static qreal expectedBaselineTop(QQuickText *item) { QFontMetricsF fm(item->font()); - return fm.ascent(); + return fm.ascent() + item->topPadding(); } static qreal expectedBaselineBottom(QQuickText *item) { QFontMetricsF fm(item->font()); - return item->height() - item->contentHeight() + fm.ascent(); + return item->height() - item->contentHeight() - item->bottomPadding() + fm.ascent(); } static qreal expectedBaselineCenter(QQuickText *item) { QFontMetricsF fm(item->font()); - return ((item->height() - item->contentHeight()) / 2) + fm.ascent(); + return ((item->height() - item->contentHeight() - item->topPadding() - item->bottomPadding()) / 2) + fm.ascent() + item->topPadding(); } static qreal expectedBaselineBold(QQuickText *item) @@ -3654,7 +3665,7 @@ static qreal expectedBaselineBold(QQuickText *item) QFont font = item->font(); font.setBold(true); QFontMetricsF fm(font); - return fm.ascent(); + return fm.ascent() + item->topPadding(); } static qreal expectedBaselineImage(QQuickText *item) @@ -3664,13 +3675,13 @@ static qreal expectedBaselineImage(QQuickText *item) // or image height - line height and the baseline is line position + ascent. Because // QTextLine's height is rounded up this can give slightly different results to image height // - descent. - return 181 - qCeil(fm.height()) + fm.ascent(); + return 181 - qCeil(fm.height()) + fm.ascent() + item->topPadding(); } static qreal expectedBaselineCustom(QQuickText *item) { QFontMetricsF fm(item->font()); - return 16 + fm.ascent(); + return 16 + fm.ascent() + item->topPadding(); } static qreal expectedBaselineScaled(QQuickText *item) @@ -3689,11 +3700,11 @@ static qreal expectedBaselineScaled(QQuickText *item) if (width < item->width()) { QFontMetricsF fm(layout.font()); - return fm.ascent(); + return fm.ascent() + item->topPadding(); } font.setPointSize(font.pointSize() - 1); } while (font.pointSize() > 0); - return 0; + return item->topPadding(); } static qreal expectedBaselineFixedBottom(QQuickText *item) @@ -3702,7 +3713,7 @@ static qreal expectedBaselineFixedBottom(QQuickText *item) qreal dy = item->text().contains(QLatin1Char('\n')) ? 160 : 180; - return dy + fm.ascent(); + return dy + fm.ascent() - item->bottomPadding(); } static qreal expectedBaselineProportionalBottom(QQuickText *item) @@ -3711,7 +3722,7 @@ static qreal expectedBaselineProportionalBottom(QQuickText *item) qreal dy = item->text().contains(QLatin1Char('\n')) ? 200 - (qCeil(fm.height()) * 3) : 200 - (qCeil(fm.height()) * 1.5); - return dy + fm.ascent(); + return dy + fm.ascent() - item->bottomPadding(); } void tst_qquicktext::baselineOffset_data() @@ -3746,8 +3757,8 @@ void tst_qquicktext::baselineOffset_data() << "<b>hello world</b>" << "<b>hello<br/>world</b>" << QByteArray("height: 200") - << &expectedBaselineTop - << &expectedBaselineBold; + << &expectedBaselineBold + << &expectedBaselineTop; QTest::newRow("richText") << "<b>hello world</b>" @@ -3818,6 +3829,102 @@ void tst_qquicktext::baselineOffset_data() << QByteArray("height: 200; lineHeightMode: Text.ProportionalHeight; lineHeight: 1.5; verticalAlignment: Text.AlignBottom") << &expectedBaselineProportionalBottom << &expectedBaselineProportionalBottom; + + QTest::newRow("top align with padding") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; topPadding: 10; bottomPadding: 20; verticalAlignment: Text.AlignTop") + << &expectedBaselineTop + << &expectedBaselineTop; + QTest::newRow("bottom align with padding") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; topPadding: 10; bottomPadding: 20; verticalAlignment: Text.AlignBottom") + << &expectedBaselineBottom + << &expectedBaselineBottom; + QTest::newRow("center align with padding") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; topPadding: 10; bottomPadding: 20; verticalAlignment: Text.AlignVCenter") + << &expectedBaselineCenter + << &expectedBaselineCenter; + + QTest::newRow("bold width padding") + << "<b>hello world</b>" + << "<b>hello<br/>world</b>" + << QByteArray("height: 200; topPadding: 10; bottomPadding: 20") + << &expectedBaselineBold + << &expectedBaselineTop; + + QTest::newRow("richText with padding") + << "<b>hello world</b>" + << "<b>hello<br/>world</b>" + << QByteArray("height: 200; topPadding: 10; bottomPadding: 20; textFormat: Text.RichText") + << &expectedBaselineTop + << &expectedBaselineTop; + + QTest::newRow("elided with padding") + << "hello world" + << "hello\nworld" + << QByteArray("width: 20; height: 8; topPadding: 10; bottomPadding: 20; elide: Text.ElideRight") + << &expectedBaselineTop + << &expectedBaselineTop; + + QTest::newRow("elided bottom align with padding") + << "hello world" + << "hello\nworld!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + << QByteArray("width: 200; height: 200; topPadding: 10; bottomPadding: 20; elide: Text.ElideRight; verticalAlignment: Text.AlignBottom") + << &expectedBaselineBottom + << &expectedBaselineBottom; + + QTest::newRow("image with padding") + << "hello <img src=\"images/heart200.png\" /> world" + << "hello <img src=\"images/heart200.png\" /><br/>world" + << QByteArray("height: 200\n; topPadding: 10; bottomPadding: 20; baseUrl: \"") + testFileUrl("reference").toEncoded() + QByteArray("\"") + << &expectedBaselineImage + << &expectedBaselineTop; + + QTest::newRow("customLine with padding") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; topPadding: 10; bottomPadding: 20; onLineLaidOut: line.y += 16") + << &expectedBaselineCustom + << &expectedBaselineCustom; + + QTest::newRow("scaled font with padding") + << "hello world" + << "hello\nworld" + << QByteArray("width: 200; topPadding: 10; bottomPadding: 20; minimumPointSize: 1; font.pointSize: 64; fontSizeMode: Text.HorizontalFit") + << &expectedBaselineScaled + << &expectedBaselineTop; + + QTest::newRow("fixed line height top align with padding") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; topPadding: 10; bottomPadding: 20; lineHeightMode: Text.FixedHeight; lineHeight: 20; verticalAlignment: Text.AlignTop") + << &expectedBaselineTop + << &expectedBaselineTop; + + QTest::newRow("fixed line height bottom align with padding") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; topPadding: 10; bottomPadding: 20; lineHeightMode: Text.FixedHeight; lineHeight: 20; verticalAlignment: Text.AlignBottom") + << &expectedBaselineFixedBottom + << &expectedBaselineFixedBottom; + + QTest::newRow("proportional line height top align with padding") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; topPadding: 10; bottomPadding: 20; lineHeightMode: Text.ProportionalHeight; lineHeight: 1.5; verticalAlignment: Text.AlignTop") + << &expectedBaselineTop + << &expectedBaselineTop; + + QTest::newRow("proportional line height bottom align with padding") + << "hello world" + << "hello\nworld" + << QByteArray("height: 200; topPadding: 10; bottomPadding: 20; lineHeightMode: Text.ProportionalHeight; lineHeight: 1.5; verticalAlignment: Text.AlignBottom") + << &expectedBaselineProportionalBottom + << &expectedBaselineProportionalBottom; } void tst_qquicktext::baselineOffset() @@ -3830,7 +3937,7 @@ void tst_qquicktext::baselineOffset() QQmlComponent component(&engine); component.setData( - "import QtQuick 2.0\n" + "import QtQuick 2.6\n" "Text {\n" + bindings + "\n" "}", QUrl()); @@ -3972,6 +4079,84 @@ void tst_qquicktext::growFromZeroWidth() QVERIFY(text->lineCount() > 3); } +void tst_qquicktext::padding() +{ + QScopedPointer<QQuickView> window(new QQuickView); + window->setSource(testFileUrl("padding.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QQuickItem *root = window->rootObject(); + QVERIFY(root); + QQuickText *obj = qobject_cast<QQuickText*>(root); + QVERIFY(obj != 0); + + qreal cw = obj->contentWidth(); + qreal ch = obj->contentHeight(); + + QVERIFY(cw > 0); + QVERIFY(ch > 0); + + QCOMPARE(obj->topPadding(), 20.0); + QCOMPARE(obj->leftPadding(), 30.0); + QCOMPARE(obj->rightPadding(), 40.0); + QCOMPARE(obj->bottomPadding(), 50.0); + + QCOMPARE(obj->implicitWidth(), cw + obj->leftPadding() + obj->rightPadding()); + QCOMPARE(obj->implicitHeight(), ch + obj->topPadding() + obj->bottomPadding()); + + obj->setTopPadding(2.25); + QCOMPARE(obj->topPadding(), 2.25); + QCOMPARE(obj->implicitHeight(), ch + obj->topPadding() + obj->bottomPadding()); + + obj->setLeftPadding(3.75); + QCOMPARE(obj->leftPadding(), 3.75); + QCOMPARE(obj->implicitWidth(), cw + obj->leftPadding() + obj->rightPadding()); + + obj->setRightPadding(4.4); + QCOMPARE(obj->rightPadding(), 4.4); + QCOMPARE(obj->implicitWidth(), cw + obj->leftPadding() + obj->rightPadding()); + + obj->setBottomPadding(1.11); + QCOMPARE(obj->bottomPadding(), 1.11); + QCOMPARE(obj->implicitHeight(), ch + obj->topPadding() + obj->bottomPadding()); + + obj->setText("Qt"); + QVERIFY(obj->contentWidth() < cw); + QCOMPARE(obj->contentHeight(), ch); + cw = obj->contentWidth(); + + QCOMPARE(obj->implicitWidth(), cw + obj->leftPadding() + obj->rightPadding()); + QCOMPARE(obj->implicitHeight(), ch + obj->topPadding() + obj->bottomPadding()); + + obj->setFont(QFont("Courier", 96)); + QVERIFY(obj->contentWidth() > cw); + QVERIFY(obj->contentHeight() > ch); + cw = obj->contentWidth(); + ch = obj->contentHeight(); + + QCOMPARE(obj->implicitWidth(), cw + obj->leftPadding() + obj->rightPadding()); + QCOMPARE(obj->implicitHeight(), ch + obj->topPadding() + obj->bottomPadding()); + + obj->resetTopPadding(); + QCOMPARE(obj->topPadding(), 10.0); + obj->resetLeftPadding(); + QCOMPARE(obj->leftPadding(), 10.0); + obj->resetRightPadding(); + QCOMPARE(obj->rightPadding(), 10.0); + obj->resetBottomPadding(); + QCOMPARE(obj->bottomPadding(), 10.0); + + obj->resetPadding(); + QCOMPARE(obj->padding(), 0.0); + QCOMPARE(obj->topPadding(), 0.0); + QCOMPARE(obj->leftPadding(), 0.0); + QCOMPARE(obj->rightPadding(), 0.0); + QCOMPARE(obj->bottomPadding(), 0.0); + + delete root; +} + QTEST_MAIN(tst_qquicktext) #include "tst_qquicktext.moc" diff --git a/tests/auto/quick/qquicktextdocument/tst_qquicktextdocument.cpp b/tests/auto/quick/qquicktextdocument/tst_qquicktextdocument.cpp index 302959dd7f..12fcbfda0e 100644 --- a/tests/auto/quick/qquicktextdocument/tst_qquicktextdocument.cpp +++ b/tests/auto/quick/qquicktextdocument/tst_qquicktextdocument.cpp @@ -36,7 +36,7 @@ #include <QtQuick/QQuickTextDocument> #include <QtQuick/QQuickItem> #include <QtQuick/private/qquicktextedit_p.h> -#include <QtQuick/private/qquicktext_p_p.h> +#include <QtQuick/private/qquicktextdocument_p.h> #include <QtGui/QTextDocument> #include <QtGui/QTextDocumentWriter> #include <QtQml/QQmlEngine> diff --git a/tests/auto/quick/qquicktextedit/BLACKLIST b/tests/auto/quick/qquicktextedit/BLACKLIST new file mode 100644 index 0000000000..492d81531a --- /dev/null +++ b/tests/auto/quick/qquicktextedit/BLACKLIST @@ -0,0 +1,2 @@ +[mouseSelection] +* diff --git a/tests/auto/quick/qquicktextedit/data/hAlignVisual.qml b/tests/auto/quick/qquicktextedit/data/hAlignVisual.qml index 017bab97a7..1280a655f0 100644 --- a/tests/auto/quick/qquicktextedit/data/hAlignVisual.qml +++ b/tests/auto/quick/qquicktextedit/data/hAlignVisual.qml @@ -10,5 +10,6 @@ Rectangle { anchors.centerIn: parent horizontalAlignment: Text.AlignLeft font.pointSize: 12 + font.family: "Times New Roman" } } diff --git a/tests/auto/quick/qquicktextedit/data/padding.qml b/tests/auto/quick/qquicktextedit/data/padding.qml new file mode 100644 index 0000000000..f4852bec8b --- /dev/null +++ b/tests/auto/quick/qquicktextedit/data/padding.qml @@ -0,0 +1,12 @@ +import QtQuick 2.6 + +TextEdit { + width: 200; height: 200 + text: "Hello Qt" + + padding: 10 + topPadding: 20 + leftPadding: 30 + rightPadding: 40 + bottomPadding: 50 +} diff --git a/tests/auto/quick/qquicktextedit/data/signal_editingfinished.qml b/tests/auto/quick/qquicktextedit/data/signal_editingfinished.qml new file mode 100644 index 0000000000..b5caab5e7c --- /dev/null +++ b/tests/auto/quick/qquicktextedit/data/signal_editingfinished.qml @@ -0,0 +1,13 @@ +import QtQuick 2.6 + +Item { + property QtObject input1: input1 + property QtObject input2: input2 + + width: 800; height: 600 + + Column{ + TextEdit { id: input1; activeFocusOnTab: true } + TextEdit { id: input2; activeFocusOnTab: true } + } +} diff --git a/tests/auto/quick/qquicktextedit/qquicktextedit.pro b/tests/auto/quick/qquicktextedit/qquicktextedit.pro index 2a6d753536..c6f2bb91a8 100644 --- a/tests/auto/quick/qquicktextedit/qquicktextedit.pro +++ b/tests/auto/quick/qquicktextedit/qquicktextedit.pro @@ -13,4 +13,6 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private network-private testlib +osx: LIBS += -framework AppKit + DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp index 9d1d099c0e..7f454aaa11 100644 --- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp @@ -43,7 +43,8 @@ #include <QtGui/qguiapplication.h> #include <private/qquicktextedit_p.h> #include <private/qquicktextedit_p_p.h> -#include <private/qquicktext_p_p.h> +#include <private/qquicktext_p.h> +#include <private/qquicktextdocument_p.h> #include <QFontMetrics> #include <QtQuick/QQuickView> #include <QDir> @@ -72,7 +73,7 @@ QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& QString persistent_dir = QQmlDataTest::instance()->dataDirectory(); QString arch = "unknown-architecture"; // QTest needs to help with this. - QString expectfile = persistent_dir + QDir::separator() + filebasename + "-" + arch + ".png"; + QString expectfile = persistent_dir + QDir::separator() + filebasename + QLatin1Char('-') + arch + ".png"; if (!QFile::exists(expectfile)) { actual.save(expectfile); @@ -166,6 +167,8 @@ private slots: void implicitSizeBinding_data(); void implicitSizeBinding(); + void signal_editingfinished(); + void preeditCursorRectangle(); void inputMethodComposing(); void cursorRectangleSize_data(); @@ -199,6 +202,9 @@ private slots: void emptytags_QTBUG_22058(); void cursorRectangle_QTBUG_38947(); void textCached_QTBUG_41583(); + void doubleSelect_QTBUG_38704(); + + void padding(); private: void simulateKeys(QWindow *window, const QList<Key> &keys); @@ -280,6 +286,9 @@ QList<Key> &operator <<(QList<Key> &keys, Qt::Key key) tst_qquicktextedit::tst_qquicktextedit() { + qRegisterMetaType<QQuickTextEdit::TextFormat>(); + qRegisterMetaType<QQuickTextEdit::SelectionMode>(); + standard << "the quick brown fox jumped over the lazy dog" << "the quick brown fox\n jumped over the lazy dog" << "Hello, world!" @@ -573,7 +582,7 @@ void tst_qquicktextedit::textFormat() QQuickTextEdit *textObject = qobject_cast<QQuickTextEdit*>(textComponent.create()); QVERIFY(textObject != 0); - QVERIFY(textObject->textFormat() == QQuickTextEdit::RichText); + QCOMPARE(textObject->textFormat(), QQuickTextEdit::RichText); } { QQmlComponent textComponent(&engine); @@ -581,7 +590,7 @@ void tst_qquicktextedit::textFormat() QQuickTextEdit *textObject = qobject_cast<QQuickTextEdit*>(textComponent.create()); QVERIFY(textObject != 0); - QVERIFY(textObject->textFormat() == QQuickTextEdit::PlainText); + QCOMPARE(textObject->textFormat(), QQuickTextEdit::PlainText); } { QQmlComponent component(&engine); @@ -590,7 +599,7 @@ void tst_qquicktextedit::textFormat() QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(object.data()); QVERIFY(edit); - QSignalSpy spy(edit, SIGNAL(textFormatChanged(TextFormat))); + QSignalSpy spy(edit, &QQuickTextEdit::textFormatChanged); QCOMPARE(edit->textFormat(), QQuickTextEdit::PlainText); @@ -798,7 +807,7 @@ void tst_qquicktextedit::hAlign_RightToLeft() // keyboard input direction from qApp->inputMethod()->inputDirection textEdit->setText(""); platformInputContext.setInputDirection(Qt::LeftToRight); - QVERIFY(qApp->inputMethod()->inputDirection() == Qt::LeftToRight); + QCOMPARE(qApp->inputMethod()->inputDirection(), Qt::LeftToRight); QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft); QVERIFY(textEdit->positionToRectangle(0).x() < window.width()/2); @@ -806,7 +815,7 @@ void tst_qquicktextedit::hAlign_RightToLeft() platformInputContext.setInputDirection(Qt::RightToLeft); QCOMPARE(cursorRectangleSpy.count(), 1); - QVERIFY(qApp->inputMethod()->inputDirection() == Qt::RightToLeft); + QCOMPARE(qApp->inputMethod()->inputDirection(), Qt::RightToLeft); QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); QVERIFY(textEdit->positionToRectangle(0).x() > window.width()/2); @@ -1397,22 +1406,22 @@ void tst_qquicktextedit::selection() } textEditObject->setCursorPosition(0); - QVERIFY(textEditObject->cursorPosition() == 0); - QVERIFY(textEditObject->selectionStart() == 0); - QVERIFY(textEditObject->selectionEnd() == 0); + QCOMPARE(textEditObject->cursorPosition(), 0); + QCOMPARE(textEditObject->selectionStart(), 0); + QCOMPARE(textEditObject->selectionEnd(), 0); QVERIFY(textEditObject->selectedText().isNull()); // Verify invalid positions are ignored. textEditObject->setCursorPosition(-1); - QVERIFY(textEditObject->cursorPosition() == 0); - QVERIFY(textEditObject->selectionStart() == 0); - QVERIFY(textEditObject->selectionEnd() == 0); + QCOMPARE(textEditObject->cursorPosition(), 0); + QCOMPARE(textEditObject->selectionStart(), 0); + QCOMPARE(textEditObject->selectionEnd(), 0); QVERIFY(textEditObject->selectedText().isNull()); textEditObject->setCursorPosition(textEditObject->text().count()+1); - QVERIFY(textEditObject->cursorPosition() == 0); - QVERIFY(textEditObject->selectionStart() == 0); - QVERIFY(textEditObject->selectionEnd() == 0); + QCOMPARE(textEditObject->cursorPosition(), 0); + QCOMPARE(textEditObject->selectionStart(), 0); + QCOMPARE(textEditObject->selectionEnd(), 0); QVERIFY(textEditObject->selectedText().isNull()); //Test selection @@ -1426,9 +1435,9 @@ void tst_qquicktextedit::selection() } textEditObject->setCursorPosition(0); - QVERIFY(textEditObject->cursorPosition() == 0); - QVERIFY(textEditObject->selectionStart() == 0); - QVERIFY(textEditObject->selectionEnd() == 0); + QCOMPARE(textEditObject->cursorPosition(), 0); + QCOMPARE(textEditObject->selectionStart(), 0); + QCOMPARE(textEditObject->selectionEnd(), 0); QVERIFY(textEditObject->selectedText().isNull()); //Test Error Ignoring behaviour @@ -1443,20 +1452,20 @@ void tst_qquicktextedit::selection() textEditObject->select(0,100); QVERIFY(textEditObject->selectedText().isNull()); textEditObject->select(0,10); - QVERIFY(textEditObject->selectedText().size() == 10); + QCOMPARE(textEditObject->selectedText().size(), 10); textEditObject->select(-10,0); - QVERIFY(textEditObject->selectedText().size() == 10); + QCOMPARE(textEditObject->selectedText().size(), 10); textEditObject->select(100,101); - QVERIFY(textEditObject->selectedText().size() == 10); + QCOMPARE(textEditObject->selectedText().size(), 10); textEditObject->select(0,-10); - QVERIFY(textEditObject->selectedText().size() == 10); + QCOMPARE(textEditObject->selectedText().size(), 10); textEditObject->select(0,100); - QVERIFY(textEditObject->selectedText().size() == 10); + QCOMPARE(textEditObject->selectedText().size(), 10); textEditObject->deselect(); QVERIFY(textEditObject->selectedText().isNull()); textEditObject->select(0,10); - QVERIFY(textEditObject->selectedText().size() == 10); + QCOMPARE(textEditObject->selectedText().size(), 10); textEditObject->deselect(); QVERIFY(textEditObject->selectedText().isNull()); } @@ -1535,31 +1544,31 @@ void tst_qquicktextedit::keySelection() QSignalSpy spy(input, SIGNAL(selectedTextChanged())); simulateKey(&window, Qt::Key_Right, Qt::ShiftModifier); - QVERIFY(input->hasActiveFocus() == true); + QVERIFY(input->hasActiveFocus()); QCOMPARE(input->selectedText(), QString("a")); QCOMPARE(spy.count(), 1); simulateKey(&window, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == true); + QVERIFY(input->hasActiveFocus()); QCOMPARE(input->selectedText(), QString()); QCOMPARE(spy.count(), 2); simulateKey(&window, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == false); + QVERIFY(!input->hasActiveFocus()); QCOMPARE(input->selectedText(), QString()); QCOMPARE(spy.count(), 2); simulateKey(&window, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == true); + QVERIFY(input->hasActiveFocus()); QCOMPARE(spy.count(), 2); simulateKey(&window, Qt::Key_Left, Qt::ShiftModifier); - QVERIFY(input->hasActiveFocus() == true); + QVERIFY(input->hasActiveFocus()); QCOMPARE(input->selectedText(), QString("a")); QCOMPARE(spy.count(), 3); simulateKey(&window, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == true); + QVERIFY(input->hasActiveFocus()); QCOMPARE(input->selectedText(), QString()); QCOMPARE(spy.count(), 4); simulateKey(&window, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == false); + QVERIFY(!input->hasActiveFocus()); QCOMPARE(input->selectedText(), QString()); QCOMPARE(spy.count(), 4); } @@ -2107,7 +2116,7 @@ void tst_qquicktextedit::mouseSelectionMode_accessors() QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(object.data()); QVERIFY(edit); - QSignalSpy spy(edit, SIGNAL(mouseSelectionModeChanged(SelectionMode))); + QSignalSpy spy(edit, &QQuickTextEdit::mouseSelectionModeChanged); QCOMPARE(edit->mouseSelectionMode(), QQuickTextEdit::SelectCharacters); @@ -2362,8 +2371,8 @@ void tst_qquicktextedit::positionAt() secondLine.setLineWidth(texteditObject->width()); layout.endLayout(); - qreal y0; - qreal y1; + qreal y0 = 0; + qreal y1 = 0; switch (verticalAlignment) { case QQuickTextEdit::AlignTop: @@ -2594,9 +2603,7 @@ void tst_qquicktextedit::cursorDelegate() void tst_qquicktextedit::remoteCursorDelegate() { - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(dataDirectory(), TestHTTPServer::Delay); + ThreadedTestHTTPServer server(dataDirectory(), TestHTTPServer::Delay); QQuickView view; @@ -2732,20 +2739,21 @@ void tst_qquicktextedit::delegateLoading() QFETCH(QString, qmlfile); QFETCH(QString, error); - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(testFile("httpfail"), TestHTTPServer::Disconnect); - server.serveDirectory(testFile("httpslow"), TestHTTPServer::Delay); - server.serveDirectory(testFile("http")); + QHash<QString, TestHTTPServer::Mode> dirs; + dirs[testFile("httpfail")] = TestHTTPServer::Disconnect; + dirs[testFile("httpslow")] = TestHTTPServer::Delay; + dirs[testFile("http")] = TestHTTPServer::Normal; + ThreadedTestHTTPServer server(dirs); error.replace(QStringLiteral("{{ServerBaseUrl}}"), server.baseUrl().toString()); + if (!error.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, error.toUtf8()); QQuickView view(server.url(qmlfile)); view.show(); view.requestActivate(); if (!error.isEmpty()) { - QTest::ignoreMessage(QtWarningMsg, error.toUtf8()); QTRY_VERIFY(view.status()==QQuickView::Error); QTRY_VERIFY(!view.rootObject()); // there is fail item inside this test } else { @@ -2786,17 +2794,17 @@ void tst_qquicktextedit::navigation() QQuickTextEdit *input = qobject_cast<QQuickTextEdit *>(qvariant_cast<QObject *>(window.rootObject()->property("myInput"))); QVERIFY(input != 0); - QTRY_VERIFY(input->hasActiveFocus() == true); + QTRY_VERIFY(input->hasActiveFocus()); simulateKey(&window, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == false); + QVERIFY(!input->hasActiveFocus()); simulateKey(&window, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == true); + QVERIFY(input->hasActiveFocus()); simulateKey(&window, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == true); + QVERIFY(input->hasActiveFocus()); simulateKey(&window, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == false); + QVERIFY(!input->hasActiveFocus()); simulateKey(&window, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == true); + QVERIFY(input->hasActiveFocus()); // Test left and right navigation works if the TextEdit is empty (QTBUG-25447). input->setText(QString()); @@ -2976,8 +2984,8 @@ void tst_qquicktextedit::readOnly() QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(qvariant_cast<QObject *>(window.rootObject()->property("myInput"))); QVERIFY(edit != 0); - QTRY_VERIFY(edit->hasActiveFocus() == true); - QVERIFY(edit->isReadOnly() == true); + QTRY_VERIFY(edit->hasActiveFocus()); + QVERIFY(edit->isReadOnly()); QString initial = edit->text(); for (int k=Qt::Key_0; k<=Qt::Key_Z; k++) simulateKey(&window, k); @@ -3009,7 +3017,7 @@ void tst_qquicktextedit::textInput() QTest::qWaitForWindowActive(&view); QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(view.rootObject()); QVERIFY(edit); - QVERIFY(edit->hasActiveFocus() == true); + QVERIFY(edit->hasActiveFocus()); // test that input method event is committed and change signal is emitted QSignalSpy spy(edit, SIGNAL(textChanged())); @@ -3045,7 +3053,7 @@ void tst_qquicktextedit::inputMethodUpdate() QTest::qWaitForWindowActive(&view); QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(view.rootObject()); QVERIFY(edit); - QVERIFY(edit->hasActiveFocus() == true); + QVERIFY(edit->hasActiveFocus()); // text change even without cursor position change needs to trigger update edit->setText("test"); @@ -3219,15 +3227,15 @@ void tst_qquicktextedit::pastingRichText_QTBUG_14003() QQuickTextEdit *obj = qobject_cast<QQuickTextEdit*>(component.create()); QTRY_VERIFY(obj != 0); - QTRY_VERIFY(obj->textFormat() == QQuickTextEdit::PlainText); + QTRY_COMPARE(obj->textFormat(), QQuickTextEdit::PlainText); QMimeData *mData = new QMimeData; mData->setHtml("<font color=\"red\">Hello</font>"); QGuiApplication::clipboard()->setMimeData(mData); obj->paste(); - QTRY_VERIFY(obj->text() == ""); - QTRY_VERIFY(obj->textFormat() == QQuickTextEdit::PlainText); + QTRY_COMPARE(obj->text(), QString()); + QTRY_COMPARE(obj->textFormat(), QQuickTextEdit::PlainText); } #endif @@ -3253,11 +3261,11 @@ void tst_qquicktextedit::implicitSize() QQuickTextEdit *textObject = qobject_cast<QQuickTextEdit*>(textComponent.create()); QVERIFY(textObject->width() < textObject->implicitWidth()); - QVERIFY(textObject->height() == textObject->implicitHeight()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); textObject->resetWidth(); - QVERIFY(textObject->width() == textObject->implicitWidth()); - QVERIFY(textObject->height() == textObject->implicitHeight()); + QCOMPARE(textObject->width(), textObject->implicitWidth()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); } void tst_qquicktextedit::contentSize() @@ -3316,6 +3324,53 @@ void tst_qquicktextedit::implicitSizeBinding() QCOMPARE(textObject->height(), textObject->implicitHeight()); } +void tst_qquicktextedit::signal_editingfinished() +{ + QQuickView *window = new QQuickView(0); + window->setBaseSize(QSize(800,600)); + + window->setSource(testFileUrl("signal_editingfinished.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QCOMPARE(QGuiApplication::focusWindow(), window); + + QVERIFY(window->rootObject() != 0); + + QQuickTextEdit *input1 = qobject_cast<QQuickTextEdit *>(qvariant_cast<QObject *>(window->rootObject()->property("input1"))); + QVERIFY(input1); + QQuickTextEdit *input2 = qobject_cast<QQuickTextEdit *>(qvariant_cast<QObject *>(window->rootObject()->property("input2"))); + QVERIFY(input2); + + QSignalSpy editingFinished1Spy(input1, SIGNAL(editingFinished())); + + input1->setFocus(true); + QTRY_VERIFY(input1->hasActiveFocus()); + QTRY_VERIFY(!input2->hasActiveFocus()); + + QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + QTRY_COMPARE(editingFinished1Spy.count(), 1); + + QTRY_VERIFY(!input1->hasActiveFocus()); + QTRY_VERIFY(input2->hasActiveFocus()); + + QSignalSpy editingFinished2Spy(input2, SIGNAL(editingFinished())); + + input2->setFocus(true); + QTRY_VERIFY(!input1->hasActiveFocus()); + QTRY_VERIFY(input2->hasActiveFocus()); + + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + QTRY_COMPARE(editingFinished2Spy.count(), 1); + + QTRY_VERIFY(input1->hasActiveFocus()); + QTRY_VERIFY(!input2->hasActiveFocus()); +} + void tst_qquicktextedit::clipRect() { QQmlComponent component(&engine); @@ -3993,7 +4048,7 @@ void tst_qquicktextedit::append_data() << QString("Hello") << standard.at(0) + QString("\nHello") << 18 << standard.at(0).length() + 6 << standard.at(0).length() + 6 - << false << true; + << true << true; QTest::newRow("reversed selection kept intact") << standard.at(0) << QQuickTextEdit::PlainText @@ -4075,11 +4130,8 @@ void tst_qquicktextedit::append() if (selectionStart > selectionEnd) qSwap(selectionStart, selectionEnd); - QEXPECT_FAIL("into selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue); - QEXPECT_FAIL("into reversed selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue); QCOMPARE(selectionSpy.count() > 0, selectionChanged); QCOMPARE(selectionStartSpy.count() > 0, selectionStart != expectedSelectionStart); - QEXPECT_FAIL("into reversed selection", "selectionEndChanged signal not emitted", Continue); QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd); QCOMPARE(textSpy.count() > 0, text != expectedText); QCOMPARE(cursorPositionSpy.count() > 0, cursorPositionChanged); @@ -4162,7 +4214,7 @@ void tst_qquicktextedit::insert_data() << QString("Hello") << QString("Hello") + standard.at(0) << 19 << 24 << 24 - << false << true; + << true << true; QTest::newRow("before reversed selection") << standard.at(0) << QQuickTextEdit::PlainText @@ -4170,7 +4222,7 @@ void tst_qquicktextedit::insert_data() << QString("Hello") << QString("Hello") + standard.at(0) << 19 << 24 << 19 - << false << true; + << true << true; QTest::newRow("after selection") << standard.at(0) << QQuickTextEdit::PlainText @@ -4293,11 +4345,8 @@ void tst_qquicktextedit::insert() if (selectionStart > selectionEnd) qSwap(selectionStart, selectionEnd); - QEXPECT_FAIL("into selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue); - QEXPECT_FAIL("into reversed selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue); QCOMPARE(selectionSpy.count() > 0, selectionChanged); QCOMPARE(selectionStartSpy.count() > 0, selectionStart != expectedSelectionStart); - QEXPECT_FAIL("into reversed selection", "selectionEndChanged signal not emitted", Continue); QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd); QCOMPARE(textSpy.count() > 0, text != expectedText); QCOMPARE(cursorPositionSpy.count() > 0, cursorPositionChanged); @@ -4407,7 +4456,7 @@ void tst_qquicktextedit::remove_data() << 0 << 5 << standard.at(0).mid(5) << 9 << 14 << 14 - << false << true; + << true << true; QTest::newRow("before reversed selection") << standard.at(0) << QQuickTextEdit::PlainText @@ -4415,7 +4464,7 @@ void tst_qquicktextedit::remove_data() << 0 << 5 << standard.at(0).mid(5) << 9 << 14 << 9 - << false << true; + << true << true; QTest::newRow("after selection") << standard.at(0) << QQuickTextEdit::PlainText @@ -4537,11 +4586,8 @@ void tst_qquicktextedit::remove() QCOMPARE(textEdit->selectionEnd(), expectedSelectionEnd); QCOMPARE(textEdit->cursorPosition(), expectedCursorPosition); - QEXPECT_FAIL("from selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue); - QEXPECT_FAIL("from reversed selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue); QCOMPARE(selectionSpy.count() > 0, selectionChanged); QCOMPARE(selectionStartSpy.count() > 0, selectionStart != expectedSelectionStart); - QEXPECT_FAIL("from reversed selection", "selectionEndChanged signal not emitted", Continue); QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd); QCOMPARE(textSpy.count() > 0, text != expectedText); @@ -5220,8 +5266,8 @@ void tst_qquicktextedit::embeddedImages_data() QTest::newRow("local") << testFileUrl("embeddedImagesLocalRelative.qml") << ""; QTest::newRow("remote") << testFileUrl("embeddedImagesRemote.qml") << ""; QTest::newRow("remote-error") << testFileUrl("embeddedImagesRemoteError.qml") - << testFileUrl("embeddedImagesRemoteError.qml").toString()+":3:1: QML TextEdit: Error downloading {{ServerBaseUrl}}/notexists.png - server replied: Not found"; - QTest::newRow("remote-relative") << testFileUrl("embeddedImagesRemoteRelative.qml") << ""; + << testFileUrl("embeddedImagesRemoteError.qml").toString()+":3:1: QML TextEdit: Error transferring {{ServerBaseUrl}}/notexists.png - server replied: Not found"; + QTest::newRow("remote") << testFileUrl("embeddedImagesRemoteRelative.qml") << ""; } void tst_qquicktextedit::embeddedImages() @@ -5323,6 +5369,104 @@ void tst_qquicktextedit::textCached_QTBUG_41583() QVERIFY(!textedit->property("empty").toBool()); } +void tst_qquicktextedit::doubleSelect_QTBUG_38704() +{ + QString componentStr = "import QtQuick 2.2\nTextEdit { text: \"TextEdit\" }"; + QQmlComponent textEditComponent(&engine); + textEditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(textEditComponent.create()); + QVERIFY(textEdit != 0); + + QSignalSpy selectionSpy(textEdit, SIGNAL(selectedTextChanged())); + + textEdit->select(0,1); //Select some text initially + QCOMPARE(selectionSpy.count(), 1); + textEdit->select(0,1); //No change to selection start/end + QCOMPARE(selectionSpy.count(), 1); + textEdit->select(0,2); //Change selection end + QCOMPARE(selectionSpy.count(), 2); + textEdit->select(1,2); //Change selection start + QCOMPARE(selectionSpy.count(), 3); +} + +void tst_qquicktextedit::padding() +{ + QScopedPointer<QQuickView> window(new QQuickView); + window->setSource(testFileUrl("padding.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QQuickItem *root = window->rootObject(); + QVERIFY(root); + QQuickTextEdit *obj = qobject_cast<QQuickTextEdit*>(root); + QVERIFY(obj != 0); + + qreal cw = obj->contentWidth(); + qreal ch = obj->contentHeight(); + + QVERIFY(cw > 0); + QVERIFY(ch > 0); + + QCOMPARE(obj->topPadding(), 20.0); + QCOMPARE(obj->leftPadding(), 30.0); + QCOMPARE(obj->rightPadding(), 40.0); + QCOMPARE(obj->bottomPadding(), 50.0); + + QCOMPARE(obj->implicitWidth(), cw + obj->leftPadding() + obj->rightPadding()); + QCOMPARE(obj->implicitHeight(), ch + obj->topPadding() + obj->bottomPadding()); + + obj->setTopPadding(2.25); + QCOMPARE(obj->topPadding(), 2.25); + QCOMPARE(obj->implicitHeight(), ch + obj->topPadding() + obj->bottomPadding()); + + obj->setLeftPadding(3.75); + QCOMPARE(obj->leftPadding(), 3.75); + QCOMPARE(obj->implicitWidth(), cw + obj->leftPadding() + obj->rightPadding()); + + obj->setRightPadding(4.4); + QCOMPARE(obj->rightPadding(), 4.4); + QCOMPARE(obj->implicitWidth(), cw + obj->leftPadding() + obj->rightPadding()); + + obj->setBottomPadding(1.11); + QCOMPARE(obj->bottomPadding(), 1.11); + QCOMPARE(obj->implicitHeight(), ch + obj->topPadding() + obj->bottomPadding()); + + obj->setText("Qt"); + QVERIFY(obj->contentWidth() < cw); + QCOMPARE(obj->contentHeight(), ch); + cw = obj->contentWidth(); + + QCOMPARE(obj->implicitWidth(), cw + obj->leftPadding() + obj->rightPadding()); + QCOMPARE(obj->implicitHeight(), ch + obj->topPadding() + obj->bottomPadding()); + + obj->setFont(QFont("Courier", 96)); + QVERIFY(obj->contentWidth() > cw); + QVERIFY(obj->contentHeight() > ch); + cw = obj->contentWidth(); + ch = obj->contentHeight(); + + QCOMPARE(obj->implicitWidth(), cw + obj->leftPadding() + obj->rightPadding()); + QCOMPARE(obj->implicitHeight(), ch + obj->topPadding() + obj->bottomPadding()); + + obj->resetTopPadding(); + QCOMPARE(obj->topPadding(), 10.0); + obj->resetLeftPadding(); + QCOMPARE(obj->leftPadding(), 10.0); + obj->resetRightPadding(); + QCOMPARE(obj->rightPadding(), 10.0); + obj->resetBottomPadding(); + QCOMPARE(obj->bottomPadding(), 10.0); + + obj->resetPadding(); + QCOMPARE(obj->padding(), 0.0); + QCOMPARE(obj->topPadding(), 0.0); + QCOMPARE(obj->leftPadding(), 0.0); + QCOMPARE(obj->rightPadding(), 0.0); + QCOMPARE(obj->bottomPadding(), 0.0); + + delete root; +} + QTEST_MAIN(tst_qquicktextedit) #include "tst_qquicktextedit.moc" diff --git a/tests/auto/quick/qquicktextinput/data/padding.qml b/tests/auto/quick/qquicktextinput/data/padding.qml new file mode 100644 index 0000000000..23bfe20f22 --- /dev/null +++ b/tests/auto/quick/qquicktextinput/data/padding.qml @@ -0,0 +1,12 @@ +import QtQuick 2.6 + +TextInput { + width: 200; height: 200 + text: "Hello Qt" + + padding: 10 + topPadding: 20 + leftPadding: 30 + rightPadding: 40 + bottomPadding: 50 +} diff --git a/tests/auto/quick/qquicktextinput/qquicktextinput.pro b/tests/auto/quick/qquicktextinput/qquicktextinput.pro index c14b09c545..4929289920 100644 --- a/tests/auto/quick/qquicktextinput/qquicktextinput.pro +++ b/tests/auto/quick/qquicktextinput/qquicktextinput.pro @@ -13,4 +13,6 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib +osx: LIBS += -framework AppKit + DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index d87054ac9e..2a687b3c69 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -45,6 +45,7 @@ #include <QInputMethod> #include <private/qquicktextinput_p.h> #include <private/qquicktextinput_p_p.h> +#include <private/qquickvalidator_p.h> #include <QDebug> #include <QDir> #include <math.h> @@ -70,7 +71,7 @@ QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& QString persistent_dir = QQmlDataTest::instance()->dataDirectory(); QString arch = "unknown-architecture"; // QTest needs to help with this. - QString expectfile = persistent_dir + QDir::separator() + filebasename + "-" + arch + ".png"; + QString expectfile = persistent_dir + QDir::separator() + filebasename + QLatin1Char('-') + arch + ".png"; if (!QFile::exists(expectfile)) { actual.save(expectfile); @@ -222,6 +223,7 @@ private slots: void baselineOffset(); void ensureVisible(); + void padding(); private: void simulateKey(QWindow *, int key); @@ -591,7 +593,7 @@ void tst_qquicktextinput::wrap() textHeight = textObject->height(); QVERIFY(textObject != 0); - QVERIFY(textObject->wrapMode() == QQuickTextInput::WrapAnywhere); + QCOMPARE(textObject->wrapMode(), QQuickTextInput::WrapAnywhere); QCOMPARE(textObject->width(), 300.); delete textObject; @@ -658,22 +660,22 @@ void tst_qquicktextinput::selection() } textinputObject->setCursorPosition(0); - QVERIFY(textinputObject->cursorPosition() == 0); - QVERIFY(textinputObject->selectionStart() == 0); - QVERIFY(textinputObject->selectionEnd() == 0); + QCOMPARE(textinputObject->cursorPosition(), 0); + QCOMPARE(textinputObject->selectionStart(), 0); + QCOMPARE(textinputObject->selectionEnd(), 0); QVERIFY(textinputObject->selectedText().isNull()); // Verify invalid positions are ignored. textinputObject->setCursorPosition(-1); - QVERIFY(textinputObject->cursorPosition() == 0); - QVERIFY(textinputObject->selectionStart() == 0); - QVERIFY(textinputObject->selectionEnd() == 0); + QCOMPARE(textinputObject->cursorPosition(), 0); + QCOMPARE(textinputObject->selectionStart(), 0); + QCOMPARE(textinputObject->selectionEnd(), 0); QVERIFY(textinputObject->selectedText().isNull()); textinputObject->setCursorPosition(textinputObject->text().count()+1); - QVERIFY(textinputObject->cursorPosition() == 0); - QVERIFY(textinputObject->selectionStart() == 0); - QVERIFY(textinputObject->selectionEnd() == 0); + QCOMPARE(textinputObject->cursorPosition(), 0); + QCOMPARE(textinputObject->selectionStart(), 0); + QCOMPARE(textinputObject->selectionEnd(), 0); QVERIFY(textinputObject->selectedText().isNull()); //Test selection @@ -687,9 +689,9 @@ void tst_qquicktextinput::selection() } textinputObject->setCursorPosition(0); - QVERIFY(textinputObject->cursorPosition() == 0); - QVERIFY(textinputObject->selectionStart() == 0); - QVERIFY(textinputObject->selectionEnd() == 0); + QCOMPARE(textinputObject->cursorPosition(), 0); + QCOMPARE(textinputObject->selectionStart(), 0); + QCOMPARE(textinputObject->selectionEnd(), 0); QVERIFY(textinputObject->selectedText().isNull()); //Test Error Ignoring behaviour @@ -704,20 +706,20 @@ void tst_qquicktextinput::selection() textinputObject->select(0,100); QVERIFY(textinputObject->selectedText().isNull()); textinputObject->select(0,10); - QVERIFY(textinputObject->selectedText().size() == 10); + QCOMPARE(textinputObject->selectedText().size(), 10); textinputObject->select(-10,10); - QVERIFY(textinputObject->selectedText().size() == 10); + QCOMPARE(textinputObject->selectedText().size(), 10); textinputObject->select(100,101); - QVERIFY(textinputObject->selectedText().size() == 10); + QCOMPARE(textinputObject->selectedText().size(), 10); textinputObject->select(0,-10); - QVERIFY(textinputObject->selectedText().size() == 10); + QCOMPARE(textinputObject->selectedText().size(), 10); textinputObject->select(0,100); - QVERIFY(textinputObject->selectedText().size() == 10); + QCOMPARE(textinputObject->selectedText().size(), 10); textinputObject->deselect(); QVERIFY(textinputObject->selectedText().isNull()); textinputObject->select(0,10); - QVERIFY(textinputObject->selectedText().size() == 10); + QCOMPARE(textinputObject->selectedText().size(), 10); textinputObject->deselect(); QVERIFY(textinputObject->selectedText().isNull()); @@ -1513,13 +1515,13 @@ void tst_qquicktextinput::horizontalAlignment_RightToLeft() // keyboard input direction from QInputMethod::inputDirection() textInput->setText(""); platformInputContext.setInputDirection(Qt::LeftToRight); - QVERIFY(qApp->inputMethod()->inputDirection() == Qt::LeftToRight); + QCOMPARE(qApp->inputMethod()->inputDirection(), Qt::LeftToRight); QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft); QCOMPARE(textInput->boundingRect().left(), qreal(0)); QSignalSpy cursorRectangleSpy(textInput, SIGNAL(cursorRectangleChanged())); platformInputContext.setInputDirection(Qt::RightToLeft); - QVERIFY(qApp->inputMethod()->inputDirection() == Qt::RightToLeft); + QCOMPARE(qApp->inputMethod()->inputDirection(), Qt::RightToLeft); QCOMPARE(cursorRectangleSpy.count(), 1); QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); QVERIFY(textInput->boundingRect().right() >= textInput->width() - 1); @@ -1853,7 +1855,7 @@ void tst_qquicktextinput::maxLength() QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput *>(window.rootObject()); QVERIFY(textinputObject != 0); QVERIFY(textinputObject->text().isEmpty()); - QVERIFY(textinputObject->maxLength() == 10); + QCOMPARE(textinputObject->maxLength(), 10); foreach (const QString &str, standard) { QVERIFY(textinputObject->text().length() <= 10); textinputObject->setText(str); @@ -1861,7 +1863,7 @@ void tst_qquicktextinput::maxLength() } textinputObject->setText(""); - QTRY_VERIFY(textinputObject->hasActiveFocus() == true); + QTRY_VERIFY(textinputObject->hasActiveFocus()); for (int i=0; i<20; i++) { QTRY_COMPARE(textinputObject->text().length(), qMin(i,10)); //simulateKey(&window, Qt::Key_A); @@ -1880,8 +1882,8 @@ void tst_qquicktextinput::masks() QVERIFY(window.rootObject() != 0); QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput *>(window.rootObject()); QVERIFY(textinputObject != 0); - QTRY_VERIFY(textinputObject->hasActiveFocus() == true); - QVERIFY(textinputObject->text().length() == 0); + QTRY_VERIFY(textinputObject->hasActiveFocus()); + QCOMPARE(textinputObject->text().length(), 0); QCOMPARE(textinputObject->inputMask(), QString("HHHHhhhh; ")); QCOMPARE(textinputObject->length(), 8); for (int i=0; i<10; i++) { @@ -1997,7 +1999,7 @@ void tst_qquicktextinput::validators() QCOMPARE(dblInput->validator()->locale(), defaultLocale); dblInput->setFocus(true); - QVERIFY(dblInput->hasActiveFocus() == true); + QVERIFY(dblInput->hasActiveFocus()); QCOMPARE(dblInput->hasAcceptableInput(), false); QCOMPARE(dblInput->property("acceptable").toBool(), false); QTest::keyPress(&window, Qt::Key_1); @@ -2131,7 +2133,7 @@ void tst_qquicktextinput::validators() QVERIFY(strInput); QSignalSpy strSpy(strInput, SIGNAL(acceptableInputChanged())); strInput->setFocus(true); - QVERIFY(strInput->hasActiveFocus() == true); + QVERIFY(strInput->hasActiveFocus()); QCOMPARE(strInput->hasAcceptableInput(), false); QCOMPARE(strInput->property("acceptable").toBool(), false); QTest::keyPress(&window, Qt::Key_1); @@ -2175,7 +2177,7 @@ void tst_qquicktextinput::validators() QVERIFY(unvalidatedInput); QSignalSpy unvalidatedSpy(unvalidatedInput, SIGNAL(acceptableInputChanged())); unvalidatedInput->setFocus(true); - QVERIFY(unvalidatedInput->hasActiveFocus() == true); + QVERIFY(unvalidatedInput->hasActiveFocus()); QCOMPARE(unvalidatedInput->hasAcceptableInput(), true); QCOMPARE(unvalidatedInput->property("acceptable").toBool(), true); QTest::keyPress(&window, Qt::Key_1); @@ -2216,7 +2218,7 @@ void tst_qquicktextinput::inputMethods() QCOMPARE(plainInput.inputMethodHints(), Qt::ImhNone); input->setFocus(true); - QVERIFY(input->hasActiveFocus() == true); + QVERIFY(input->hasActiveFocus()); // test that input method event is committed QInputMethodEvent event; event.setCommitString( "My ", -12, 0); @@ -2399,23 +2401,23 @@ void tst_qquicktextinput::navigation() QVERIFY(input != 0); input->setCursorPosition(0); - QTRY_VERIFY(input->hasActiveFocus() == true); + QTRY_VERIFY(input->hasActiveFocus()); simulateKey(&window, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == false); + QVERIFY(!input->hasActiveFocus()); simulateKey(&window, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == true); + QVERIFY(input->hasActiveFocus()); //QT-2944: If text is selected, ensure we deselect upon cursor motion input->setCursorPosition(input->text().length()); input->select(0,input->text().length()); QVERIFY(input->selectionStart() != input->selectionEnd()); simulateKey(&window, Qt::Key_Right); - QVERIFY(input->selectionStart() == input->selectionEnd()); - QVERIFY(input->selectionStart() == input->text().length()); - QVERIFY(input->hasActiveFocus() == true); + QCOMPARE(input->selectionStart(), input->selectionEnd()); + QCOMPARE(input->selectionStart(), input->text().length()); + QVERIFY(input->hasActiveFocus()); simulateKey(&window, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == false); + QVERIFY(!input->hasActiveFocus()); simulateKey(&window, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == true); + QVERIFY(input->hasActiveFocus()); // Up and Down should NOT do Home/End, even on OS X (QTBUG-10438). input->setCursorPosition(2); @@ -2451,26 +2453,26 @@ void tst_qquicktextinput::navigation_RTL() input->setText(QString::fromUtf16(arabic_str, 11)); input->setCursorPosition(0); - QTRY_VERIFY(input->hasActiveFocus() == true); + QTRY_VERIFY(input->hasActiveFocus()); // move off simulateKey(&window, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == false); + QVERIFY(!input->hasActiveFocus()); // move back simulateKey(&window, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == true); + QVERIFY(input->hasActiveFocus()); input->setCursorPosition(input->text().length()); - QVERIFY(input->hasActiveFocus() == true); + QVERIFY(input->hasActiveFocus()); // move off simulateKey(&window, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == false); + QVERIFY(!input->hasActiveFocus()); // move back simulateKey(&window, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == true); + QVERIFY(input->hasActiveFocus()); } #ifndef QT_NO_CLIPBOARD @@ -2855,10 +2857,7 @@ void tst_qquicktextinput::cursorDelegate() void tst_qquicktextinput::remoteCursorDelegate() { - TestHTTPServer server; - QVERIFY2(server.listen(), qPrintable(server.errorString())); - server.serveDirectory(dataDirectory(), TestHTTPServer::Delay); - + ThreadedTestHTTPServer server(dataDirectory(), TestHTTPServer::Delay); QQuickView view; QQmlComponent component(view.engine(), server.url("/RemoteCursor.qml")); @@ -2996,6 +2995,14 @@ void tst_qquicktextinput::cursorRectangle_data() << false; } +#ifndef QT_NO_IM +#define COMPARE_INPUT_METHOD_QUERY(type, input, property, method, result) \ + QCOMPARE((type) input->inputMethodQuery(property).method(), result); +#else +#define COMPARE_INPUT_METHOD_QUERY(type, input, property, method, result) \ + qt_noop() +#endif + void tst_qquicktextinput::cursorRectangle() { QFETCH(QString, text); @@ -3035,7 +3042,7 @@ void tst_qquicktextinput::cursorRectangle() r = input.cursorRectangle(); QCOMPARE(r.left(), line.cursorToX(i, QTextLine::Leading) - offset); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(i), r); } @@ -3045,7 +3052,7 @@ void tst_qquicktextinput::cursorRectangle() for (int i = positionAtWidth + 1; i < text.length(); ++i) { input.setCursorPosition(i); QCOMPARE(r, input.cursorRectangle()); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(i), r); } @@ -3058,7 +3065,7 @@ void tst_qquicktextinput::cursorRectangle() } else { QVERIFY(r.left() <= input.width()); } - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(i), r); } @@ -3071,7 +3078,7 @@ void tst_qquicktextinput::cursorRectangle() QCOMPARE(r.left(), line.cursorToX(i, QTextLine::Leading) - offset); QCOMPARE(r.top(), 0.); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(i), r); } @@ -3082,15 +3089,17 @@ void tst_qquicktextinput::cursorRectangle() } else { QCOMPARE(r.left(), input.width()); } - QVERIFY(r.top() >= line.height() - 1); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + // we can't be exact here, as the space character can have a different ascent/descent from the arabic chars + // this then leads to different line heights between the wrapped and non wrapped texts + QVERIFY(r.top() >= line.height() - 5); + COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(11), r); for (int i = wrapPosition + 1; i < text.length(); ++i) { input.setCursorPosition(i); r = input.cursorRectangle(); - QVERIFY(r.top() >= line.height() - 1); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QVERIFY(r.top() >= line.height() - 5); + COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(i), r); } @@ -3102,7 +3111,7 @@ void tst_qquicktextinput::cursorRectangle() QCOMPARE(r.left(), line.cursorToX(i, QTextLine::Leading) - offset); QCOMPARE(r.top(), 0.); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(i), r); } @@ -3112,7 +3121,7 @@ void tst_qquicktextinput::cursorRectangle() for (int i = positionAtWidth + 1; i < wrapPosition && leftToRight; ++i) { input.setCursorPosition(i); QCOMPARE(r, input.cursorRectangle()); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(i), r); } @@ -3124,14 +3133,14 @@ void tst_qquicktextinput::cursorRectangle() QCOMPARE(r.left(), input.width()); } QVERIFY(r.bottom() >= input.height()); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(11), r); for (int i = wrapPosition + 1; i < text.length(); ++i) { input.setCursorPosition(i); r = input.cursorRectangle(); QVERIFY(r.bottom() >= input.height()); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(i), r); } @@ -3139,7 +3148,7 @@ void tst_qquicktextinput::cursorRectangle() input.setCursorPosition(i); r = input.cursorRectangle(); QVERIFY(r.bottom() >= input.height()); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(i), r); } @@ -3147,13 +3156,13 @@ void tst_qquicktextinput::cursorRectangle() r = input.cursorRectangle(); QCOMPARE(r.top(), 0.); QCOMPARE(r.left(), leftToRight ? input.width() : 0); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(10), r); for (int i = wrapPosition - 2; i >= positionAtWidth + 1; --i) { input.setCursorPosition(i); QCOMPARE(r, input.cursorRectangle()); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(i), r); } @@ -3161,7 +3170,7 @@ void tst_qquicktextinput::cursorRectangle() input.setCursorPosition(i); r = input.cursorRectangle(); QCOMPARE(r.top(), 0.); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(i), r); } @@ -3190,9 +3199,9 @@ void tst_qquicktextinput::readOnly() QQuickTextInput *input = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(window.rootObject()->property("myInput"))); QVERIFY(input != 0); - QTRY_VERIFY(input->hasActiveFocus() == true); - QVERIFY(input->isReadOnly() == true); - QVERIFY(input->isCursorVisible() == false); + QTRY_VERIFY(input->hasActiveFocus()); + QVERIFY(input->isReadOnly()); + QVERIFY(!input->isCursorVisible()); QString initial = input->text(); for (int k=Qt::Key_0; k<=Qt::Key_Z; k++) simulateKey(&window, k); @@ -3205,7 +3214,7 @@ void tst_qquicktextinput::readOnly() input->setReadOnly(false); QCOMPARE(input->isReadOnly(), false); QCOMPARE(input->cursorPosition(), input->text().length()); - QVERIFY(input->isCursorVisible() == true); + QVERIFY(input->isCursorVisible()); } void tst_qquicktextinput::echoMode() @@ -3220,7 +3229,7 @@ void tst_qquicktextinput::echoMode() QQuickTextInput *input = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(window.rootObject()->property("myInput"))); QVERIFY(input != 0); - QTRY_VERIFY(input->hasActiveFocus() == true); + QTRY_VERIFY(input->hasActiveFocus()); QString initial = input->text(); Qt::InputMethodHints ref; QCOMPARE(initial, QLatin1String("ABCDefgh")); @@ -3230,7 +3239,7 @@ void tst_qquicktextinput::echoMode() //Normal ref &= ~Qt::ImhHiddenText; ref &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData); - QCOMPARE((Qt::InputMethodHints) input->inputMethodQuery(Qt::ImHints).toInt(), ref); + COMPARE_INPUT_METHOD_QUERY(Qt::InputMethodHints, input, Qt::ImHints, toInt, ref); input->setEchoMode(QQuickTextInput::NoEcho); QCOMPARE(input->text(), initial); QCOMPARE(input->displayText(), QLatin1String("")); @@ -3238,17 +3247,17 @@ void tst_qquicktextinput::echoMode() //NoEcho ref |= Qt::ImhHiddenText; ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData); - QCOMPARE((Qt::InputMethodHints) input->inputMethodQuery(Qt::ImHints).toInt(), ref); + COMPARE_INPUT_METHOD_QUERY(Qt::InputMethodHints, input, Qt::ImHints, toInt, ref); input->setEchoMode(QQuickTextInput::Password); //Password ref |= Qt::ImhHiddenText; ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData); QCOMPARE(input->text(), initial); QCOMPARE(input->displayText(), QString(8, passwordMaskCharacter.at(0))); - QCOMPARE((Qt::InputMethodHints) input->inputMethodQuery(Qt::ImHints).toInt(), ref); + COMPARE_INPUT_METHOD_QUERY(Qt::InputMethodHints, input, Qt::ImHints, toInt, ref); // clearing input hints do not clear bits set by echo mode input->setInputMethodHints(Qt::ImhNone); - QCOMPARE((Qt::InputMethodHints) input->inputMethodQuery(Qt::ImHints).toInt(), ref); + COMPARE_INPUT_METHOD_QUERY(Qt::InputMethodHints, input, Qt::ImHints, toInt, ref); input->setPasswordCharacter(QChar('Q')); QCOMPARE(input->passwordCharacter(), QLatin1String("Q")); QCOMPARE(input->text(), initial); @@ -3257,19 +3266,20 @@ void tst_qquicktextinput::echoMode() //PasswordEchoOnEdit ref &= ~Qt::ImhHiddenText; ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData); - QCOMPARE((Qt::InputMethodHints) input->inputMethodQuery(Qt::ImHints).toInt(), ref); + COMPARE_INPUT_METHOD_QUERY(Qt::InputMethodHints, input, Qt::ImHints, toInt, ref); QCOMPARE(input->text(), initial); QCOMPARE(input->displayText(), QLatin1String("QQQQQQQQ")); - QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("QQQQQQQQ")); + COMPARE_INPUT_METHOD_QUERY(QString, input, Qt::ImSurroundingText, toString, + QLatin1String("QQQQQQQQ")); QTest::keyPress(&window, Qt::Key_A);//Clearing previous entry is part of PasswordEchoOnEdit QTest::keyRelease(&window, Qt::Key_A, Qt::NoModifier ,10); QCOMPARE(input->text(), QLatin1String("a")); QCOMPARE(input->displayText(), QLatin1String("a")); - QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("a")); + COMPARE_INPUT_METHOD_QUERY(QString, input, Qt::ImSurroundingText, toString, QLatin1String("a")); input->setFocus(false); - QVERIFY(input->hasActiveFocus() == false); + QVERIFY(!input->hasActiveFocus()); QCOMPARE(input->displayText(), QLatin1String("Q")); - QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("Q")); + COMPARE_INPUT_METHOD_QUERY(QString, input, Qt::ImSurroundingText, toString, QLatin1String("Q")); input->setFocus(true); QVERIFY(input->hasActiveFocus()); QInputMethodEvent inputEvent; @@ -3277,7 +3287,7 @@ void tst_qquicktextinput::echoMode() QGuiApplication::sendEvent(input, &inputEvent); QCOMPARE(input->text(), initial); QCOMPARE(input->displayText(), initial); - QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), initial); + COMPARE_INPUT_METHOD_QUERY(QString, input, Qt::ImSurroundingText, toString, initial); } void tst_qquicktextinput::passwordEchoDelay() @@ -5077,6 +5087,10 @@ void tst_qquicktextinput::keySequence_data() << standard.at(0) << QKeySequence(QKeySequence::DeleteStartOfWord) << 7 << 7 << 4 << (standard.at(0).mid(0, 4) + standard.at(0).mid(7)) << QString() << QQuickTextInput::Normal << Qt::Key_Direction_L; + QTest::newRow("delete complete line") + << standard.at(0) << QKeySequence(QKeySequence::DeleteCompleteLine) << 0 << 0 + << 0 << QString() << QString() + << QQuickTextInput::Normal << Qt::Key_Direction_L; } void tst_qquicktextinput::keySequence() @@ -5819,11 +5833,11 @@ void tst_qquicktextinput::implicitSize() QQuickTextInput *textObject = qobject_cast<QQuickTextInput*>(textComponent.create()); QVERIFY(textObject->width() < textObject->implicitWidth()); - QVERIFY(textObject->height() == textObject->implicitHeight()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); textObject->resetWidth(); - QVERIFY(textObject->width() == textObject->implicitWidth()); - QVERIFY(textObject->height() == textObject->implicitHeight()); + QCOMPARE(textObject->width(), textObject->implicitWidth()); + QCOMPARE(textObject->height(), textObject->implicitHeight()); } void tst_qquicktextinput::implicitSizeBinding_data() @@ -6370,25 +6384,25 @@ Q_DECLARE_METATYPE(ExpectedBaseline) static qreal expectedBaselineTop(QQuickTextInput *item) { QFontMetricsF fm(item->font()); - return fm.ascent(); + return fm.ascent() + item->topPadding(); } static qreal expectedBaselineBottom(QQuickTextInput *item) { QFontMetricsF fm(item->font()); - return item->height() - item->contentHeight() + fm.ascent(); + return item->height() - item->contentHeight() - item->bottomPadding() + fm.ascent(); } static qreal expectedBaselineCenter(QQuickTextInput *item) { QFontMetricsF fm(item->font()); - return ((item->height() - item->contentHeight()) / 2) + fm.ascent(); + return ((item->height() - item->contentHeight() - item->topPadding() - item->bottomPadding()) / 2) + fm.ascent() + item->topPadding(); } static qreal expectedBaselineMultilineBottom(QQuickTextInput *item) { QFontMetricsF fm(item->font()); - return item->height() - item->contentHeight() + fm.ascent(); + return item->height() - item->contentHeight() - item->bottomPadding() + fm.ascent(); } void tst_qquicktextinput::baselineOffset_data() @@ -6433,6 +6447,41 @@ void tst_qquicktextinput::baselineOffset_data() << -1. << &expectedBaselineMultilineBottom << &expectedBaselineBottom; + + QTest::newRow("padding") + << "Typography" + << QByteArray("topPadding: 10; bottomPadding: 20") + << -1. + << &expectedBaselineTop + << &expectedBaselineTop; + + QTest::newRow("top align with padding") + << "Typography" + << QByteArray("height: 200; verticalAlignment: Text.AlignTop; topPadding: 10; bottomPadding: 20") + << -1. + << &expectedBaselineTop + << &expectedBaselineTop; + + QTest::newRow("bottom align with padding") + << "Typography" + << QByteArray("height: 200; verticalAlignment: Text.AlignBottom; topPadding: 10; bottomPadding: 20") + << 100. + << &expectedBaselineBottom + << &expectedBaselineBottom; + + QTest::newRow("center align with padding") + << "Typography" + << QByteArray("height: 200; verticalAlignment: Text.AlignVCenter; topPadding: 10; bottomPadding: 20") + << 100. + << &expectedBaselineCenter + << &expectedBaselineCenter; + + QTest::newRow("multiline bottom aligned with padding") + << "The quick brown fox jumps over the lazy dog" + << QByteArray("height: 200; width: 30; verticalAlignment: Text.AlignBottom; wrapMode: TextInput.WordWrap; topPadding: 10; bottomPadding: 20") + << -1. + << &expectedBaselineMultilineBottom + << &expectedBaselineBottom; } void tst_qquicktextinput::baselineOffset() @@ -6445,7 +6494,7 @@ void tst_qquicktextinput::baselineOffset() QQmlComponent component(&engine); component.setData( - "import QtQuick 2.0\n" + "import QtQuick 2.6\n" "TextInput {\n" + bindings + "\n" "}", QUrl()); @@ -6510,6 +6559,85 @@ void tst_qquicktextinput::ensureVisible() QCOMPARE(input->boundingRect().height(), line.height()); } +void tst_qquicktextinput::padding() +{ + QScopedPointer<QQuickView> window(new QQuickView); + window->setSource(testFileUrl("padding.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QQuickItem *root = window->rootObject(); + QVERIFY(root); + QQuickTextInput *obj = qobject_cast<QQuickTextInput*>(root); + QVERIFY(obj != 0); + + qreal cw = obj->contentWidth(); + qreal ch = obj->contentHeight(); + + QVERIFY(cw > 0); + QVERIFY(ch > 0); + + QCOMPARE(obj->padding(), 10.0); + QCOMPARE(obj->topPadding(), 20.0); + QCOMPARE(obj->leftPadding(), 30.0); + QCOMPARE(obj->rightPadding(), 40.0); + QCOMPARE(obj->bottomPadding(), 50.0); + + QCOMPARE(obj->implicitWidth(), qCeil(cw) + obj->leftPadding() + obj->rightPadding()); + QCOMPARE(obj->implicitHeight(), qCeil(ch) + obj->topPadding() + obj->bottomPadding()); + + obj->setTopPadding(2.25); + QCOMPARE(obj->topPadding(), 2.25); + QCOMPARE(obj->implicitHeight(), qCeil(ch) + obj->topPadding() + obj->bottomPadding()); + + obj->setLeftPadding(3.75); + QCOMPARE(obj->leftPadding(), 3.75); + QCOMPARE(obj->implicitWidth(), qCeil(cw) + obj->leftPadding() + obj->rightPadding()); + + obj->setRightPadding(4.4); + QCOMPARE(obj->rightPadding(), 4.4); + QCOMPARE(obj->implicitWidth(), qCeil(cw) + obj->leftPadding() + obj->rightPadding()); + + obj->setBottomPadding(1.11); + QCOMPARE(obj->bottomPadding(), 1.11); + QCOMPARE(obj->implicitHeight(), qCeil(ch) + obj->topPadding() + obj->bottomPadding()); + + obj->setText("Qt"); + QVERIFY(obj->contentWidth() < cw); + QCOMPARE(obj->contentHeight(), ch); + cw = obj->contentWidth(); + + QCOMPARE(obj->implicitWidth(), qCeil(cw) + obj->leftPadding() + obj->rightPadding()); + QCOMPARE(obj->implicitHeight(), qCeil(ch) + obj->topPadding() + obj->bottomPadding()); + + obj->setFont(QFont("Courier", 96)); + QVERIFY(obj->contentWidth() > cw); + QVERIFY(obj->contentHeight() > ch); + cw = obj->contentWidth(); + ch = obj->contentHeight(); + + QCOMPARE(obj->implicitWidth(), qCeil(cw) + obj->leftPadding() + obj->rightPadding()); + QCOMPARE(obj->implicitHeight(), qCeil(ch) + obj->topPadding() + obj->bottomPadding()); + + obj->resetTopPadding(); + QCOMPARE(obj->topPadding(), 10.0); + obj->resetLeftPadding(); + QCOMPARE(obj->leftPadding(), 10.0); + obj->resetRightPadding(); + QCOMPARE(obj->rightPadding(), 10.0); + obj->resetBottomPadding(); + QCOMPARE(obj->bottomPadding(), 10.0); + + obj->resetPadding(); + QCOMPARE(obj->padding(), 0.0); + QCOMPARE(obj->topPadding(), 0.0); + QCOMPARE(obj->leftPadding(), 0.0); + QCOMPARE(obj->rightPadding(), 0.0); + QCOMPARE(obj->bottomPadding(), 0.0); + + delete root; +} + QTEST_MAIN(tst_qquicktextinput) #include "tst_qquicktextinput.moc" diff --git a/tests/auto/quick/qquickview/data/error2.qml b/tests/auto/quick/qquickview/data/error2.qml new file mode 100644 index 0000000000..1d754b64f0 --- /dev/null +++ b/tests/auto/quick/qquickview/data/error2.qml @@ -0,0 +1,4 @@ +import QtQuick.Window 2.0 + +Window { +} diff --git a/tests/auto/quick/qquickview/tst_qquickview.cpp b/tests/auto/quick/qquickview/tst_qquickview.cpp index a980c69140..69e27984c7 100644 --- a/tests/auto/quick/qquickview/tst_qquickview.cpp +++ b/tests/auto/quick/qquickview/tst_qquickview.cpp @@ -182,10 +182,23 @@ void tst_QQuickView::errors() { { QQuickView view; + QVERIFY(view.errors().isEmpty()); // don't crash + } + { + QQuickView view; QQmlTestMessageHandler messageHandler; view.setSource(testFileUrl("error1.qml")); - QVERIFY(view.status() == QQuickView::Error); - QVERIFY(view.errors().count() == 1); + QCOMPARE(view.status(), QQuickView::Error); + QCOMPARE(view.errors().count(), 1); + } + + { + QQuickView view; + QQmlTestMessageHandler messageHandler; + view.setSource(testFileUrl("error2.qml")); + QCOMPARE(view.status(), QQuickView::Error); + QCOMPARE(view.errors().count(), 1); + view.show(); } } @@ -196,16 +209,16 @@ void tst_QQuickView::engine() QQuickView *view = new QQuickView(engine, 0); QVERIFY(view); - QVERIFY(engine->incubationController() == view->incubationController()); + QCOMPARE(engine->incubationController(), view->incubationController()); QQuickView *view2 = new QQuickView(engine, 0); QVERIFY(view); - QVERIFY(engine->incubationController() == view->incubationController()); + QCOMPARE(engine->incubationController(), view->incubationController()); delete view; QVERIFY(!engine->incubationController()); engine->setIncubationController(view2->incubationController()); - QVERIFY(engine->incubationController() == view2->incubationController()); + QCOMPARE(engine->incubationController(), view2->incubationController()); delete view2; QVERIFY(!engine->incubationController()); diff --git a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp index 2dd9e77370..d578a0900c 100644 --- a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp +++ b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp @@ -513,15 +513,15 @@ void tst_qquickvisualdatamodel::rootIndex() QVERIFY(obj != 0); QMetaObject::invokeMethod(obj, "setRoot"); - QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0)); + QCOMPARE(qvariant_cast<QModelIndex>(obj->rootIndex()), model.index(0,0)); QMetaObject::invokeMethod(obj, "setRootToParent"); - QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex()); + QCOMPARE(qvariant_cast<QModelIndex>(obj->rootIndex()), QModelIndex()); QMetaObject::invokeMethod(obj, "setRoot"); - QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0)); + QCOMPARE(qvariant_cast<QModelIndex>(obj->rootIndex()), model.index(0,0)); model.clear(); // will emit modelReset() - QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex()); + QCOMPARE(qvariant_cast<QModelIndex>(obj->rootIndex()), QModelIndex()); delete obj; } @@ -628,7 +628,7 @@ void tst_qquickvisualdatamodel::childChanged() model.item(1,0)->takeRow(1); name = findItem<QQuickText>(contentItem, "display", 1); - QVERIFY(name == 0); + QVERIFY(!name); vdm->setRootIndex(QVariant::fromValue(QModelIndex())); QCOMPARE(listview->count(), 3); diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index dfe5276e8e..f53ade9541 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -277,6 +277,10 @@ class tst_qquickwindow : public QQmlDataTest { Q_OBJECT public: + tst_qquickwindow() + { + QQuickWindow::setDefaultAlphaBuffer(true); + } private slots: void initTestCase() @@ -504,7 +508,7 @@ void tst_qquickwindow::touchEvent_basic() window->resize(250, 250); window->setPosition(100, 100); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window)); + QVERIFY(QTest::qWaitForWindowActive(window)); TestTouchItem *bottomItem = new TestTouchItem(window->contentItem()); bottomItem->setObjectName("Bottom Item"); @@ -635,7 +639,7 @@ void tst_qquickwindow::touchEvent_propagation() window->setPosition(100, 100); window->setTitle(QTest::currentTestFunction()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window)); + QVERIFY(QTest::qWaitForWindowActive(window)); TestTouchItem *bottomItem = new TestTouchItem(window->contentItem()); bottomItem->setObjectName("Bottom Item"); @@ -769,18 +773,18 @@ void tst_qquickwindow::touchEvent_cancel() window->setPosition(100, 100); window->setTitle(QTest::currentTestFunction()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window)); + QVERIFY(QTest::qWaitForWindowActive(window)); TestTouchItem *item = new TestTouchItem(window->contentItem()); item->setPosition(QPointF(50, 50)); item->setSize(QSizeF(150, 150)); - QPointF pos(10, 10); - QTest::touchEvent(window, touchDevice).press(0, item->mapToScene(pos).toPoint(),window); + QPointF pos(50, 50); + QTest::touchEvent(window, touchDevice).press(0, item->mapToScene(pos).toPoint(), window); QCoreApplication::processEvents(); QTRY_COMPARE(item->lastEvent.touchPoints.count(), 1); - TouchEventData d = makeTouchData(QEvent::TouchBegin, window, Qt::TouchPointPressed, makeTouchPoint(item,pos)); + TouchEventData d = makeTouchData(QEvent::TouchBegin, window, Qt::TouchPointPressed, makeTouchPoint(item, pos)); COMPARE_TOUCH_DATA(item->lastEvent, d); item->reset(); @@ -803,7 +807,7 @@ void tst_qquickwindow::touchEvent_reentrant() window->setPosition(100, 100); window->setTitle(QTest::currentTestFunction()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window)); + QVERIFY(QTest::qWaitForWindowActive(window)); TestTouchItem *item = new TestTouchItem(window->contentItem()); @@ -978,7 +982,7 @@ void tst_qquickwindow::clearWindow() delete window; - QVERIFY(item->window() == 0); + QVERIFY(!item->window()); delete item; } @@ -993,7 +997,7 @@ void tst_qquickwindow::mouseFiltering() window->setPosition(100, 100); window->setTitle(QTest::currentTestFunction()); window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window)); + QVERIFY(QTest::qWaitForWindowActive(window)); TestTouchItem *bottomItem = new TestTouchItem(window->contentItem()); bottomItem->setObjectName("Bottom Item"); @@ -1081,17 +1085,25 @@ void tst_qquickwindow::defaultState() void tst_qquickwindow::grab_data() { QTest::addColumn<bool>("visible"); - QTest::newRow("visible") << true; - QTest::newRow("invisible") << false; + QTest::addColumn<bool>("alpha"); + QTest::newRow("visible,opaque") << true << false; + QTest::newRow("invisible,opaque") << false << false; + QTest::newRow("visible,transparent") << true << true; + QTest::newRow("invisible,transparent") << false << true; } void tst_qquickwindow::grab() { QFETCH(bool, visible); + QFETCH(bool, alpha); QQuickWindow window; window.setTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1Char(' ') + QLatin1String(QTest::currentDataTag())); - window.setColor(Qt::red); + if (alpha) { + window.setColor(QColor(0, 0, 0, 0)); + } else { + window.setColor(Qt::red); + } window.resize(250, 250); @@ -1103,9 +1115,14 @@ void tst_qquickwindow::grab() } QImage content = window.grabWindow(); - QCOMPARE(content.width(), window.width()); - QCOMPARE(content.height(), window.height()); - QCOMPARE((uint) content.convertToFormat(QImage::Format_RGB32).pixel(0, 0), (uint) 0xffff0000); + QCOMPARE(content.width(), int(window.width() * window.devicePixelRatio())); + QCOMPARE(content.height(), int(window.height() * window.devicePixelRatio())); + + if (alpha) { + QCOMPARE((uint) content.convertToFormat(QImage::Format_ARGB32_Premultiplied).pixel(0, 0), (uint) 0x00000000); + } else { + QCOMPARE((uint) content.convertToFormat(QImage::Format_RGB32).pixel(0, 0), (uint) 0xffff0000); + } } void tst_qquickwindow::multipleWindows() @@ -1232,7 +1249,7 @@ void tst_qquickwindow::headless() if (threaded) { QTRY_COMPARE(invalidated.size(), 1); - QVERIFY(window->openglContext() == 0); + QVERIFY(!window->openglContext()); } if (QGuiApplication::platformName() == QLatin1String("windows") @@ -1242,7 +1259,7 @@ void tst_qquickwindow::headless() // Destroy the native windowing system buffers window->destroy(); - QVERIFY(window->handle() == 0); + QVERIFY(!window->handle()); // Show and verify that we are back and running window->show(); @@ -1452,7 +1469,7 @@ void tst_qquickwindow::cursor() clippedItem.setParentItem(&clippingItem); window.show(); - QVERIFY(QTest::qWaitForWindowExposed(&window)); + QVERIFY(QTest::qWaitForWindowActive(&window)); // Position the cursor over the parent and child item and the clipped section of clippedItem. QTest::mouseMove(&window, QPoint(100, 100)); @@ -1609,7 +1626,7 @@ void tst_qquickwindow::hideThenDelete() if (!persistentGL) QVERIFY(openglDestroyed->size() > 0); else - QVERIFY(openglDestroyed->size() == 0); + QCOMPARE(openglDestroyed->size(), 0); } else { QCOMPARE(sgInvalidated->size(), 0); QCOMPARE(openglDestroyed->size(), 0); @@ -1693,7 +1710,7 @@ void tst_qquickwindow::requestActivate() window1->requestActivate(); // and then transfer the focus to window1 QTRY_COMPARE(QGuiApplication::focusWindow(), window1.data()); - QVERIFY(window1->isActive() == true); + QVERIFY(window1->isActive()); QQuickItem *item = QQuickVisualTestUtil::findItem<QQuickItem>(window1->contentItem(), "item1"); QVERIFY(item); @@ -1805,7 +1822,7 @@ void tst_qquickwindow::crashWhenHoverItemDeleted() QVERIFY(!window.isNull()); window->setTitle(QTest::currentTestFunction()); window->show(); - QTest::qWaitForWindowExposed(window.data()); + QTest::qWaitForWindowActive(window.data()); // Simulate a move from the first rectangle to the second. Crash will happen in here // Moving instantaneously from (0, 99) to (0, 102) does not cause the crash @@ -1844,7 +1861,7 @@ void tst_qquickwindow::qobjectEventFilter_touch() window.setPosition(100, 100); window.setTitle(QTest::currentTestFunction()); window.show(); - QVERIFY(QTest::qWaitForWindowExposed(&window)); + QVERIFY(QTest::qWaitForWindowActive(&window)); TestTouchItem *item = new TestTouchItem(window.contentItem()); item->setSize(QSizeF(150, 150)); @@ -1870,7 +1887,7 @@ void tst_qquickwindow::qobjectEventFilter_key() window.setPosition(100, 100); window.setTitle(QTest::currentTestFunction()); window.show(); - QVERIFY(QTest::qWaitForWindowExposed(&window)); + QVERIFY(QTest::qWaitForWindowActive(&window)); TestTouchItem *item = new TestTouchItem(window.contentItem()); item->setSize(QSizeF(150, 150)); @@ -1899,8 +1916,7 @@ void tst_qquickwindow::qobjectEventFilter_mouse() window.setPosition(100, 100); window.setTitle(QTest::currentTestFunction()); window.show(); - - QVERIFY(QTest::qWaitForWindowExposed(&window)); + QVERIFY(QTest::qWaitForWindowActive(&window)); TestTouchItem *item = new TestTouchItem(window.contentItem()); item->setSize(QSizeF(150, 150)); @@ -1909,6 +1925,7 @@ void tst_qquickwindow::qobjectEventFilter_mouse() item->installEventFilter(&eventFilter); QPoint point = item->mapToScene(QPointF(10, 10)).toPoint(); + QTest::mouseMove(&window, point); QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, point); QVERIFY(eventFilter.events.contains((int)QEvent::MouseButtonPress)); @@ -2048,44 +2065,108 @@ public: static int deleted; }; +class GlRenderJob : public QRunnable +{ +public: + GlRenderJob(GLubyte *buf) : readPixel(buf), mutex(0), condition(0) {} + ~GlRenderJob() {} + void run() { + QOpenGLContext::currentContext()->functions()->glClearColor(1.0f, 0, 0, 1.0f); + QOpenGLContext::currentContext()->functions()->glClear(GL_COLOR_BUFFER_BIT); + QOpenGLContext::currentContext()->functions()->glReadPixels(0, 0, 1, 1, GL_RGBA, + GL_UNSIGNED_BYTE, + (void *)readPixel); + if (mutex) { + mutex->lock(); + condition->wakeOne(); + mutex->unlock(); + } + } + GLubyte *readPixel; + QMutex *mutex; + QWaitCondition *condition; +}; + int RenderJob::deleted = 0; void tst_qquickwindow::testRenderJob() { QList<QQuickWindow::RenderStage> completedJobs; - QQuickWindow window; - window.setTitle(QTest::currentTestFunction()); - QQuickWindow::RenderStage stages[] = { QQuickWindow::BeforeSynchronizingStage, QQuickWindow::AfterSynchronizingStage, QQuickWindow::BeforeRenderingStage, QQuickWindow::AfterRenderingStage, - QQuickWindow::AfterSwapStage + QQuickWindow::AfterSwapStage, + QQuickWindow::NoStage }; - // Schedule the jobs - for (int i=0; i<5; ++i) - window.scheduleRenderJob(new RenderJob(stages[i], &completedJobs), stages[i]); - window.show(); - QTRY_COMPARE(completedJobs.size(), 5); + const int numJobs = 6; + + { + QQuickWindow window; + window.setTitle(QTest::currentTestFunction()); + RenderJob::deleted = 0; - for (int i=0; i<5; ++i) { - QCOMPARE(completedJobs.at(i), stages[i]); + // Schedule the jobs + for (int i = 0; i < numJobs; ++i) + window.scheduleRenderJob(new RenderJob(stages[i], &completedJobs), stages[i]); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + // All jobs should be deleted + QTRY_COMPARE(RenderJob::deleted, numJobs); + + // The NoStage job is not completed, if it is issued when there is no context, + // but the rest will be queued and completed once relevant render stage is hit. + QCOMPARE(completedJobs.size(), numJobs - 1); + + // Verify jobs were completed in correct order + for (int i = 0; i < numJobs - 1; ++i) + QCOMPARE(completedJobs.at(i), stages[i]); + + + // Check that NoStage job gets executed if it is scheduled when window is exposed + completedJobs.clear(); + RenderJob::deleted = 0; + window.scheduleRenderJob(new RenderJob(QQuickWindow::NoStage, &completedJobs), + QQuickWindow::NoStage); + QTRY_COMPARE(RenderJob::deleted, 1); + QCOMPARE(completedJobs.size(), 1); + + // Do a synchronized GL job. + GLubyte readPixel[4] = {0, 0, 0, 0}; + GlRenderJob *glJob = new GlRenderJob(readPixel); + if (window.openglContext()->thread() != QThread::currentThread()) { + QMutex mutex; + QWaitCondition condition; + glJob->mutex = &mutex; + glJob->condition = &condition; + mutex.lock(); + window.scheduleRenderJob(glJob, QQuickWindow::NoStage); + condition.wait(&mutex); + mutex.unlock(); + } else { + window.scheduleRenderJob(glJob, QQuickWindow::NoStage); + } + QCOMPARE(int(readPixel[0]), 255); + QCOMPARE(int(readPixel[1]), 0); + QCOMPARE(int(readPixel[2]), 0); + QCOMPARE(int(readPixel[3]), 255); } - // Verify that jobs are deleted when window has not been rendered at all... + // Verify that jobs are deleted when window is not rendered at all completedJobs.clear(); RenderJob::deleted = 0; { QQuickWindow window2; - for (int i=0; i<5; ++i) { + for (int i = 0; i < numJobs; ++i) { window2.scheduleRenderJob(new RenderJob(stages[i], &completedJobs), stages[i]); } } + QTRY_COMPARE(RenderJob::deleted, numJobs); QCOMPARE(completedJobs.size(), 0); - QCOMPARE(RenderJob::deleted, 5); } class EventCounter : public QQuickRectangle @@ -2144,7 +2225,7 @@ void tst_qquickwindow::testHoverChildMouseEventFilter() window.setPosition(100, 100); window.setTitle(QTest::currentTestFunction()); window.show(); - QVERIFY(QTest::qWaitForWindowExposed(&window)); + QVERIFY(QTest::qWaitForWindowActive(&window)); EventCounter *bottomItem = new EventCounter(window.contentItem()); bottomItem->setObjectName("Bottom Item"); diff --git a/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp b/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp index 5372a4d3b3..09ceb7aebd 100644 --- a/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp +++ b/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp @@ -115,15 +115,15 @@ private: QString xml; if (!data.isEmpty()) { - QStringList items = data.split(";"); + QStringList items = data.split(QLatin1Char(';')); foreach(const QString &item, items) { if (item.isEmpty()) continue; QVariantList variants; xml += QLatin1String("<item>"); - QStringList fields = item.split(","); + QStringList fields = item.split(QLatin1Char(',')); foreach(const QString &field, fields) { - QStringList values = field.split("="); + QStringList values = field.split(QLatin1Char('=')); if (values.count() != 2) { qWarning() << "makeItemXmlAndData: invalid field:" << field; continue; @@ -760,9 +760,9 @@ void tst_qquickxmllistmodel::noKeysValueChanges() QTRY_VERIFY(model->data(model->index(0, 0), roles.at(2)).toString() != QLatin1String("Football")); QCOMPARE(model->data(model->index(0, 0), roles.at(2)).toString(), QLatin1String("AussieRules")); - QVERIFY(spyInsert.count() == 0); - QVERIFY(spyRemove.count() == 0); - QVERIFY(spyCount.count() == 0); + QCOMPARE(spyInsert.count(), 0); + QCOMPARE(spyRemove.count(), 0); + QCOMPARE(spyCount.count(), 0); QCOMPARE(model->rowCount(), 2); @@ -857,22 +857,22 @@ void tst_qquickxmllistmodel::threading() QModelIndex index = m1->index(i, 0); QList<int> roles = m1->roleNames().keys(); std::sort(roles.begin(), roles.end()); - QCOMPARE(m1->data(index, roles.at(0)).toString(), QString("A" + QString::number(i))); - QCOMPARE(m1->data(index, roles.at(1)).toString(), QString("1" + QString::number(i))); + QCOMPARE(m1->data(index, roles.at(0)).toString(), QLatin1Char('A') + QString::number(i)); + QCOMPARE(m1->data(index, roles.at(1)).toString(), QLatin1Char('1') + QString::number(i)); QCOMPARE(m1->data(index, roles.at(2)).toString(), QString("Football")); index = m2->index(i, 0); roles = m2->roleNames().keys(); std::sort(roles.begin(), roles.end()); - QCOMPARE(m2->data(index, roles.at(0)).toString(), QString("B" + QString::number(i))); - QCOMPARE(m2->data(index, roles.at(1)).toString(), QString("2" + QString::number(i))); + QCOMPARE(m2->data(index, roles.at(0)).toString(), QLatin1Char('B') + QString::number(i)); + QCOMPARE(m2->data(index, roles.at(1)).toString(), QLatin1Char('2') + QString::number(i)); QCOMPARE(m2->data(index, roles.at(2)).toString(), QString("Athletics")); index = m3->index(i, 0); roles = m3->roleNames().keys(); std::sort(roles.begin(), roles.end()); - QCOMPARE(m3->data(index, roles.at(0)).toString(), QString("C" + QString::number(i))); - QCOMPARE(m3->data(index, roles.at(1)).toString(), QString("3" + QString::number(i))); + QCOMPARE(m3->data(index, roles.at(0)).toString(), QLatin1Char('C') + QString::number(i)); + QCOMPARE(m3->data(index, roles.at(1)).toString(), QLatin1Char('3') + QString::number(i)); QCOMPARE(m3->data(index, roles.at(2)).toString(), QString("Curling")); } } @@ -940,7 +940,7 @@ void tst_qquickxmllistmodel::propertyChanges() QCOMPARE(model->property("query").toString(), QString("/Pets")); QCOMPARE(model->property("namespaceDeclarations").toString(), QString("declare namespace media=\"http://search.yahoo.com/mrss/\";")); - QTRY_VERIFY(model->rowCount() == 1); + QTRY_COMPARE(model->rowCount(), 1); QCOMPARE(sourceSpy.count(),1); QCOMPARE(xmlSpy.count(),1); @@ -957,7 +957,7 @@ void tst_qquickxmllistmodel::propertyChanges() QCOMPARE(modelQuerySpy.count(),1); QCOMPARE(namespaceDeclarationsSpy.count(),1); - QTRY_VERIFY(model->rowCount() == 1); + QTRY_COMPARE(model->rowCount(), 1); delete model; } diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro index c2b7a4cc8d..f25a28d45b 100644 --- a/tests/auto/quick/quick.pro +++ b/tests/auto/quick/quick.pro @@ -18,6 +18,7 @@ PRIVATETESTS += \ qquickapplication \ qquickbehaviors \ qquickfontloader \ + qquickfontloader_static \ qquickfontmetrics \ qquickimageprovider \ qquickpath \ @@ -74,8 +75,8 @@ QUICKTESTS = \ qquickview \ qquickcanvasitem \ qquickscreen \ - touchmouse - + touchmouse \ + scenegraph SUBDIRS += $$PUBLICTESTS diff --git a/tests/auto/quick/scenegraph/data/mipmap_large.png b/tests/auto/quick/scenegraph/data/mipmap_large.png Binary files differindex 9cb0fc7de1..1b6d99c45c 100644 --- a/tests/auto/quick/scenegraph/data/mipmap_large.png +++ b/tests/auto/quick/scenegraph/data/mipmap_large.png diff --git a/tests/auto/quick/scenegraph/data/mipmap_small.png b/tests/auto/quick/scenegraph/data/mipmap_small.png Binary files differindex dc5216fb6c..2e53012ef5 100644 --- a/tests/auto/quick/scenegraph/data/mipmap_small.png +++ b/tests/auto/quick/scenegraph/data/mipmap_small.png diff --git a/tests/auto/quick/scenegraph/data/render_Mipmap.qml b/tests/auto/quick/scenegraph/data/render_Mipmap.qml index 6d9191c5ac..9bd585373a 100644 --- a/tests/auto/quick/scenegraph/data/render_Mipmap.qml +++ b/tests/auto/quick/scenegraph/data/render_Mipmap.qml @@ -32,6 +32,7 @@ ****************************************************************************/ import QtQuick 2.3 +import QtQuick.Window 2.2 /* The test verifies that scaled down mipmapped images contains @@ -39,8 +40,8 @@ import QtQuick 2.3 #samples: 2 PixelPos R G B Error-tolerance - #final: 0 0 0.33 0.33 0.33 0.1 - #final: 1 0 0.33 0.33 0.33 0.1 + #final: 0 0 0.25 0.25 0.25 0.1 + #final: 1 0 0.25 0.25 0.25 0.1 */ RenderTestBase @@ -52,7 +53,7 @@ RenderTestBase source: "mipmap_small.png" mipmap: true smooth: false - scale: 1 / width; + scale: 1 / (width * Screen.devicePixelRatio); } Image { @@ -62,7 +63,7 @@ RenderTestBase source: "mipmap_large.png" mipmap: true smooth: false - scale: 1 / width; + scale: 1 / (width * Screen.devicePixelRatio); } onEnterFinalStage: finalStageComplete = true; diff --git a/tests/auto/quick/scenegraph/tst_scenegraph.cpp b/tests/auto/quick/scenegraph/tst_scenegraph.cpp index d2d3643ca8..80672e234e 100644 --- a/tests/auto/quick/scenegraph/tst_scenegraph.cpp +++ b/tests/auto/quick/scenegraph/tst_scenegraph.cpp @@ -33,11 +33,17 @@ #include <qtest.h> +#include <QOffscreenSurface> +#include <QOpenGLContext> +#include <QOpenGLFunctions> + #include <QtQuick> +#include <QtQml> #include <private/qopenglcontext_p.h> +#include <private/qsgcontext_p.h> +#include <private/qsgrenderloop_p.h> -#include <QtQml> class PerPixelRect : public QQuickItem { @@ -97,6 +103,12 @@ private slots: void render(); void hideWithOtherContext(); + + void createTextureFromImage_data(); + void createTextureFromImage(); + +private: + bool m_brokenMipmapSupport; }; template <typename T> class ScopedList : public QList<T> { @@ -107,6 +119,42 @@ public: void tst_SceneGraph::initTestCase() { qmlRegisterType<PerPixelRect>("SceneGraphTest", 1, 0, "PerPixelRect"); + + QSGRenderLoop *loop = QSGRenderLoop::instance(); + qDebug() << "RenderLoop: " << loop; + + QOpenGLContext context; + context.setFormat(loop->sceneGraphContext()->defaultSurfaceFormat()); + context.create(); + QSurfaceFormat format = context.format(); + + QOffscreenSurface surface; + surface.setFormat(format); + surface.create(); + if (!context.makeCurrent(&surface)) + qFatal("Failed to create a GL context..."); + + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + qDebug() << "R/G/B/A Buffers: " << format.redBufferSize() << format.greenBufferSize() << format.blueBufferSize() << format.alphaBufferSize(); + qDebug() << "Depth Buffer: " << format.depthBufferSize(); + qDebug() << "Stencil Buffer: " << format.stencilBufferSize(); + qDebug() << "Samples: " << format.samples(); + int textureSize; + funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &textureSize); + qDebug() << "Max Texture Size: " << textureSize; + qDebug() << "GL_VENDOR: " << (const char *) funcs->glGetString(GL_VENDOR); + qDebug() << "GL_RENDERER: " << (const char *) funcs->glGetString(GL_RENDERER); + QByteArray version = (const char *) funcs->glGetString(GL_VERSION); + qDebug() << "GL_VERSION: " << version.constData(); + QSet<QByteArray> exts = context.extensions(); + QByteArray all; + foreach (const QByteArray &e, exts) all += ' ' + e; + qDebug() << "GL_EXTENSIONS: " << all.constData(); + + m_brokenMipmapSupport = version.contains("Mesa 10.1") || version.contains("Mesa 9."); + qDebug() << "Broken Mipmap: " << m_brokenMipmapSupport; + + context.doneCurrent(); } QQuickView *createView(const QString &file, QWindow *parent = 0, int x = -1, int y = -1, int w = -1, int h = -1) @@ -210,7 +258,7 @@ void tst_SceneGraph::manyWindows_data() struct ShareContextResetter { public: - ~ShareContextResetter() { QOpenGLContextPrivate::setGlobalShareContext(0); } + ~ShareContextResetter() { qt_gl_set_global_share_context(0); } }; void tst_SceneGraph::manyWindows() @@ -223,7 +271,7 @@ void tst_SceneGraph::manyWindows() ShareContextResetter cleanup; // To avoid dangling pointer in case of test-failure. if (shared) { QVERIFY(sharedGLContext.create()); - QOpenGLContextPrivate::setGlobalShareContext(&sharedGLContext); + qt_gl_set_global_share_context(&sharedGLContext); } QScopedPointer<QWindow> parent; @@ -297,8 +345,8 @@ struct Sample { .arg(color.redF()).arg(color.greenF()).arg(color.blueF()); } - bool check(const QImage &image) { - QColor color(image.pixel(x, y)); + bool check(const QImage &image, qreal scale) { + QColor color(image.pixel(x * scale, y * scale)); return qAbs(color.redF() - r) <= tolerance && qAbs(color.greenF() - g) <= tolerance && qAbs(color.blueF() - b) <= tolerance; @@ -368,11 +416,11 @@ void tst_SceneGraph::render_data() << "data/render_BreakOpacityBatch.qml" << "data/render_OutOfFloatRange.qml" << "data/render_StackingOrder.qml" - << "data/render_Mipmap.qml" << "data/render_ImageFiltering.qml" << "data/render_bug37422.qml" - << "data/render_OpacityThroughBatchRoot.qml" - ; + << "data/render_OpacityThroughBatchRoot.qml"; + if (!m_brokenMipmapSupport) + files << "data/render_Mipmap.qml"; QRegExp sampleCount("#samples: *(\\d+)"); // X:int Y:int R:float G:float B:float Error:float @@ -428,11 +476,18 @@ void tst_SceneGraph::render() view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); + // We're checking actual pixels, so scale up the sample point to the top-left of the + // 2x2 pixel block and hope that this is good enough. Ideally, view and content + // would be in identical coordinate space, meaning pixels, but we're not in an + // ideal world. + // Just keep this in mind when writing tests. + qreal scale = view.devicePixelRatio(); + // Grab the window and check all our base stage samples QImage content = view.grabWindow(); for (int i=0; i<baseStage.size(); ++i) { Sample sample = baseStage.at(i); - QVERIFY2(sample.check(content), qPrintable(sample.toString(content))); + QVERIFY2(sample.check(content, scale), qPrintable(sample.toString(content))); } // Put the qml file into the final stage and wait for it to @@ -445,7 +500,7 @@ void tst_SceneGraph::render() content = view.grabWindow(); for (int i=0; i<finalStage.size(); ++i) { Sample sample = finalStage.at(i); - QVERIFY2(sample.check(content), qPrintable(sample.toString(content))); + QVERIFY2(sample.check(content, scale), qPrintable(sample.toString(content))); } } @@ -482,6 +537,34 @@ void tst_SceneGraph::hideWithOtherContext() QVERIFY(!renderingOnMainThread || QOpenGLContext::currentContext() != &context); } +void tst_SceneGraph::createTextureFromImage_data() +{ + QImage rgba(64, 64, QImage::Format_ARGB32_Premultiplied); + QImage rgb(64, 64, QImage::Format_RGB32); + + QTest::addColumn<QImage>("image"); + QTest::addColumn<uint>("flags"); + QTest::addColumn<bool>("expectedAlpha"); + + QTest::newRow("rgb") << rgb << uint(0) << false; + QTest::newRow("argb") << rgba << uint(0) << true; + QTest::newRow("rgb,alpha") << rgb << uint(QQuickWindow::TextureHasAlphaChannel) << false; + QTest::newRow("argb,alpha") << rgba << uint(QQuickWindow::TextureHasAlphaChannel) << true; + QTest::newRow("rgb,!alpha") << rgb << uint(QQuickWindow::TextureIsOpaque) << false; + QTest::newRow("argb,!alpha") << rgba << uint(QQuickWindow::TextureIsOpaque) << false; +} + +void tst_SceneGraph::createTextureFromImage() +{ + QFETCH(QImage, image); + QFETCH(uint, flags); + QFETCH(bool, expectedAlpha); + + QQuickView view; + QScopedPointer<QSGTexture> texture(view.createTextureFromImage(image, (QQuickWindow::CreateTextureOptions) flags)); + QCOMPARE(texture->hasAlphaChannel(), expectedAlpha); +} + #include "tst_scenegraph.moc" diff --git a/tests/auto/quick/shared/viewtestutil.cpp b/tests/auto/quick/shared/viewtestutil.cpp index 5b9111d448..1330cbccc9 100644 --- a/tests/auto/quick/shared/viewtestutil.cpp +++ b/tests/auto/quick/shared/viewtestutil.cpp @@ -72,18 +72,30 @@ void QQuickViewTestUtil::moveMouseAway(QQuickView *window) #endif } +void QQuickViewTestUtil::moveAndRelease(QQuickView *window, const QPoint &position) +{ + QTest::mouseMove(window, position); + QTest::mouseRelease(window, Qt::LeftButton, 0, position); +} + +void QQuickViewTestUtil::moveAndPress(QQuickView *window, const QPoint &position) +{ + QTest::mouseMove(window, position); + QTest::mousePress(window, Qt::LeftButton, 0, position); +} + void QQuickViewTestUtil::flick(QQuickView *window, const QPoint &from, const QPoint &to, int duration) { const int pointCount = 5; QPoint diff = to - from; // send press, five equally spaced moves, and release. - QTest::mousePress(window, Qt::LeftButton, 0, from); + moveAndPress(window, from); for (int i = 0; i < pointCount; ++i) QTest::mouseMove(window, from + (i+1)*diff/pointCount, duration / pointCount); - QTest::mouseRelease(window, Qt::LeftButton, 0, to); + moveAndRelease(window, to); QTest::qWait(50); } @@ -265,11 +277,11 @@ void QQuickViewTestUtil::QaimModel::resetItems(const QList<QPair<QString, QStrin void QQuickViewTestUtil::QaimModel::matchAgainst(const QList<QPair<QString, QString> > &other, const QString &error1, const QString &error2) { for (int i=0; i<other.count(); i++) { QVERIFY2(list.contains(other[i]), - QTest::toString(other[i].first + " " + other[i].second + " " + error1)); + QTest::toString(other[i].first + QLatin1Char(' ') + other[i].second + QLatin1Char(' ') + error1)); } for (int i=0; i<list.count(); i++) { QVERIFY2(other.contains(list[i]), - QTest::toString(list[i].first + " " + list[i].second + " " + error2)); + QTest::toString(list[i].first + QLatin1Char(' ') + list[i].second + QLatin1Char(' ') + error2)); } } diff --git a/tests/auto/quick/shared/viewtestutil.h b/tests/auto/quick/shared/viewtestutil.h index 8c5f5c54e6..1643eca979 100644 --- a/tests/auto/quick/shared/viewtestutil.h +++ b/tests/auto/quick/shared/viewtestutil.h @@ -48,6 +48,8 @@ namespace QQuickViewTestUtil void centerOnScreen(QQuickView *window, const QSize &size); void centerOnScreen(QQuickView *window); void moveMouseAway(QQuickView *window); + void moveAndPress(QQuickView *window, const QPoint &position); + void moveAndRelease(QQuickView *window, const QPoint &position); QList<int> adjustIndexesForAddDisplaced(const QList<int> &indexes, int index, int count); QList<int> adjustIndexesForMove(const QList<int> &indexes, int from, int to, int count); diff --git a/tests/auto/quick/touchmouse/data/hoverMouseAreas.qml b/tests/auto/quick/touchmouse/data/hoverMouseAreas.qml new file mode 100644 index 0000000000..1bdd0b3caf --- /dev/null +++ b/tests/auto/quick/touchmouse/data/hoverMouseAreas.qml @@ -0,0 +1,39 @@ +import QtQuick 2.4 + +Item { + width: 500 + height: 500 + + Rectangle { + width: 300 + height: 90 + color: mouseArea1.containsMouse ? "red" : "grey" + x: 100 + y: 100 + + MouseArea { + id: mouseArea1 + objectName: "mouseArea1" + anchors.fill: parent + hoverEnabled: true + onPressed: parent.border.width = 4 + onReleased: parent.border.width = 0 + } + } + Rectangle { + width: 300 + height: 100 + color: mouseArea2.containsMouse ? "red" : "lightblue" + x: 100 + y: 200 + + MouseArea { + id: mouseArea2 + objectName: "mouseArea2" + anchors.fill: parent + hoverEnabled: true + onPressed: parent.border.width = 4 + onReleased: parent.border.width = 0 + } + } +} diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp index 539bbb4703..e14b7d7c84 100644 --- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp +++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp @@ -161,6 +161,8 @@ private slots: void touchGrabCausesMouseUngrab(); + void hoverEnabled(); + protected: bool eventFilter(QObject *, QEvent *event) { @@ -863,7 +865,7 @@ void tst_TouchMouse::pinchOnFlickable() QVERIFY(rect); // flickable - single touch point - QVERIFY(flickable->contentX() == 0.0); + QCOMPARE(flickable->contentX(), 0.0); QPoint p = QPoint(100, 100); QTest::touchEvent(window, device).press(0, p, window); QQuickTouchUtils::flush(window); @@ -945,7 +947,7 @@ void tst_TouchMouse::flickableOnPinch() QVERIFY(rect); // flickable - single touch point - QVERIFY(flickable->contentX() == 0.0); + QCOMPARE(flickable->contentX(), 0.0); QPoint p = QPoint(100, 100); QTest::touchEvent(window, device).press(0, p, window); QQuickTouchUtils::flush(window); @@ -1025,7 +1027,7 @@ void tst_TouchMouse::mouseOnFlickableOnPinch() QVERIFY(rect); // flickable - single touch point - QVERIFY(flickable->contentX() == 0.0); + QCOMPARE(flickable->contentX(), 0.0); QPoint p = QPoint(100, 100); QTest::touchEvent(window, device).press(0, p, window); QQuickTouchUtils::flush(window); @@ -1232,6 +1234,93 @@ void tst_TouchMouse::touchGrabCausesMouseUngrab() delete window; } +void tst_TouchMouse::hoverEnabled() +{ + // QTouchDevice *device = new QTouchDevice; + // device->setType(QTouchDevice::TouchScreen); + // QWindowSystemInterface::registerTouchDevice(device); + + QQuickView *window = createView(); + window->setSource(testFileUrl("hoverMouseAreas.qml")); + + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + QQuickItem *root = window->rootObject(); + QVERIFY(root != 0); + + QQuickMouseArea *mouseArea1 = root->findChild<QQuickMouseArea*>("mouseArea1"); + QVERIFY(mouseArea1 != 0); + + QQuickMouseArea *mouseArea2 = root->findChild<QQuickMouseArea*>("mouseArea2"); + QVERIFY(mouseArea2 != 0); + + QSignalSpy enterSpy1(mouseArea1, SIGNAL(entered())); + QSignalSpy exitSpy1(mouseArea1, SIGNAL(exited())); + QSignalSpy clickSpy1(mouseArea1, SIGNAL(clicked(QQuickMouseEvent *))); + + QSignalSpy enterSpy2(mouseArea2, SIGNAL(entered())); + QSignalSpy exitSpy2(mouseArea2, SIGNAL(exited())); + QSignalSpy clickSpy2(mouseArea2, SIGNAL(clicked(QQuickMouseEvent *))); + + QPoint p0(50, 50); + QPoint p1(150, 150); + QPoint p2(150, 250); + + // ------------------------- Mouse move to mouseArea1 + QTest::mouseMove(window, p1); + + QVERIFY(enterSpy1.count() == 1); + QVERIFY(mouseArea1->hovered()); + QVERIFY(!mouseArea2->hovered()); + + // ------------------------- Touch click on mouseArea1 + QTest::touchEvent(window, device).press(0, p1, window); + + QVERIFY(enterSpy1.count() == 1); + QVERIFY(enterSpy2.count() == 0); + QVERIFY(mouseArea1->pressed()); + QVERIFY(mouseArea1->hovered()); + QVERIFY(!mouseArea2->hovered()); + + QTest::touchEvent(window, device).release(0, p1, window); + QVERIFY(clickSpy1.count() == 1); + QVERIFY(mouseArea1->hovered()); + QVERIFY(!mouseArea2->hovered()); + + // ------------------------- Touch click on mouseArea2 + QTest::touchEvent(window, device).press(0, p2, window); + + QVERIFY(mouseArea1->hovered()); + QVERIFY(mouseArea2->hovered()); + QVERIFY(mouseArea2->pressed()); + QVERIFY(enterSpy1.count() == 1); + QVERIFY(enterSpy2.count() == 1); + + QTest::touchEvent(window, device).release(0, p2, window); + + QVERIFY(clickSpy2.count() == 1); + QVERIFY(mouseArea1->hovered()); + QVERIFY(!mouseArea2->hovered()); + QVERIFY(exitSpy1.count() == 0); + QVERIFY(exitSpy2.count() == 1); + + // ------------------------- Another touch click on mouseArea1 + QTest::touchEvent(window, device).press(0, p1, window); + + QVERIFY(enterSpy1.count() == 1); + QVERIFY(enterSpy2.count() == 1); + QVERIFY(mouseArea1->pressed()); + QVERIFY(mouseArea1->hovered()); + QVERIFY(!mouseArea2->hovered()); + + QTest::touchEvent(window, device).release(0, p1, window); + QVERIFY(clickSpy1.count() == 2); + QVERIFY(mouseArea1->hovered()); + QVERIFY(!mouseArea1->pressed()); + QVERIFY(!mouseArea2->hovered()); +} + QTEST_MAIN(tst_TouchMouse) #include "tst_touchmouse.moc" diff --git a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp index 3da920ca27..bec3de524c 100644 --- a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp +++ b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp @@ -59,6 +59,7 @@ private slots: void engine(); void readback(); void renderingSignals(); + void grabBeforeShow(); }; @@ -75,8 +76,12 @@ void tst_qquickwidget::showHide() window.show(); QVERIFY(QTest::qWaitForWindowExposed(&window, 5000)); + QVERIFY(childView->quickWindow()->isVisible()); + QVERIFY(childView->quickWindow()->visibility() != QWindow::Hidden); - childView->hide(); + window.hide(); + QVERIFY(!childView->quickWindow()->isVisible()); + QCOMPARE(childView->quickWindow()->visibility(), QWindow::Hidden); } void tst_qquickwidget::reparentAfterShow() @@ -223,11 +228,12 @@ void tst_qquickwidget::errors() { QQuickWidget *view = new QQuickWidget; QScopedPointer<QQuickWidget> cleanupView(view); + QVERIFY(view->errors().isEmpty()); // don't crash QQmlTestMessageHandler messageHandler; view->setSource(testFileUrl("error1.qml")); - QVERIFY(view->status() == QQuickWidget::Error); - QVERIFY(view->errors().count() == 1); + QCOMPARE(view->status(), QQuickWidget::Error); + QCOMPARE(view->errors().count(), 1); } void tst_qquickwidget::engine() @@ -292,6 +298,14 @@ void tst_qquickwidget::renderingSignals() QTRY_VERIFY(afterRenderingSpy.size() > 0); } +// QTBUG-49929, verify that Qt Designer grabbing the contents before drag +// does not crash due to missing GL contexts or similar. +void tst_qquickwidget::grabBeforeShow() +{ + QQuickWidget widget; + QVERIFY(!widget.grab().isNull()); +} + QTEST_MAIN(tst_qquickwidget) #include "tst_qquickwidget.moc" diff --git a/tests/auto/shared/testhttpserver.cpp b/tests/auto/shared/testhttpserver.cpp index 7235246fc0..80ce10cacd 100644 --- a/tests/auto/shared/testhttpserver.cpp +++ b/tests/auto/shared/testhttpserver.cpp @@ -36,6 +36,7 @@ #include <QDebug> #include <QFile> #include <QTimer> +#include <QTest> /*! \internal @@ -80,25 +81,35 @@ The following request urls will then result in the appropriate action: \row \li http://localhost:14445/slowMain.qml \li slowMain.qml returned after 500ms \endtable */ -TestHTTPServer::TestHTTPServer() -: m_state(AwaitingHeader) + +static QUrl localHostUrl(quint16 port) { - QObject::connect(&server, SIGNAL(newConnection()), this, SLOT(newConnection())); + QUrl url; + url.setScheme(QStringLiteral("http")); + url.setHost(QStringLiteral("127.0.0.1")); + url.setPort(port); + return url; +} +TestHTTPServer::TestHTTPServer() + : m_state(AwaitingHeader) +{ + QObject::connect(&m_server, &QTcpServer::newConnection, this, &TestHTTPServer::newConnection); } bool TestHTTPServer::listen() { - return server.listen(QHostAddress::LocalHost, 0); + return m_server.listen(QHostAddress::LocalHost, 0); } QUrl TestHTTPServer::baseUrl() const { - QUrl url; - url.setScheme(QStringLiteral("http")); - url.setHost(QStringLiteral("127.0.0.1")); - url.setPort(server.serverPort()); - return url; + return localHostUrl(m_server.serverPort()); +} + +quint16 TestHTTPServer::port() const +{ + return m_server.serverPort(); } QUrl TestHTTPServer::url(const QString &documentPath) const @@ -113,12 +124,12 @@ QString TestHTTPServer::urlString(const QString &documentPath) const QString TestHTTPServer::errorString() const { - return server.errorString(); + return m_server.errorString(); } bool TestHTTPServer::serveDirectory(const QString &dir, Mode mode) { - dirs.append(qMakePair(dir, mode)); + m_directories.append(qMakePair(dir, mode)); return true; } @@ -128,17 +139,17 @@ bool TestHTTPServer::serveDirectory(const QString &dir, Mode mode) */ void TestHTTPServer::addAlias(const QString &filename, const QString &alias) { - aliases.insert(filename, alias); + m_aliases.insert(filename, alias); } void TestHTTPServer::addRedirect(const QString &filename, const QString &redirectName) { - redirects.insert(filename, redirectName); + m_redirects.insert(filename, redirectName); } void TestHTTPServer::registerFileNameForContentSubstitution(const QString &fileName) { - contentSubstitutedFileNames.insert(fileName); + m_contentSubstitutedFileNames.insert(fileName); } bool TestHTTPServer::wait(const QUrl &expect, const QUrl &reply, const QUrl &body) @@ -147,19 +158,23 @@ bool TestHTTPServer::wait(const QUrl &expect, const QUrl &reply, const QUrl &bod m_data.clear(); QFile expectFile(expect.toLocalFile()); - if (!expectFile.open(QIODevice::ReadOnly)) return false; + if (!expectFile.open(QIODevice::ReadOnly)) + return false; QFile replyFile(reply.toLocalFile()); - if (!replyFile.open(QIODevice::ReadOnly)) return false; + if (!replyFile.open(QIODevice::ReadOnly)) + return false; - bodyData = QByteArray(); + m_bodyData = QByteArray(); if (body.isValid()) { QFile bodyFile(body.toLocalFile()); - if (!bodyFile.open(QIODevice::ReadOnly)) return false; - bodyData = bodyFile.readAll(); + if (!bodyFile.open(QIODevice::ReadOnly)) + return false; + m_bodyData = bodyFile.readAll(); } - const QByteArray serverHostUrl = QByteArrayLiteral("127.0.0.1:") + QByteArray::number(server.serverPort()); + const QByteArray serverHostUrl + = QByteArrayLiteral("127.0.0.1:")+ QByteArray::number(m_server.serverPort()); QByteArray line; bool headers_done = false; @@ -170,10 +185,10 @@ bool TestHTTPServer::wait(const QUrl &expect, const QUrl &reply, const QUrl &bod continue; } if (headers_done) { - waitData.body.append(line); + m_waitData.body.append(line); } else { line.replace("{{ServerHostUrl}}", serverHostUrl); - waitData.headers.append(line); + m_waitData.headers.append(line); } } /* @@ -181,20 +196,21 @@ bool TestHTTPServer::wait(const QUrl &expect, const QUrl &reply, const QUrl &bod waitData = waitData.left(waitData.count() - 1); */ - replyData = replyFile.readAll(); + m_replyData = replyFile.readAll(); - if (!replyData.endsWith('\n')) - replyData.append("\n"); - replyData.append("Content-length: " + QByteArray::number(bodyData.length())); - replyData .append("\n\n"); + if (!m_replyData.endsWith('\n')) + m_replyData.append('\n'); + m_replyData.append("Content-length: "); + m_replyData.append(QByteArray::number(m_bodyData.length())); + m_replyData.append("\n\n"); - for (int ii = 0; ii < replyData.count(); ++ii) { - if (replyData.at(ii) == '\n' && (!ii || replyData.at(ii - 1) != '\r')) { - replyData.insert(ii, '\r'); + for (int ii = 0; ii < m_replyData.count(); ++ii) { + if (m_replyData.at(ii) == '\n' && (!ii || m_replyData.at(ii - 1) != '\r')) { + m_replyData.insert(ii, '\r'); ++ii; } } - replyData.append(bodyData); + m_replyData.append(m_bodyData); return true; } @@ -206,25 +222,27 @@ bool TestHTTPServer::hasFailed() const void TestHTTPServer::newConnection() { - QTcpSocket *socket = server.nextPendingConnection(); - if (!socket) return; + QTcpSocket *socket = m_server.nextPendingConnection(); + if (!socket) + return; - if (!dirs.isEmpty()) - dataCache.insert(socket, QByteArray()); + if (!m_directories.isEmpty()) + m_dataCache.insert(socket, QByteArray()); - QObject::connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected())); - QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead())); + QObject::connect(socket, &QAbstractSocket::disconnected, this, &TestHTTPServer::disconnected); + QObject::connect(socket, &QIODevice::readyRead, this, &TestHTTPServer::readyRead); } void TestHTTPServer::disconnected() { QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender()); - if (!socket) return; + if (!socket) + return; - dataCache.remove(socket); - for (int ii = 0; ii < toSend.count(); ++ii) { - if (toSend.at(ii).first == socket) { - toSend.removeAt(ii); + m_dataCache.remove(socket); + for (int ii = 0; ii < m_toSend.count(); ++ii) { + if (m_toSend.at(ii).first == socket) { + m_toSend.removeAt(ii); --ii; } } @@ -235,14 +253,15 @@ void TestHTTPServer::disconnected() void TestHTTPServer::readyRead() { QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender()); - if (!socket || socket->state() == QTcpSocket::ClosingState) return; + if (!socket || socket->state() == QTcpSocket::ClosingState) + return; - if (!dirs.isEmpty()) { + if (!m_directories.isEmpty()) { serveGET(socket, socket->readAll()); return; } - if (m_state == Failed || (waitData.body.isEmpty() && waitData.headers.count() == 0)) { + if (m_state == Failed || (m_waitData.body.isEmpty() && m_waitData.headers.count() == 0)) { qWarning() << "TestHTTPServer: Unexpected data" << socket->readAll(); return; } @@ -256,8 +275,9 @@ void TestHTTPServer::readyRead() m_data += socket->readAll(); break; } else { - if (!waitData.headers.contains(line)) { - qWarning() << "TestHTTPServer: Unexpected header:" << line << "\nExpected headers: " << waitData.headers; + if (!m_waitData.headers.contains(line)) { + qWarning() << "TestHTTPServer: Unexpected header:" << line + << "\nExpected headers: " << m_waitData.headers; m_state = Failed; socket->disconnectFromHost(); return; @@ -268,34 +288,38 @@ void TestHTTPServer::readyRead() m_data += socket->readAll(); } - if (!m_data.isEmpty() || waitData.body.isEmpty()) { - if (waitData.body != m_data) { - qWarning() << "TestHTTPServer: Unexpected data" << m_data << "\nExpected: " << waitData.body; + if (!m_data.isEmpty() || m_waitData.body.isEmpty()) { + if (m_waitData.body != m_data) { + qWarning() << "TestHTTPServer: Unexpected data" << m_data << "\nExpected: " << m_waitData.body; m_state = Failed; } else { - socket->write(replyData); + socket->write(m_replyData); } socket->disconnectFromHost(); } } -bool TestHTTPServer::reply(QTcpSocket *socket, const QByteArray &fileName) +bool TestHTTPServer::reply(QTcpSocket *socket, const QByteArray &fileNameIn) { - if (redirects.contains(fileName)) { - QByteArray response = "HTTP/1.1 302 Found\r\nContent-length: 0\r\nContent-type: text/html; charset=UTF-8\r\nLocation: " + redirects[fileName].toUtf8() + "\r\n\r\n"; + const QString fileName = QLatin1String(fileNameIn); + if (m_redirects.contains(fileName)) { + const QByteArray response + = "HTTP/1.1 302 Found\r\nContent-length: 0\r\nContent-type: text/html; charset=UTF-8\r\nLocation: " + + m_redirects.value(fileName).toUtf8() + "\r\n\r\n"; socket->write(response); return true; } - for (int ii = 0; ii < dirs.count(); ++ii) { - QString dir = dirs.at(ii).first; - Mode mode = dirs.at(ii).second; + for (int ii = 0; ii < m_directories.count(); ++ii) { + const QString &dir = m_directories.at(ii).first; + const Mode mode = m_directories.at(ii).second; - QString dirFile = dir + QLatin1String("/") + QLatin1String(fileName); + QString dirFile = dir + QLatin1Char('/') + fileName; if (!QFile::exists(dirFile)) { - if (aliases.contains(fileName)) - dirFile = dir + QLatin1String("/") + aliases.value(fileName); + const QHash<QString, QString>::const_iterator it = m_aliases.constFind(fileName); + if (it != m_aliases.constEnd()) + dirFile = dir + QLatin1Char('/') + it.value(); } QFile file(dirFile); @@ -305,18 +329,18 @@ bool TestHTTPServer::reply(QTcpSocket *socket, const QByteArray &fileName) return true; QByteArray data = file.readAll(); - if (contentSubstitutedFileNames.contains("/" + fileName)) { + if (m_contentSubstitutedFileNames.contains(QLatin1Char('/') + fileName)) data.replace(QByteArrayLiteral("{{ServerBaseUrl}}"), baseUrl().toString().toUtf8()); - } - QByteArray response = "HTTP/1.0 200 OK\r\nContent-type: text/html; charset=UTF-8\r\nContent-length: "; + QByteArray response + = "HTTP/1.0 200 OK\r\nContent-type: text/html; charset=UTF-8\r\nContent-length: "; response += QByteArray::number(data.count()); response += "\r\n\r\n"; response += data; if (mode == Delay) { - toSend.append(qMakePair(socket, response)); - QTimer::singleShot(500, this, SLOT(sendOne())); + m_toSend.append(qMakePair(socket, response)); + QTimer::singleShot(500, this, &TestHTTPServer::sendOne); return false; } else { socket->write(response); @@ -325,9 +349,7 @@ bool TestHTTPServer::reply(QTcpSocket *socket, const QByteArray &fileName) } } - - QByteArray response = "HTTP/1.0 404 Not found\r\nContent-type: text/html; charset=UTF-8\r\n\r\n"; - socket->write(response); + socket->write("HTTP/1.0 404 Not found\r\nContent-type: text/html; charset=UTF-8\r\n\r\n"); return true; } @@ -339,39 +361,88 @@ void TestHTTPServer::sendDelayedItem() void TestHTTPServer::sendOne() { - if (!toSend.isEmpty()) { - toSend.first().first->write(toSend.first().second); - toSend.first().first->close(); - toSend.removeFirst(); + if (!m_toSend.isEmpty()) { + m_toSend.first().first->write(m_toSend.first().second); + m_toSend.first().first->close(); + m_toSend.removeFirst(); } } void TestHTTPServer::serveGET(QTcpSocket *socket, const QByteArray &data) { - if (!dataCache.contains(socket)) + const QHash<QTcpSocket *, QByteArray>::iterator it = m_dataCache.find(socket); + if (it == m_dataCache.end()) return; - QByteArray total = dataCache[socket] + data; - dataCache[socket] = total; + QByteArray &total = it.value(); + total.append(data); if (total.contains("\n\r\n")) { - bool close = true; - if (total.startsWith("GET /")) { + const int space = total.indexOf(' ', 4); + if (space != -1) + close = reply(socket, total.mid(5, space - 5)); + } + m_dataCache.erase(it); + if (close) + socket->disconnectFromHost(); + } +} - int space = total.indexOf(' ', 4); - if (space != -1) { +ThreadedTestHTTPServer::ThreadedTestHTTPServer(const QString &dir, TestHTTPServer::Mode mode) : + m_port(0) +{ + m_dirs[dir] = mode; + start(); +} - QByteArray req = total.mid(5, space - 5); - close = reply(socket, req); +ThreadedTestHTTPServer::ThreadedTestHTTPServer(const QHash<QString, TestHTTPServer::Mode> &dirs) : + m_dirs(dirs), m_port(0) +{ + start(); +} - } - } - dataCache.remove(socket); +ThreadedTestHTTPServer::~ThreadedTestHTTPServer() +{ + quit(); + wait(); +} - if (close) - socket->disconnectFromHost(); +QUrl ThreadedTestHTTPServer::baseUrl() const +{ + return localHostUrl(m_port); +} + +QUrl ThreadedTestHTTPServer::url(const QString &documentPath) const +{ + return baseUrl().resolved(documentPath); +} + +QString ThreadedTestHTTPServer::urlString(const QString &documentPath) const +{ + return url(documentPath).toString(); +} + +void ThreadedTestHTTPServer::run() +{ + TestHTTPServer server; + { + QMutexLocker locker(&m_mutex); + QVERIFY2(server.listen(), qPrintable(server.errorString())); + m_port = server.port(); + for (QHash<QString, TestHTTPServer::Mode>::ConstIterator i = m_dirs.constBegin(); + i != m_dirs.constEnd(); ++i) { + server.serveDirectory(i.key(), i.value()); + } + m_condition.wakeAll(); } + exec(); } +void ThreadedTestHTTPServer::start() +{ + QMutexLocker locker(&m_mutex); + QThread::start(); + m_condition.wait(&m_mutex); +} diff --git a/tests/auto/shared/testhttpserver.h b/tests/auto/shared/testhttpserver.h index 0c0e799d8e..bf826b247b 100644 --- a/tests/auto/shared/testhttpserver.h +++ b/tests/auto/shared/testhttpserver.h @@ -34,10 +34,12 @@ #ifndef TESTHTTPSERVER_H #define TESTHTTPSERVER_H -#include <QObject> #include <QTcpServer> #include <QUrl> #include <QPair> +#include <QThread> +#include <QMutex> +#include <QWaitCondition> class TestHTTPServer : public QObject { @@ -46,6 +48,7 @@ public: TestHTTPServer(); bool listen(); + quint16 port() const; QUrl baseUrl() const; QUrl url(const QString &documentPath) const; QString urlString(const QString &documentPath) const; @@ -81,24 +84,48 @@ private: void serveGET(QTcpSocket *, const QByteArray &); bool reply(QTcpSocket *, const QByteArray &); - QList<QPair<QString, Mode> > dirs; - QHash<QTcpSocket *, QByteArray> dataCache; - QList<QPair<QTcpSocket *, QByteArray> > toSend; - QSet<QString> contentSubstitutedFileNames; + QList<QPair<QString, Mode> > m_directories; + QHash<QTcpSocket *, QByteArray> m_dataCache; + QList<QPair<QTcpSocket *, QByteArray> > m_toSend; + QSet<QString> m_contentSubstitutedFileNames; struct WaitData { QList <QByteArray>headers; QByteArray body; - } waitData; - QByteArray replyData; - QByteArray bodyData; + } m_waitData; + QByteArray m_replyData; + QByteArray m_bodyData; QByteArray m_data; State m_state; - QHash<QString,QString> aliases; - QHash<QString,QString> redirects; + QHash<QString, QString> m_aliases; + QHash<QString, QString> m_redirects; - QTcpServer server; + QTcpServer m_server; +}; + +class ThreadedTestHTTPServer : public QThread +{ + Q_OBJECT +public: + ThreadedTestHTTPServer(const QString &dir, TestHTTPServer::Mode mode = TestHTTPServer::Normal); + ThreadedTestHTTPServer(const QHash<QString, TestHTTPServer::Mode> &dirs); + ~ThreadedTestHTTPServer(); + + QUrl baseUrl() const; + QUrl url(const QString &documentPath) const; + QString urlString(const QString &documentPath) const; + +protected: + void run(); + +private: + void start(); + + QHash<QString, TestHTTPServer::Mode> m_dirs; + quint16 m_port; + QMutex m_mutex; + QWaitCondition m_condition; }; #endif // TESTHTTPSERVER_H |