summaryrefslogtreecommitdiff
path: root/tests/auto
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/declarative/debugger/debugger.pro1
-rw-r--r--tests/auto/declarative/debugger/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp2
-rw-r--r--tests/auto/declarative/debugger/qdeclarativedebugjs/qdeclarativedebugjs.pro2
-rw-r--r--tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp10
-rw-r--r--tests/auto/declarative/debugger/qdeclarativedebugtrace/data/test.qml5
-rw-r--r--tests/auto/declarative/debugger/qdeclarativedebugtrace/qdeclarativedebugtrace.pro14
-rw-r--r--tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp252
-rw-r--r--tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.cpp3
-rw-r--r--tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.pro2
-rw-r--r--tests/auto/declarative/debugger/shared/debugutil.cpp21
-rw-r--r--tests/auto/declarative/debugger/shared/debugutil_p.h1
-rw-r--r--tests/auto/declarative/declarative.pro3
-rw-r--r--tests/auto/declarative/examples/examples.pro4
-rw-r--r--tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp8
-rw-r--r--tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp18
-rw-r--r--tests/auto/declarative/qdeclarativebehaviors/data/startOnCompleted.qml15
-rw-r--r--tests/auto/declarative/qdeclarativebehaviors/data/valueType.qml13
-rw-r--r--tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp34
-rw-r--r--tests/auto/declarative/qdeclarativecontext/data/RefreshExpressionsType.qml5
-rw-r--r--tests/auto/declarative/qdeclarativecontext/data/refreshExpressions.qml6
-rw-r--r--tests/auto/declarative/qdeclarativecontext/data/refreshExpressionsRootContext.qml6
-rw-r--r--tests/auto/declarative/qdeclarativecontext/qdeclarativecontext.pro6
-rw-r--r--tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp154
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/SequenceConversionComponent.qml7
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/deleteWhileBindingRunning.qml5
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/forInLoop.qml13
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/nonNotifyable.qml6
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/qtbug_20344.qml6
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/readonlyDeclaration.qml45
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.array.qml152
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.bindings.error.qml19
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.bindings.qml28
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.copy.qml160
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.read.error.qml21
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.read.qml105
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.threads.qml74
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.write.error.qml18
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.write.qml109
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/threadScript.js4
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/typeOf.js25
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/typeOf.qml26
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp9
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/testtypes.h109
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp356
-rw-r--r--tests/auto/declarative/qdeclarativeexpression/tst_qdeclarativeexpression.cpp10
-rw-r--r--tests/auto/declarative/qdeclarativefontloader/data/qtbug-20268.qml27
-rw-r--r--tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp23
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/chainInCompletion.qml5
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/testtypes.cpp28
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/testtypes.h18
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp129
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/ReadOnlyType.qml5
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/property.5.errors.txt1
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/property.5.qml6
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/readOnly.5.errors.txt2
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/readOnly.5.qml5
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/readonly.qml17
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp54
-rw-r--r--tests/auto/declarative/qdeclarativelistcompositor/tst_qdeclarativelistcompositor.cpp236
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/data/workerremoveelement.js8
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/data/workerremoveelement.qml33
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/data/workerremovelist.js9
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/data/workerremovelist.qml33
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/data/workersync.js8
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/data/workersync.qml32
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro4
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp608
-rw-r--r--tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp12
-rw-r--r--tests/auto/declarative/qdeclarativeqt/data/consoleLog.qml22
-rw-r--r--tests/auto/declarative/qdeclarativeqt/data/resolvedUrl.qml13
-rw-r--r--tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp49
-rw-r--r--tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash3.qml27
-rw-r--r--tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp22
-rw-r--r--tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp5
-rw-r--r--tests/auto/declarative/qdeclarativeworkerscript/data/externalObjectWorker.qml14
-rw-r--r--tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp11
-rw-r--r--tests/auto/declarative/qjsengine/tst_qjsengine.cpp5
-rw-r--r--tests/auto/declarative/qmlplugindump/tst_qmlplugindump.cpp12
-rw-r--r--tests/auto/declarative/qquickanchors/data/anchors.qml162
-rw-r--r--tests/auto/declarative/qquickanchors/data/centerin.qml12
-rw-r--r--tests/auto/declarative/qquickanchors/data/centerinRotation.qml17
-rw-r--r--tests/auto/declarative/qquickanchors/data/crash1.qml11
-rw-r--r--tests/auto/declarative/qquickanchors/data/fill.qml14
-rw-r--r--tests/auto/declarative/qquickanchors/data/hvCenter.qml11
-rw-r--r--tests/auto/declarative/qquickanchors/data/loop1.qml8
-rw-r--r--tests/auto/declarative/qquickanchors/data/loop2.qml20
-rw-r--r--tests/auto/declarative/qquickanchors/data/margins.qml13
-rw-r--r--tests/auto/declarative/qquickanchors/qquickanchors.pro12
-rw-r--r--tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp693
-rw-r--r--tests/auto/declarative/qquickcanvas/tst_qquickcanvas.cpp5
-rw-r--r--tests/auto/declarative/qquickflickable/tst_qquickflickable.cpp2
-rw-r--r--tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp4
-rw-r--r--tests/auto/declarative/qquickgridview/tst_qquickgridview.cpp104
-rw-r--r--tests/auto/declarative/qquickitem/tst_qquickitem.cpp5
-rw-r--r--tests/auto/declarative/qquickitem2/qquickitem2.pro2
-rw-r--r--tests/auto/declarative/qquickmultipointtoucharea/data/inFlickable.qml25
-rw-r--r--tests/auto/declarative/qquickmultipointtoucharea/data/nested.qml27
-rw-r--r--tests/auto/declarative/qquickmultipointtoucharea/data/nonOverlapping.qml32
-rw-r--r--tests/auto/declarative/qquickmultipointtoucharea/data/properties.qml15
-rw-r--r--tests/auto/declarative/qquickmultipointtoucharea/data/signalTest.qml25
-rw-r--r--tests/auto/declarative/qquickmultipointtoucharea/qquickmultipointtoucharea.pro11
-rw-r--r--tests/auto/declarative/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp586
-rw-r--r--tests/auto/declarative/qquickpathview/data/pathline.qml48
-rw-r--r--tests/auto/declarative/qquickpathview/tst_qquickpathview.cpp89
-rw-r--r--tests/auto/declarative/qquickpositioners/tst_qquickpositioners.cpp22
-rw-r--r--tests/auto/declarative/qquickspriteimage/data/basic.qml60
-rw-r--r--tests/auto/declarative/qquickspriteimage/data/squarefacesprite.pngbin0 -> 496 bytes
-rw-r--r--tests/auto/declarative/qquickspriteimage/qquickspriteimage.pro12
-rw-r--r--tests/auto/declarative/qquickspriteimage/tst_qquickspriteimage.cpp81
-rw-r--r--tests/auto/declarative/qquicktext/tst_qquicktext.cpp13
-rw-r--r--tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp289
-rw-r--r--tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp369
-rw-r--r--tests/auto/declarative/qquickview/tst_qquickview.cpp4
-rw-r--r--tests/auto/declarative/qquickvisualdatamodel/data/create.qml3
-rw-r--r--tests/auto/declarative/qquickvisualdatamodel/data/datalist-package.qml20
-rw-r--r--tests/auto/declarative/qquickvisualdatamodel/data/groups-invalid.qml14
-rw-r--r--tests/auto/declarative/qquickvisualdatamodel/data/groups-package.qml52
-rw-r--r--tests/auto/declarative/qquickvisualdatamodel/data/groups.qml8
-rw-r--r--tests/auto/declarative/qquickvisualdatamodel/data/onChanged.qml87
-rw-r--r--tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp277
-rw-r--r--tests/auto/declarative/v4/data/qtbug_21883.qml5
-rw-r--r--tests/auto/declarative/v4/tst_v4.cpp14
-rw-r--r--tests/auto/headersclean/tst_headersclean.cpp1
-rw-r--r--tests/auto/particles/qquickage/tst_qquickage.cpp18
-rw-r--r--tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp3
-rw-r--r--tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp3
-rw-r--r--tests/auto/particles/qquickcustomaffector/data/basic.qml7
-rw-r--r--tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp14
-rw-r--r--tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp3
-rw-r--r--tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp4
-rw-r--r--tests/auto/particles/qquickfriction/tst_qquickfriction.cpp6
-rw-r--r--tests/auto/particles/qquickgravity/tst_qquickgravity.cpp13
-rw-r--r--tests/auto/particles/qquickgroupgoal/data/basic.qml73
-rw-r--r--tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro11
-rw-r--r--tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp90
-rw-r--r--tests/auto/particles/qquickimageparticle/qquickimageparticle.pro1
-rw-r--r--tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp15
-rw-r--r--tests/auto/particles/qquickitemparticle/qquickitemparticle.pro2
-rw-r--r--tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp3
-rw-r--r--tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp3
-rw-r--r--tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp3
-rw-r--r--tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp1
-rw-r--r--tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp3
-rw-r--r--tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp3
-rw-r--r--tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp3
-rw-r--r--tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp3
-rw-r--r--tests/auto/particles/qquickspritegoal/data/basic.qml81
-rw-r--r--tests/auto/particles/qquickspritegoal/qquickspritegoal.pro11
-rw-r--r--tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp81
-rw-r--r--tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp3
-rw-r--r--tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp3
-rw-r--r--tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp3
-rw-r--r--tests/auto/particles/qquickwander/tst_qquickwander.cpp3
-rw-r--r--tests/auto/qtquick1/examples/examples.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/qdeclarativefocusscope.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativestates/data/signalOverrideCrash3.qml27
-rw-r--r--tests/auto/qtquick1/qdeclarativestates/tst_qdeclarativestates.cpp17
-rw-r--r--tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp4
160 files changed, 6281 insertions, 904 deletions
diff --git a/tests/auto/declarative/debugger/debugger.pro b/tests/auto/declarative/debugger/debugger.pro
index 869b3a8cd6..90c5d4bc7e 100644
--- a/tests/auto/declarative/debugger/debugger.pro
+++ b/tests/auto/declarative/debugger/debugger.pro
@@ -6,6 +6,7 @@ PRIVATETESTS += \
qdeclarativedebugservice \
qdeclarativedebugjs \
qdeclarativeinspector \
+ qdeclarativedebugtrace \
qpacketprotocol
contains(QT_CONFIG, private_tests) {
diff --git a/tests/auto/declarative/debugger/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp b/tests/auto/declarative/debugger/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp
index 1587eee060..82e25598e9 100644
--- a/tests/auto/declarative/debugger/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp
+++ b/tests/auto/declarative/debugger/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp
@@ -162,7 +162,7 @@ void tst_QDeclarativeDebugClient::sequentialConnect()
QCOMPARE(m_conn->state(), QAbstractSocket::UnconnectedState);
// Make sure that the disconnect is actually delivered to the server
- QGuiApplication::processEvents();
+ QTest::qWait(100);
connection2.connectToHost("127.0.0.1", PORT);
QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Connection established");
diff --git a/tests/auto/declarative/debugger/qdeclarativedebugjs/qdeclarativedebugjs.pro b/tests/auto/declarative/debugger/qdeclarativedebugjs/qdeclarativedebugjs.pro
index 1cbbbc1c58..a2286ae0d5 100644
--- a/tests/auto/declarative/debugger/qdeclarativedebugjs/qdeclarativedebugjs.pro
+++ b/tests/auto/declarative/debugger/qdeclarativedebugjs/qdeclarativedebugjs.pro
@@ -15,6 +15,6 @@ testDataFiles.path = .
DEPLOYMENT += testDataFiles
-CONFIG += parallel_test
+CONFIG += parallel_test insignificant_test
OTHER_FILES += data/test.qml data/test.js
diff --git a/tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp b/tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp
index 73cea4e2d7..1239c43a70 100644
--- a/tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp
+++ b/tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp
@@ -1078,17 +1078,15 @@ void tst_QDeclarativeDebugJS::setBreakpointInScriptOnTimerCallback()
{
int sourceLine = 49;
client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
+ //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
+ sourceLine = 67;
+ client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
client->startDebugging();
QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
client->evaluate("timer.running = true");
client->continueDebugging(QJSDebugClient::Continue);
- //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
-
- sourceLine = 67;
-
- client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
QString jsonString(client->response);
@@ -1376,6 +1374,7 @@ void tst_QDeclarativeDebugJS::setExceptionBreak()
client->startDebugging();
QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
client->evaluate("root.raiseException = true");
+ QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
client->continueDebugging(QJSDebugClient::Continue);
QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
}
@@ -1595,6 +1594,7 @@ void tst_QDeclarativeDebugJS::getScopes()
QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
client->scopes();
+ QEXPECT_FAIL("", "Failing after v8 integration", Abort);
QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
}
diff --git a/tests/auto/declarative/debugger/qdeclarativedebugtrace/data/test.qml b/tests/auto/declarative/debugger/qdeclarativedebugtrace/data/test.qml
new file mode 100644
index 0000000000..9c36e13c5b
--- /dev/null
+++ b/tests/auto/declarative/debugger/qdeclarativedebugtrace/data/test.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+Item {
+
+}
diff --git a/tests/auto/declarative/debugger/qdeclarativedebugtrace/qdeclarativedebugtrace.pro b/tests/auto/declarative/debugger/qdeclarativedebugtrace/qdeclarativedebugtrace.pro
new file mode 100644
index 0000000000..9ddb51c66d
--- /dev/null
+++ b/tests/auto/declarative/debugger/qdeclarativedebugtrace/qdeclarativedebugtrace.pro
@@ -0,0 +1,14 @@
+CONFIG += testcase
+TARGET = tst_qdeclarativedebugtrace
+macx:CONFIG -= app_bundle
+
+HEADERS += ../shared/debugutil_p.h
+
+SOURCES += tst_qdeclarativedebugtrace.cpp \
+ ../shared/debugutil.cpp
+
+OTHER_FILES += data/test.qml
+
+CONFIG += parallel_test declarative_debug
+
+QT += core-private gui-private v8-private declarative-private network testlib
diff --git a/tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp b/tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp
new file mode 100644
index 0000000000..52271477e7
--- /dev/null
+++ b/tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp
@@ -0,0 +1,252 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+#include <QLibraryInfo>
+
+#include "QtDeclarative/private/qdeclarativedebugtrace_p.h"
+#include "../shared/debugutil_p.h"
+#include "../../shared/util.h"
+
+#define PORT 13773
+#define STR_PORT "13773"
+
+class QDeclarativeDebugTraceClient : public QDeclarativeDebugClient
+{
+ Q_OBJECT
+
+public:
+ QDeclarativeDebugTraceClient(QDeclarativeDebugConnection *connection)
+ : QDeclarativeDebugClient(QLatin1String("CanvasFrameRate"), connection)
+ {
+ }
+
+ QList<QDeclarativeDebugData> traceMessages;
+
+ void setTraceStatus(bool enabled) {
+ QByteArray message;
+ QDataStream stream(&message, QIODevice::WriteOnly);
+ stream << enabled;
+ sendMessage(message);
+ }
+
+signals:
+ void complete();
+
+protected:
+ void messageReceived(const QByteArray &message);
+};
+
+class tst_QDeclarativeDebugTrace : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QDeclarativeDebugTrace()
+ : m_process(0)
+ , m_connection(0)
+ , m_client(0)
+ {
+ }
+
+private:
+ QDeclarativeDebugProcess *m_process;
+ QDeclarativeDebugConnection *m_connection;
+ QDeclarativeDebugTraceClient *m_client;
+
+private slots:
+ void init();
+ void cleanup();
+
+ void connectWithTraceEnabled();
+ void connectWithTraceDisabled();
+};
+
+void QDeclarativeDebugTraceClient::messageReceived(const QByteArray &message)
+{
+ QByteArray msg = message;
+ QDataStream stream(&msg, QIODevice::ReadOnly);
+
+
+ QDeclarativeDebugData data;
+ data.time = -2;
+ data.messageType = -1;
+ data.detailType = -1;
+ data.line = -1;
+ data.framerate = -1;
+ data.animationcount = -1;
+
+ stream >> data.time >> data.messageType;
+
+ QVERIFY(data.time >= -1);
+
+ switch (data.messageType) {
+ case (QDeclarativeDebugTrace::Event): {
+ stream >> data.detailType;
+
+ switch (data.detailType) {
+ case QDeclarativeDebugTrace::AnimationFrame: {
+ stream >> data.framerate >> data.animationcount;
+ QVERIFY(data.framerate != -1);
+ QVERIFY(data.animationcount != -1);
+ break;
+ }
+ case QDeclarativeDebugTrace::FramePaint:
+ case QDeclarativeDebugTrace::Mouse:
+ case QDeclarativeDebugTrace::Key:
+ case QDeclarativeDebugTrace::StartTrace:
+ case QDeclarativeDebugTrace::EndTrace:
+ break;
+ default: {
+ QString failMsg = QString("Unknown event type:") + data.detailType;
+ QFAIL(qPrintable(failMsg));
+ break;
+ }
+ }
+ break;
+ }
+ case QDeclarativeDebugTrace::Complete: {
+ emit complete();
+ QVERIFY(stream.atEnd());
+ return;
+ }
+ case QDeclarativeDebugTrace::RangeStart: {
+ stream >> data.detailType;
+ QVERIFY(data.detailType >= 0 && data.detailType < QDeclarativeDebugTrace::MaximumRangeType);
+ break;
+ }
+ case QDeclarativeDebugTrace::RangeEnd: {
+ stream >> data.detailType;
+ QVERIFY(data.detailType >= 0 && data.detailType < QDeclarativeDebugTrace::MaximumRangeType);
+ break;
+ }
+ case QDeclarativeDebugTrace::RangeData: {
+ stream >> data.detailType >> data.detailData;
+ QVERIFY(data.detailType >= 0 && data.detailType < QDeclarativeDebugTrace::MaximumRangeType);
+ break;
+ }
+ case QDeclarativeDebugTrace::RangeLocation: {
+ stream >> data.detailType >> data.detailData >> data.line;
+ QVERIFY(data.detailType >= 0 && data.detailType < QDeclarativeDebugTrace::MaximumRangeType);
+ QVERIFY(data.line >= -2);
+ break;
+ }
+ default:
+ QString failMsg = QString("Unknown message type:") + data.messageType;
+ QFAIL(qPrintable(failMsg));
+ break;
+ }
+ QVERIFY(stream.atEnd());
+ traceMessages.append(data);
+}
+
+void tst_QDeclarativeDebugTrace::init()
+{
+ const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene";
+ QStringList arguments;
+ arguments << QString("-qmljsdebugger=port:"STR_PORT",block");
+ arguments << QString(TESTDATA(QLatin1String("test.qml")));
+
+ m_process = new QDeclarativeDebugProcess(executable);
+ m_process->start(QStringList() << arguments);
+ if (!m_process->waitForSessionStart()) {
+ QString failMsg = QString("Could not launch app '%1'.\nApplication output:\n%2").arg(
+ executable, m_process->output());
+ QFAIL(qPrintable(failMsg));
+ }
+
+ QDeclarativeDebugConnection *m_connection = new QDeclarativeDebugConnection();
+ m_client = new QDeclarativeDebugTraceClient(m_connection);
+
+ m_connection->connectToHost(QLatin1String("127.0.0.1"), PORT);
+}
+
+void tst_QDeclarativeDebugTrace::cleanup()
+{
+ delete m_process;
+ delete m_connection;
+ delete m_client;
+}
+
+void tst_QDeclarativeDebugTrace::connectWithTraceEnabled()
+{
+ QTRY_COMPARE(m_client->status(), QDeclarativeDebugClient::Enabled);
+ m_client->setTraceStatus(true);
+ m_client->setTraceStatus(false);
+ if (!QDeclarativeDebugTest::waitForSignal(m_client, SIGNAL(complete()))) {
+ QString failMsg
+ = QString("No trace received in time. App output: \n\n").arg(m_process->output());
+ QFAIL(qPrintable(failMsg));
+ }
+
+ // must start with "StartTrace"
+ QCOMPARE(m_client->traceMessages.first().messageType, (int)QDeclarativeDebugTrace::Event);
+ QCOMPARE(m_client->traceMessages.first().detailType, (int)QDeclarativeDebugTrace::StartTrace);
+
+ // must end with "EndTrace"
+ QCOMPARE(m_client->traceMessages.last().messageType, (int)QDeclarativeDebugTrace::Event);
+ QCOMPARE(m_client->traceMessages.last().detailType, (int)QDeclarativeDebugTrace::EndTrace);
+}
+
+void tst_QDeclarativeDebugTrace::connectWithTraceDisabled()
+{
+ QTRY_COMPARE(m_client->status(), QDeclarativeDebugClient::Enabled);
+ m_client->setTraceStatus(false);
+ m_client->setTraceStatus(true);
+ m_client->setTraceStatus(false);
+ if (!QDeclarativeDebugTest::waitForSignal(m_client, SIGNAL(complete()))) {
+ QString failMsg
+ = QString("No trace received in time. App output: \n\n").arg(m_process->output());
+ QFAIL(qPrintable(failMsg));
+ }
+
+ // must start with "StartTrace"
+ QCOMPARE(m_client->traceMessages.first().messageType, (int)QDeclarativeDebugTrace::Event);
+ QCOMPARE(m_client->traceMessages.first().detailType, (int)QDeclarativeDebugTrace::StartTrace);
+
+ // must end with "EndTrace"
+ QCOMPARE(m_client->traceMessages.last().messageType, (int)QDeclarativeDebugTrace::Event);
+ QCOMPARE(m_client->traceMessages.last().detailType, (int)QDeclarativeDebugTrace::EndTrace);
+}
+
+QTEST_MAIN(tst_QDeclarativeDebugTrace)
+
+#include "tst_qdeclarativedebugtrace.moc"
diff --git a/tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.cpp b/tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.cpp
index fe079d645e..5545f8e046 100644
--- a/tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.cpp
+++ b/tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.cpp
@@ -45,8 +45,7 @@
#include <QDebug>
#include <QThread>
-#include "../../../../src/plugins/qmltooling/qmldbg_inspector/qdeclarativeinspectorprotocol.h"
-#include "../../../../shared/util.h"
+#include "../../../../../src/plugins/qmltooling/shared/qdeclarativeinspectorprotocol.h"
#include "../shared/debugutil_p.h"
using namespace QmlJSDebugger;
diff --git a/tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.pro b/tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.pro
index 26e4208f59..63230c05a0 100644
--- a/tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.pro
+++ b/tests/auto/declarative/debugger/qdeclarativeinspector/tst_qdeclarativeinspector.pro
@@ -1,5 +1,5 @@
CONFIG += testcase
-TARGET = tst_qdeclarativinspector
+TARGET = tst_qdeclarativeinspector
macx:CONFIG -= app_bundle
HEADERS += ../shared/debugutil_p.h
diff --git a/tests/auto/declarative/debugger/shared/debugutil.cpp b/tests/auto/declarative/debugger/shared/debugutil.cpp
index 2c769be53f..154e20bdb3 100644
--- a/tests/auto/declarative/debugger/shared/debugutil.cpp
+++ b/tests/auto/declarative/debugger/shared/debugutil.cpp
@@ -148,18 +148,24 @@ bool QDeclarativeDebugProcess::waitForSessionStart()
QString QDeclarativeDebugProcess::output() const
{
- return m_outputBuffer;
+ return m_output;
}
void QDeclarativeDebugProcess::processAppOutput()
{
m_mutex.lock();
- const QString appOutput = m_process.readAll();
- static QRegExp newline("[\n\r]{1,2}");
- QStringList lines = appOutput.split(newline);
- foreach (const QString &line, lines) {
- if (line.isEmpty())
- continue;
+
+ QString newOutput = m_process.readAll();
+ m_output.append(newOutput);
+ m_outputBuffer.append(newOutput);
+
+ while (true) {
+ const int nlIndex = m_outputBuffer.indexOf(QLatin1Char('\n'));
+ if (nlIndex < 0) // no further complete lines
+ break;
+ const QString line = m_outputBuffer.left(nlIndex);
+ m_outputBuffer = m_outputBuffer.right(m_outputBuffer.size() - nlIndex - 1);
+
if (line.startsWith("Qml debugging is enabled")) // ignore
continue;
if (line.startsWith("QDeclarativeDebugServer:")) {
@@ -172,7 +178,6 @@ void QDeclarativeDebugProcess::processAppOutput()
continue;
}
}
- m_outputBuffer.append(appOutput);
}
m_mutex.unlock();
}
diff --git a/tests/auto/declarative/debugger/shared/debugutil_p.h b/tests/auto/declarative/debugger/shared/debugutil_p.h
index 99a482cf2a..24b7e252cb 100644
--- a/tests/auto/declarative/debugger/shared/debugutil_p.h
+++ b/tests/auto/declarative/debugger/shared/debugutil_p.h
@@ -113,6 +113,7 @@ private:
QString m_executable;
QProcess m_process;
QString m_outputBuffer;
+ QString m_output;
QTimer m_timer;
QEventLoop m_eventLoop;
QMutex m_mutex;
diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro
index cd4309486f..f2f127ffc1 100644
--- a/tests/auto/declarative/declarative.pro
+++ b/tests/auto/declarative/declarative.pro
@@ -62,6 +62,7 @@ PRIVATETESTS += \
!contains(QT_CONFIG,xmlpatterns):PRIVATETESTS -= qdeclarativexmllistmodel
QUICKTESTS = \
+ qquickanchors \
qquickanimatedimage \
qquickborderimage \
qquickcanvas \
@@ -77,10 +78,12 @@ QUICKTESTS = \
qquicklistview \
qquickloader \
qquickmousearea \
+ qquickmultipointtoucharea \
qquickpathview \
qquickpincharea \
qquickpositioners \
qquickrepeater \
+ qquickspriteimage \
qquicktext \
qquicktextedit \
qquicktextinput \
diff --git a/tests/auto/declarative/examples/examples.pro b/tests/auto/declarative/examples/examples.pro
index e68a93c6d5..4ae24bb1a4 100644
--- a/tests/auto/declarative/examples/examples.pro
+++ b/tests/auto/declarative/examples/examples.pro
@@ -7,7 +7,5 @@ DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
#temporary
-CONFIG += insignificant_test
+CONFIG += insignificant_test #QTBUG-22672
QT += core-private gui-private declarative-private qtquick1-private widgets-private v8-private testlib
-
-qpa:CONFIG+=insignificant_test # QTBUG-20990, aborts
diff --git a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
index 6c375a5adf..b355a8097a 100644
--- a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
+++ b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
@@ -806,9 +806,11 @@ void tst_qdeclarativeanimations::attached()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("attached.qml")));
- QTest::ignoreMessage(QtDebugMsg, "off");
- QTest::ignoreMessage(QtDebugMsg, "on");
+ QUrl url(QUrl::fromLocalFile(TESTDATA("attached.qml")));
+ QDeclarativeComponent c(&engine, url);
+ QString messageFormat = QString(QLatin1String("%1 (%2:%3)"));
+ QTest::ignoreMessage(QtDebugMsg, messageFormat.arg(QLatin1String("off")).arg(url.toString()).arg(24).toLatin1());
+ QTest::ignoreMessage(QtDebugMsg, messageFormat.arg(QLatin1String("on")).arg(url.toString()).arg(20).toLatin1());
QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
QVERIFY(rect);
}
diff --git a/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp b/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp
index db345e38fd..72313ab054 100644
--- a/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp
+++ b/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp
@@ -67,8 +67,6 @@ tst_qdeclarativeapplication::tst_qdeclarativeapplication()
void tst_qdeclarativeapplication::active()
{
- QSKIP("QTBUG-21573");
-
QDeclarativeComponent component(&engine);
component.setData("import QtQuick 2.0; Item { property bool active: Qt.application.active }", QUrl::fromLocalFile(""));
QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
@@ -84,23 +82,28 @@ void tst_qdeclarativeapplication::active()
view.show();
view.requestActivateWindow();
QTest::qWait(50);
+ QEXPECT_FAIL("", "QTBUG-21573", Abort);
QTRY_COMPARE(view.status(), QQuickView::Ready);
QCOMPARE(item->property("active").toBool(), QGuiApplication::activeWindow() != 0);
- // not active again
+#if 0
+ // QGuiApplication has no equivalent of setActiveWindow(0). QTBUG-21573
+ // Is this different to clearing the active state of the window or can it be removed?
+ // On Mac, setActiveWindow(0) on mac does not deactivate the current application,
+ // must switch to a different app or hide the current app to trigger this
// on mac, setActiveWindow(0) on mac does not deactivate the current application
// (you have to switch to a different app or hide the current app to trigger this)
-#if !defined(Q_WS_MAC)
-// QTBUG-21573
-// QGuiApplication::setActiveWindow(0);
+
+ // not active again
+ QGuiApplication::setActiveWindow(0);
QVERIFY(!item->property("active").toBool());
QCOMPARE(item->property("active").toBool(), QGuiApplication::activeWindow() != 0);
#endif
+
}
void tst_qdeclarativeapplication::layoutDirection()
{
- QSKIP("QTBUG-21573");
QDeclarativeComponent component(&engine);
component.setData("import QtQuick 2.0; Item { property bool layoutDirection: Qt.application.layoutDirection }", QUrl::fromLocalFile(""));
@@ -114,6 +117,7 @@ void tst_qdeclarativeapplication::layoutDirection()
// mirrored
QGuiApplication::setLayoutDirection(Qt::RightToLeft);
+ QEXPECT_FAIL("", "QTBUG-21573", Abort);
QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::RightToLeft);
// not mirrored again
diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/startOnCompleted.qml b/tests/auto/declarative/qdeclarativebehaviors/data/startOnCompleted.qml
new file mode 100644
index 0000000000..fdc3779a5c
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativebehaviors/data/startOnCompleted.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 400
+ height: 400
+
+ Rectangle {
+ id: innerRect
+ width: 100; height: 100
+ color: "green"
+ Behavior on x { NumberAnimation {} }
+ }
+
+ Component.onCompleted: innerRect.x = 100
+}
diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/valueType.qml b/tests/auto/declarative/qdeclarativebehaviors/data/valueType.qml
new file mode 100644
index 0000000000..7bc8297dc7
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativebehaviors/data/valueType.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+Rectangle {
+ width: 400
+ height: 400
+
+ color.r: 1
+ color.g: 0
+ color.b: 1
+
+ Behavior on color.r { NumberAnimation { duration: 500; } }
+
+ function changeR() { color.r = 0 }
+}
diff --git a/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp b/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp
index 38a07eb3d4..35f8b6219d 100644
--- a/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp
+++ b/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp
@@ -66,6 +66,7 @@ private slots:
void replaceBinding();
//void transitionOverrides();
void group();
+ void valueType();
void emptyBehavior();
void explicitSelection();
void nonSelectingBehavior();
@@ -77,6 +78,7 @@ private slots:
void runningTrue();
void sameValue();
void delayedRegistration();
+ void startOnCompleted();
};
void tst_qdeclarativebehaviors::simpleBehavior()
@@ -236,6 +238,19 @@ void tst_qdeclarativebehaviors::group()
}
}
+void tst_qdeclarativebehaviors::valueType()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("valueType.qml")));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QVERIFY(rect);
+
+ //QTBUG-20827
+ QCOMPARE(rect->color(), QColor::fromRgb(255,0,255));
+
+ delete rect;
+}
+
void tst_qdeclarativebehaviors::emptyBehavior()
{
QDeclarativeEngine engine;
@@ -433,6 +448,25 @@ void tst_qdeclarativebehaviors::delayedRegistration()
QTRY_COMPARE(innerRect->property("x").toInt(), int(100));
}
+//QTBUG-22555
+void tst_qdeclarativebehaviors::startOnCompleted()
+{
+ QDeclarativeEngine engine;
+
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("startOnCompleted.qml")));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QVERIFY(rect != 0);
+
+ QQuickItem *innerRect = rect->findChild<QQuickRectangle*>();
+ QVERIFY(innerRect != 0);
+
+ QCOMPARE(innerRect->property("x").toInt(), int(0));
+
+ QTRY_COMPARE(innerRect->property("x").toInt(), int(100));
+
+ delete rect;
+}
+
QTEST_MAIN(tst_qdeclarativebehaviors)
#include "tst_qdeclarativebehaviors.moc"
diff --git a/tests/auto/declarative/qdeclarativecontext/data/RefreshExpressionsType.qml b/tests/auto/declarative/qdeclarativecontext/data/RefreshExpressionsType.qml
new file mode 100644
index 0000000000..b7c3427c85
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativecontext/data/RefreshExpressionsType.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+QtObject {
+ property var dummy: countCommand.doCommand();
+}
diff --git a/tests/auto/declarative/qdeclarativecontext/data/refreshExpressions.qml b/tests/auto/declarative/qdeclarativecontext/data/refreshExpressions.qml
new file mode 100644
index 0000000000..01e503f8dc
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativecontext/data/refreshExpressions.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+QtObject {
+ property variant v1: RefreshExpressionsType {}
+ property variant v2: RefreshExpressionsType {}
+}
diff --git a/tests/auto/declarative/qdeclarativecontext/data/refreshExpressionsRootContext.qml b/tests/auto/declarative/qdeclarativecontext/data/refreshExpressionsRootContext.qml
new file mode 100644
index 0000000000..bd82cd9552
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativecontext/data/refreshExpressionsRootContext.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+QtObject {
+ property var dummy: countCommand.doCommand(), unresolvedName
+}
+
diff --git a/tests/auto/declarative/qdeclarativecontext/qdeclarativecontext.pro b/tests/auto/declarative/qdeclarativecontext/qdeclarativecontext.pro
index 65af53a45d..5e48bec033 100644
--- a/tests/auto/declarative/qdeclarativecontext/qdeclarativecontext.pro
+++ b/tests/auto/declarative/qdeclarativecontext/qdeclarativecontext.pro
@@ -3,6 +3,10 @@ TARGET = tst_qdeclarativecontext
SOURCES += tst_qdeclarativecontext.cpp
macx:CONFIG -= app_bundle
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
CONFIG += parallel_test
-QT += core-private gui-private declarative-private testlib
+QT += core-private gui-private declarative-private testlib v8-private
diff --git a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp
index c241acac05..68599a2e83 100644
--- a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp
+++ b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp
@@ -45,6 +45,18 @@
#include <QDeclarativeContext>
#include <QDeclarativeComponent>
#include <QDeclarativeExpression>
+#include <private/qdeclarativecontext_p.h>
+#include "../shared/util.h"
+
+inline QUrl TEST_FILE(const QString &filename)
+{
+ return QUrl::fromLocalFile(TESTDATA(filename));
+}
+
+inline QUrl TEST_FILE(const char *filename)
+{
+ return TEST_FILE(QLatin1String(filename));
+}
class tst_qdeclarativecontext : public QObject
{
@@ -64,6 +76,10 @@ private slots:
void readOnlyContexts();
void nameForObject();
+ void refreshExpressions();
+ void refreshExpressionsCrash();
+ void refreshExpressionsRootContext();
+
private:
QDeclarativeEngine engine;
};
@@ -490,6 +506,144 @@ void tst_qdeclarativecontext::nameForObject()
delete o;
}
+class DeleteCommand : public QObject
+{
+Q_OBJECT
+public:
+ DeleteCommand() : object(0) {}
+
+ QObject *object;
+
+public slots:
+ void doCommand() { if (object) delete object; object = 0; }
+};
+
+// Calling refresh expressions would crash if an expression or context was deleted during
+// the refreshing
+void tst_qdeclarativecontext::refreshExpressionsCrash()
+{
+ {
+ QDeclarativeEngine engine;
+
+ DeleteCommand command;
+ engine.rootContext()->setContextProperty("deleteCommand", &command);
+ // We use a fresh context here to bypass any root-context optimizations in
+ // the engine
+ QDeclarativeContext ctxt(engine.rootContext());
+
+ QDeclarativeComponent component(&engine);
+ component.setData("import QtQuick 2.0; QtObject { property var binding: deleteCommand.doCommand() }", QUrl());
+ QVERIFY(component.isReady());
+
+ QObject *o1 = component.create(&ctxt);
+ QObject *o2 = component.create(&ctxt);
+
+ command.object = o2;
+
+ QDeclarativeContextData::get(&ctxt)->refreshExpressions();
+
+ delete o1;
+ }
+ {
+ QDeclarativeEngine engine;
+
+ DeleteCommand command;
+ engine.rootContext()->setContextProperty("deleteCommand", &command);
+ // We use a fresh context here to bypass any root-context optimizations in
+ // the engine
+ QDeclarativeContext ctxt(engine.rootContext());
+
+ QDeclarativeComponent component(&engine);
+ component.setData("import QtQuick 2.0; QtObject { property var binding: deleteCommand.doCommand() }", QUrl());
+ QVERIFY(component.isReady());
+
+ QObject *o1 = component.create(&ctxt);
+ QObject *o2 = component.create(&ctxt);
+
+ command.object = o1;
+
+ QDeclarativeContextData::get(&ctxt)->refreshExpressions();
+
+ delete o2;
+ }
+}
+
+class CountCommand : public QObject
+{
+Q_OBJECT
+public:
+ CountCommand() : count(0) {}
+
+ int count;
+
+public slots:
+ void doCommand() { ++count; }
+};
+
+
+// Test that calling refresh expressions causes all the expressions to refresh
+void tst_qdeclarativecontext::refreshExpressions()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeComponent component(&engine, TEST_FILE("refreshExpressions.qml"));
+ QDeclarativeComponent component2(&engine, TEST_FILE("RefreshExpressionsType.qml"));
+
+ CountCommand command;
+ engine.rootContext()->setContextProperty("countCommand", &command);
+
+ // We use a fresh context here to bypass any root-context optimizations in
+ // the engine
+ QDeclarativeContext context(engine.rootContext());
+ QDeclarativeContext context2(&context);
+
+ QObject *o1 = component.create(&context);
+ QObject *o2 = component.create(&context2);
+ QObject *o3 = component2.create(&context);
+
+ QCOMPARE(command.count, 5);
+
+ QDeclarativeContextData::get(&context)->refreshExpressions();
+
+ QCOMPARE(command.count, 10);
+
+ delete o3;
+ delete o2;
+ delete o1;
+}
+
+// Test that updating the root context, only causes expressions in contexts with an
+// unresolved name to reevaluate
+void tst_qdeclarativecontext::refreshExpressionsRootContext()
+{
+ QDeclarativeEngine engine;
+
+ CountCommand command;
+ engine.rootContext()->setContextProperty("countCommand", &command);
+
+ QDeclarativeComponent component(&engine, TEST_FILE("refreshExpressions.qml"));
+ QDeclarativeComponent component2(&engine, TEST_FILE("refreshExpressionsRootContext.qml"));
+
+ QDeclarativeContext context(engine.rootContext());
+ QDeclarativeContext context2(engine.rootContext());
+
+ QString warning = component2.url().toString() + QLatin1String(":4: ReferenceError: Can't find variable: unresolvedName");
+
+ QObject *o1 = component.create(&context);
+
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
+ QObject *o2 = component2.create(&context2);
+
+ QCOMPARE(command.count, 3);
+
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
+ QDeclarativeContextData::get(engine.rootContext())->refreshExpressions();
+
+ QCOMPARE(command.count, 4);
+
+ delete o2;
+ delete o1;
+}
+
QTEST_MAIN(tst_qdeclarativecontext)
#include "tst_qdeclarativecontext.moc"
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/SequenceConversionComponent.qml b/tests/auto/declarative/qdeclarativeecmascript/data/SequenceConversionComponent.qml
new file mode 100644
index 0000000000..0c7f60b062
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/SequenceConversionComponent.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+MySequenceConversionObject {
+ id: sccmsco
+ objectName: "sccmsco"
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/deleteWhileBindingRunning.qml b/tests/auto/declarative/qdeclarativeecmascript/data/deleteWhileBindingRunning.qml
new file mode 100644
index 0000000000..b5cc59e2c0
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/deleteWhileBindingRunning.qml
@@ -0,0 +1,5 @@
+import Qt.test 1.0
+
+MyDeleteObject {
+ property int result: nestedObject.intProperty + deleteNestedObject
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/forInLoop.qml b/tests/auto/declarative/qdeclarativeecmascript/data/forInLoop.qml
new file mode 100644
index 0000000000..f14367f177
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/forInLoop.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+
+QtObject {
+ property list<QtObject> objects
+ objects: [QtObject { objectName: "obj1" }, QtObject { objectName: "obj2" }, QtObject { objectName: "obj3" }]
+ property string listResult
+
+ function listProperty() {
+ for (var i in objects)
+ listResult += i + "=" + objects[i].objectName + "|"
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/nonNotifyable.qml b/tests/auto/declarative/qdeclarativeecmascript/data/nonNotifyable.qml
new file mode 100644
index 0000000000..2b8b113c34
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/nonNotifyable.qml
@@ -0,0 +1,6 @@
+import Qt.test 1.0
+
+MyQmlObject {
+ id: root
+ property int test: root.value
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_20344.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_20344.qml
new file mode 100644
index 0000000000..f490848caf
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_20344.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+MyQmlObject {
+ Component.onCompleted: v8function()
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/readonlyDeclaration.qml b/tests/auto/declarative/qdeclarativeecmascript/data/readonlyDeclaration.qml
new file mode 100644
index 0000000000..5377d2dcbf
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/readonlyDeclaration.qml
@@ -0,0 +1,45 @@
+import QtQuick 2.0
+
+QtObject {
+ property int dummy: 13
+
+ readonly property int test1: 19
+ readonly property int test2: dummy * 49
+ readonly property alias test3: other.test
+
+ property bool test: false
+
+ property var dummyObj: QtObject {
+ id: other
+ property int test: 9
+ }
+
+ Component.onCompleted: {
+ if (test1 != 19) return;
+ if (test2 != 637) return;
+ if (test3 != 9) return;
+
+ var caught = false;
+
+ caught = false;
+ try { test1 = 13 } catch (e) { caught = true; }
+ if (!caught) return;
+
+ caught = false;
+ try { test2 = 13 } catch (e) { caught = true; }
+ if (!caught) return;
+
+ caught = false;
+ try { test3 = 13 } catch (e) { caught = true; }
+ if (!caught) return;
+
+ other.test = 13;
+ dummy = 9;
+
+ if (test1 != 19) return;
+ if (test2 != 441) return;
+ if (test3 != 13) return;
+
+ test = true;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.array.qml b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.array.qml
new file mode 100644
index 0000000000..5eaa225708
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.array.qml
@@ -0,0 +1,152 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: root
+ objectName: "root"
+
+ MySequenceConversionObject {
+ id: msco
+ objectName: "msco"
+ }
+
+ property bool success: false
+
+ property variant intList
+ property variant qrealList
+ property variant boolList
+ property variant stringList
+
+ function indexedAccess() {
+ intList = msco.intListProperty;
+ var jsIntList = msco.intListProperty;
+ qrealList = msco.qrealListProperty;
+ var jsQrealList = msco.qrealListProperty;
+ boolList = msco.boolListProperty;
+ var jsBoolList = msco.boolListProperty;
+ stringList = msco.stringListProperty;
+ var jsStringList = msco.stringListProperty;
+
+ // Three cases: direct property modification, variant copy modification, js var reference modification.
+ // Only the first and third should "write back" to the original QObject Q_PROPERTY; the second one
+ // should have no effect whatsoever to maintain "property variant" semantics (see e.g., valuetype).
+ success = true;
+
+ msco.intListProperty[1] = 33;
+ if (msco.intListProperty[1] != 33) success = false; // ensure write back
+ intList[1] = 44;
+ if (intList[1] == 44) success = false; // ensure no effect
+ jsIntList[1] = 55;
+ if (jsIntList[1] != 55
+ || jsIntList[1] != msco.intListProperty[1]) success = false; // ensure write back
+
+ msco.qrealListProperty[1] = 33.3;
+ if (msco.qrealListProperty[1] != 33.3) success = false; // ensure write back
+ qrealList[1] = 44.4;
+ if (qrealList[1] == 44.4) success = false; // ensure no effect
+ jsQrealList[1] = 55.5;
+ if (jsQrealList[1] != 55.5
+ || jsQrealList[1] != msco.qrealListProperty[1]) success = false; // ensure write back
+
+ msco.boolListProperty[1] = true;
+ if (msco.boolListProperty[1] != true) success = false; // ensure write back
+ boolList[1] = true;
+ if (boolList[1] != false) success = false; // ensure no effect
+ jsBoolList[1] = false;
+ if (jsBoolList[1] != false
+ || jsBoolList[1] != msco.boolListProperty[1]) success = false; // ensure write back
+
+ msco.stringListProperty[1] = "changed";
+ if (msco.stringListProperty[1] != "changed") success = false; // ensure write back
+ stringList[1] = "changed";
+ if (stringList[1] != "second") success = false; // ensure no effect
+ jsStringList[1] = "different";
+ if (jsStringList[1] != "different"
+ || jsStringList[1] != msco.stringListProperty[1]) success = false; // ensure write back
+ }
+
+ function arrayOperations() {
+ success = true;
+ var expected = 0;
+ var expectedStr = "";
+
+ // ecma262r3 defines array as implementing Length and Put. Test put here.
+ msco.intListProperty.asdf = 5; // shouldn't work, only indexes are valid names.
+ if (msco.intListProperty.asdf == 5) success = false;
+ msco.intListProperty[3] = 38; // should work.
+ if (msco.intListProperty[3] != 38) success = false;
+ msco.intListProperty[199] = 200; // should work, and should set length to 200.
+ if (msco.intListProperty[199] != 200) success = false;
+ if (msco.intListProperty.length != 200) success = false;
+
+ // other operations are defined on the array prototype; see if they work.
+ msco.intListProperty = [ 0, 1, 2, 3, 4, 5, 6, 7 ];
+ msco.intListProperty.splice(1,3, 33, 44, 55, 66);
+ expected = [ 0, 33, 44, 55, 66, 4, 5, 6, 7 ];
+ if (msco.intListProperty.toString() != expected.toString()) success = false;
+
+ msco.qrealListProperty = [ 0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1 ];
+ msco.qrealListProperty.splice(1,3, 33.33, 44.44, 55.55, 66.66);
+ expected = [ 0.1, 33.33, 44.44, 55.55, 66.66, 4.1, 5.1, 6.1, 7.1 ];
+ if (msco.qrealListProperty.toString() != expected.toString()) success = false;
+
+ msco.boolListProperty = [ false, true, true, false, false, true, false, true ];
+ msco.boolListProperty.splice(1,3, false, true, false, false);
+ expected = [ false, false, true, false, false, false, true, false, true ];
+ if (msco.boolListProperty.toString() != expected.toString()) success = false;
+
+ msco.stringListProperty = [ "one", "two", "three", "four", "five", "six", "seven", "eight" ];
+ msco.stringListProperty.splice(1,3, "nine", "ten", "eleven", "twelve");
+ expected = [ "one", "nine", "ten", "eleven", "twelve", "five", "six", "seven", "eight" ];
+ if (msco.stringListProperty.toString() != expected.toString()) success = false;
+ }
+
+ property variant variantList: [ 1, 2, 3, 4, 5 ];
+ property variant variantList2: [ 1, 2, 3, 4, 5 ];
+ function testEqualitySemantics() {
+ // ensure equality semantics match JS array equality semantics
+ success = true;
+
+ msco.intListProperty = [ 1, 2, 3, 4, 5 ];
+ msco.intListProperty2 = [ 1, 2, 3, 4, 5 ];
+ var jsIntList = [ 1, 2, 3, 4, 5 ];
+ var jsIntList2 = [ 1, 2, 3, 4, 5 ];
+
+ if (jsIntList != jsIntList) success = false;
+ if (jsIntList == jsIntList2) success = false;
+ if (jsIntList == msco.intListProperty) success = false;
+ if (jsIntList == variantList) success = false;
+
+ if (msco.intListProperty != msco.intListProperty) success = false;
+ if (msco.intListProperty == msco.intListProperty2) success = false;
+ if (msco.intListProperty == jsIntList) success = false;
+ if (msco.intListProperty == variantList) success = false;
+
+ if (variantList == variantList) return false;
+ if (variantList == variantList2) return false;
+ if (variantList == msco.intListProperty) return false;
+ if (variantList == jsIntList) return false;
+
+ if ((jsIntList == jsIntList2) != (jsIntList == msco.intListProperty)) success = false;
+ if ((jsIntList == jsIntList2) != (msco.intListProperty == msco.intListProperty2)) success = false;
+ if ((jsIntList == jsIntList) != (msco.intListProperty == msco.intListProperty)) success = false;
+ if ((jsIntList == variantList) != (msco.intListProperty == variantList)) success = false;
+ if ((variantList == jsIntList) != (variantList == msco.intListProperty)) success = false;
+ if ((msco.intListProperty == variantList) != (variantList == msco.intListProperty)) success = false;
+ }
+
+ property bool referenceDeletion: false
+ function testReferenceDeletion() {
+ referenceDeletion = true;
+ var testObj = msco.generateTestObject();
+ testObj.intListProperty = [1, 2, 3, 4, 5];
+ var testSequence = testObj.intListProperty;
+ var prevString = testSequence.toString();
+ var prevValueOf = testSequence.valueOf();
+ var prevLength = testSequence.length;
+ msco.deleteTestObject(testObj); // delete referenced object.
+ if (testSequence.toString() == prevString) referenceDeletion = false;
+ if (testSequence.valueOf() == prevValueOf) referenceDeletion = false;
+ if (testSequence.length == prevLength) referenceDeletion = false;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.bindings.error.qml b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.bindings.error.qml
new file mode 100644
index 0000000000..9c87dd293e
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.bindings.error.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: root
+ objectName: "root"
+
+ MySequenceConversionObject {
+ id: msco
+ objectName: "msco"
+ intListProperty: [ 1, 2, 3, 6, 7 ]
+ }
+
+ MySequenceConversionObject {
+ id: mscoTwo
+ objectName: "mscoTwo"
+ boolListProperty: msco.intListProperty
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.bindings.qml b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.bindings.qml
new file mode 100644
index 0000000000..8d83e9f9f5
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.bindings.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: root
+ objectName: "root"
+
+ MySequenceConversionObject {
+ id: msco
+ objectName: "msco"
+ intListProperty: [ 1, 2, 3, 6, 7 ]
+ }
+
+ MySequenceConversionObject {
+ id: mscoTwo
+ objectName: "mscoTwo"
+ intListProperty: msco.intListProperty
+ }
+
+ property variant boundSequence: msco.intListProperty
+ property int boundElement: msco.intListProperty[3]
+ property variant boundSequenceTwo: mscoTwo.intListProperty
+
+ Component.onCompleted: {
+ msco.intListProperty[3] = 12;
+ mscoTwo.intListProperty[4] = 14;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.copy.qml b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.copy.qml
new file mode 100644
index 0000000000..f6614dad0c
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.copy.qml
@@ -0,0 +1,160 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: root
+ objectName: "root"
+
+ MySequenceConversionObject {
+ id: msco
+ objectName: "msco"
+ }
+
+ property bool success: true
+
+ property variant intList
+ property variant qrealList
+ property variant boolList
+ property variant stringList
+ property variant urlList
+ property variant qstringList
+
+ // this test ensures that the "copy resource" codepaths work
+ function testCopySequences() {
+ success = true;
+
+ // create "copy resource" sequences
+ var jsIntList = msco.generateIntSequence();
+ var jsQrealList = msco.generateQrealSequence();
+ var jsBoolList = msco.generateBoolSequence();
+ var jsStringList = msco.generateStringSequence();
+ var jsUrlList = msco.generateUrlSequence();
+ var jsQStringList = msco.generateQStringSequence();
+
+ if (jsIntList.toString() != [1, 2, 3].toString())
+ success = false;
+ if (jsQrealList.toString() != [1.1, 2.2, 3.3].toString())
+ success = false;
+ if (jsBoolList.toString() != [true, false, true].toString())
+ success = false;
+ if (jsStringList.toString() != ["one", "two", "three"].toString())
+ success = false;
+ if (jsUrlList.toString() != ["http://www.example1.com", "http://www.example2.com", "http://www.example3.com"].toString())
+ success = false;
+ if (jsQStringList.toString() != ["one", "two", "three"].toString())
+ success = false;
+
+ // copy the sequence; should result in a new copy
+ intList = jsIntList;
+ qrealList = jsQrealList;
+ boolList = jsBoolList;
+ stringList = jsStringList;
+ urlList = jsUrlList;
+ qstringList = jsQStringList;
+
+ // these operations shouldn't modify either variables - because
+ // we don't handle writing to the intermediate variant at list[index]
+ // for variant properties.
+ intList[1] = 8;
+ qrealList[1] = 8.8;
+ boolList[1] = true;
+ stringList[1] = "eight";
+ urlList[1] = "http://www.example8.com";
+ qstringList[1] = "eight";
+
+ if (jsIntList[1] == 8)
+ success = false;
+ if (jsQrealList[1] == 8.8)
+ success = false;
+ if (jsBoolList[1] == true)
+ success = false;
+ if (jsStringList[1] == "eight")
+ success = false;
+ if (jsUrlList[1] == "http://www.example8.com")
+ success = false;
+ if (jsQStringList[1] == "eight")
+ success = false;
+
+ // assign a "copy resource" sequence to a QObject Q_PROPERTY
+ msco.intListProperty = intList;
+ msco.qrealListProperty = qrealList;
+ msco.boolListProperty = boolList;
+ msco.stringListProperty = stringList;
+ msco.urlListProperty = urlList;
+ msco.qstringListProperty = qstringList;
+
+ if (msco.intListProperty.toString() != [1, 2, 3].toString())
+ success = false;
+ if (msco.qrealListProperty.toString() != [1.1, 2.2, 3.3].toString())
+ success = false;
+ if (msco.boolListProperty.toString() != [true, false, true].toString())
+ success = false;
+ if (msco.stringListProperty.toString() != ["one", "two", "three"].toString())
+ success = false;
+ if (msco.urlListProperty.toString() != ["http://www.example1.com", "http://www.example2.com", "http://www.example3.com"].toString())
+ success = false;
+ if (msco.qstringListProperty.toString() != ["one", "two", "three"].toString())
+ success = false;
+
+ // now modify the QObject Q_PROPERTY (reference resource) sequences - shouldn't modify the copy resource sequences.
+ msco.intListProperty[2] = 9;
+ msco.qrealListProperty[2] = 9.9;
+ msco.boolListProperty[2] = false;
+ msco.stringListProperty[2] = "nine";
+ msco.urlListProperty[2] = "http://www.example9.com";
+ msco.qstringListProperty[2] = "nine";
+
+ if (intList[2] == 9)
+ success = false;
+ if (qrealList[2] == 9.9)
+ success = false;
+ if (boolList[2] == false)
+ success = false;
+ if (stringList[2] == "nine")
+ success = false;
+ if (urlList[2] == "http://www.example9.com")
+ success = false;
+ if (qstringList[2] == "nine")
+ success = false;
+ }
+
+ property int intVal
+ property real qrealVal
+ property bool boolVal
+ property string stringVal
+
+ // this test ensures that indexed access works for copy resource sequences.
+ function readSequenceCopyElements() {
+ success = true;
+
+ var jsIntList = msco.generateIntSequence();
+ var jsQrealList = msco.generateQrealSequence();
+ var jsBoolList = msco.generateBoolSequence();
+ var jsStringList = msco.generateStringSequence();
+
+ intVal = jsIntList[1];
+ qrealVal = jsQrealList[1];
+ boolVal = jsBoolList[1];
+ stringVal = jsStringList[1];
+
+ if (intVal != 2)
+ success = false;
+ if (qrealVal != 2.2)
+ success = false;
+ if (boolVal != false)
+ success = false;
+ if (stringVal != "two")
+ success = false;
+ }
+
+ // this test ensures that equality works for copy resource sequences.
+ function testEqualitySemantics() {
+ success = true;
+
+ var jsIntList = msco.generateIntSequence();
+ var jsIntList2 = msco.generateIntSequence();
+
+ if (jsIntList == jsIntList2) success = false;
+ if (jsIntList != jsIntList) success = false;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.read.error.qml b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.read.error.qml
new file mode 100644
index 0000000000..12a76d7e7d
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.read.error.qml
@@ -0,0 +1,21 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: root
+ objectName: "root"
+
+ MySequenceConversionObject {
+ id: msco
+ objectName: "msco"
+ }
+
+ property int pointListLength: 0
+ property variant pointList
+
+ function performTest() {
+ // we have NOT registered QList<QPoint> as a type
+ pointListLength = msco.pointListProperty.length;
+ pointList = msco.pointListProperty;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.read.qml b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.read.qml
new file mode 100644
index 0000000000..4a8a4a17b2
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.read.qml
@@ -0,0 +1,105 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: root
+ objectName: "root"
+
+ MySequenceConversionObject {
+ id: msco
+ objectName: "msco"
+ }
+
+ property int intListLength: 0
+ property variant intList
+ property int qrealListLength: 0
+ property variant qrealList
+ property int boolListLength: 0
+ property variant boolList
+ property int stringListLength: 0
+ property variant stringList
+ property int urlListLength: 0
+ property variant urlList
+ property int qstringListLength: 0
+ property variant qstringList
+
+ function readSequences() {
+ intListLength = msco.intListProperty.length;
+ intList = msco.intListProperty;
+ qrealListLength = msco.qrealListProperty.length;
+ qrealList = msco.qrealListProperty;
+ boolListLength = msco.boolListProperty.length;
+ boolList = msco.boolListProperty;
+ stringListLength = msco.stringListProperty.length;
+ stringList = msco.stringListProperty;
+ urlListLength = msco.urlListProperty.length;
+ urlList = msco.urlListProperty;
+ qstringListLength = msco.qstringListProperty.length;
+ qstringList = msco.qstringListProperty;
+ }
+
+ property int intVal
+ property real qrealVal
+ property bool boolVal
+ property string stringVal
+ property url urlVal
+ property string qstringVal
+
+ function readSequenceElements() {
+ intVal = msco.intListProperty[1];
+ qrealVal = msco.qrealListProperty[1];
+ boolVal = msco.boolListProperty[1];
+ stringVal = msco.stringListProperty[1];
+ urlVal = msco.urlListProperty[1];
+ qstringVal = msco.qstringListProperty[1];
+ }
+
+ property bool enumerationMatches
+ function enumerateSequenceElements() {
+ var jsIntList = [1, 2, 3, 4, 5];
+ msco.intListProperty = [1, 2, 3, 4, 5];
+
+ var jsIntListProps = []
+ var seqIntListProps = []
+
+ enumerationMatches = true;
+ for (var i in jsIntList) {
+ jsIntListProps.push(i);
+ if (jsIntList[i] != msco.intListProperty[i]) {
+ enumerationMatches = false;
+ }
+ }
+ for (var j in msco.intListProperty) {
+ seqIntListProps.push(j);
+ if (jsIntList[j] != msco.intListProperty[j]) {
+ enumerationMatches = false;
+ }
+ }
+
+ if (jsIntListProps.length != seqIntListProps.length) {
+ enumerationMatches = false;
+ }
+
+ var emptyList = [];
+ msco.stringListProperty = []
+ if (emptyList.toString() != msco.stringListProperty.toString()) {
+ enumerationMatches = false;
+ }
+ if (emptyList.valueOf() != msco.stringListProperty.valueOf()) {
+ enumerationMatches = false;
+ }
+ }
+
+ property bool referenceDeletion: false
+ function testReferenceDeletion() {
+ referenceDeletion = true;
+ var testObj = msco.generateTestObject();
+ testObj.intListProperty = [1, 2, 3, 4, 5];
+ var testSequence = testObj.intListProperty;
+ if (testSequence[4] != 5)
+ referenceDeletion = false;
+ msco.deleteTestObject(testObj); // delete referenced object.
+ if (testSequence[4] == 5)
+ referenceDeletion = false;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.threads.qml b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.threads.qml
new file mode 100644
index 0000000000..aefad89ca4
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.threads.qml
@@ -0,0 +1,74 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: root
+ objectName: "root"
+
+ MySequenceConversionObject {
+ id: msco
+ objectName: "msco"
+ }
+
+ property bool success: false
+ property bool finished: false
+
+ function testIntSequence() {
+ msco.intListProperty = [ 0, 1, 2, 3, 4, 5, 6, 7 ];
+ worker.sendSequence(msco.intListProperty);
+ }
+
+ function testQrealSequence() {
+ msco.qrealListProperty = [ 0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1 ];
+ worker.sendSequence(msco.qrealListProperty);
+ }
+
+ function testBoolSequence() {
+ msco.boolListProperty = [ false, true, true, false, false, true, false, true ];
+ worker.sendSequence(msco.boolListProperty);
+ }
+
+ function testStringSequence() {
+ msco.stringListProperty = [ "one", "two", "three", "four" ];
+ worker.sendSequence(msco.stringListProperty);
+ }
+
+ function testQStringSequence() {
+ msco.qstringListProperty = [ "one", "two", "three", "four" ];
+ worker.sendSequence(msco.qstringListProperty);
+ }
+
+ function testUrlSequence() {
+ msco.urlListProperty = [ "www.example1.com", "www.example2.com", "www.example3.com", "www.example4.com" ];
+ worker.sendSequence(msco.urlListProperty);
+ }
+
+ function testVariantSequence() {
+ msco.variantListProperty = [ "one", true, 3, "four" ];
+ worker.sendSequence(msco.variantListProperty);
+ }
+
+ WorkerScript {
+ id: worker
+ source: "threadScript.js"
+
+ property variant expected
+ property variant response
+
+ function sendSequence(seq) {
+ root.success = false;
+ root.finished = false;
+ worker.expected = seq;
+ worker.sendMessage(seq);
+ }
+
+ onMessage: {
+ worker.response = messageObject;
+ if (worker.response.toString() == worker.expected.toString())
+ root.success = true;
+ else
+ root.success = false;
+ root.finished = true;
+ }
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.write.error.qml b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.write.error.qml
new file mode 100644
index 0000000000..75beafd1ee
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.write.error.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: root
+ objectName: "root"
+
+ MySequenceConversionObject {
+ id: msco
+ objectName: "msco"
+ }
+
+ function performTest() {
+ // we have NOT registered QList<QPoint> as a type
+ var pointList = [ Qt.point(7,7), Qt.point(8,8), Qt.point(9,9) ];
+ msco.pointListProperty = pointList; // error.
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.write.qml b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.write.qml
new file mode 100644
index 0000000000..812de043b7
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/sequenceConversion.write.qml
@@ -0,0 +1,109 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: root
+ objectName: "root"
+
+ MySequenceConversionObject {
+ id: msco
+ objectName: "msco"
+ }
+
+ property bool success
+
+ function writeSequences() {
+ success = true;
+
+ var intList = [ 9, 8, 7, 6 ];
+ msco.intListProperty = intList;
+ var qrealList = [ 9.9, 8.8, 7.7, 6.6 ];
+ msco.qrealListProperty = qrealList;
+ var boolList = [ false, false, false, true ];
+ msco.boolListProperty = boolList;
+ var stringList = [ "nine", "eight", "seven", "six" ]
+ msco.stringListProperty = stringList;
+ var urlList = [ "http://www.example9.com", "http://www.example8.com", "http://www.example7.com", "http://www.example6.com" ]
+ msco.urlListProperty = urlList;
+ var qstringList = [ "nine", "eight", "seven", "six" ]
+ msco.qstringListProperty = qstringList;
+
+ if (msco.intListProperty[0] != 9 || msco.intListProperty[1] != 8 || msco.intListProperty[2] != 7 || msco.intListProperty[3] != 6)
+ success = false;
+ if (msco.qrealListProperty[0] != 9.9 || msco.qrealListProperty[1] != 8.8 || msco.qrealListProperty[2] != 7.7 || msco.qrealListProperty[3] != 6.6)
+ success = false;
+ if (msco.boolListProperty[0] != false || msco.boolListProperty[1] != false || msco.boolListProperty[2] != false || msco.boolListProperty[3] != true)
+ success = false;
+ if (msco.stringListProperty[0] != "nine" || msco.stringListProperty[1] != "eight" || msco.stringListProperty[2] != "seven" || msco.stringListProperty[3] != "six")
+ success = false;
+ if (msco.urlListProperty[0] != "http://www.example9.com" || msco.urlListProperty[1] != "http://www.example8.com" || msco.urlListProperty[2] != "http://www.example7.com" || msco.urlListProperty[3] != "http://www.example6.com")
+ success = false;
+ if (msco.qstringListProperty[0] != "nine" || msco.qstringListProperty[1] != "eight" || msco.qstringListProperty[2] != "seven" || msco.qstringListProperty[3] != "six")
+ success = false;
+ }
+
+ function writeSequenceElements() {
+ // set up initial conditions.
+ writeSequences();
+ success = true;
+
+ // element set.
+ msco.intListProperty[3] = 2;
+ msco.qrealListProperty[3] = 2.2;
+ msco.boolListProperty[3] = false;
+ msco.stringListProperty[3] = "changed";
+ msco.urlListProperty[3] = "http://www.examplechanged.com";
+ msco.qstringListProperty[3] = "changed";
+
+ if (msco.intListProperty[0] != 9 || msco.intListProperty[1] != 8 || msco.intListProperty[2] != 7 || msco.intListProperty[3] != 2)
+ success = false;
+ if (msco.qrealListProperty[0] != 9.9 || msco.qrealListProperty[1] != 8.8 || msco.qrealListProperty[2] != 7.7 || msco.qrealListProperty[3] != 2.2)
+ success = false;
+ if (msco.boolListProperty[0] != false || msco.boolListProperty[1] != false || msco.boolListProperty[2] != false || msco.boolListProperty[3] != false)
+ success = false;
+ if (msco.stringListProperty[0] != "nine" || msco.stringListProperty[1] != "eight" || msco.stringListProperty[2] != "seven" || msco.stringListProperty[3] != "changed")
+ success = false;
+ if (msco.urlListProperty[0] != "http://www.example9.com" || msco.urlListProperty[1] != "http://www.example8.com" || msco.urlListProperty[2] != "http://www.example7.com" || msco.urlListProperty[3] != "http://www.examplechanged.com")
+ success = false;
+ if (msco.qstringListProperty[0] != "nine" || msco.qstringListProperty[1] != "eight" || msco.qstringListProperty[2] != "seven" || msco.qstringListProperty[3] != "changed")
+ success = false;
+ }
+
+ function writeOtherElements() {
+ success = true;
+ var jsIntList = [1, 2, 3, 4, 5];
+ msco.intListProperty = [1, 2, 3, 4, 5];
+
+ jsIntList[8] = 8;
+ msco.intListProperty[8] = 8;
+ if (jsIntList[8] != msco.intListProperty[8])
+ success = false;
+ if (jsIntList.length != msco.intListProperty.length)
+ success = false;
+
+ // NOTE: we can't exactly match the spec here -- we fill the sequence with a default (rather than empty) value
+ if (msco.intListProperty[5] != 0 || msco.intListProperty[6] != 0 || msco.intListProperty[7] != 0)
+ success = false;
+
+ // should have no effect
+ var currLength = jsIntList.length;
+ jsIntList.someThing = 9;
+ msco.intListProperty.someThing = 9;
+ if (msco.intListProperty.length != currLength)
+ success = false;
+ }
+
+ property bool referenceDeletion: false
+ function testReferenceDeletion() {
+ referenceDeletion = true;
+ var testObj = msco.generateTestObject();
+ testObj.intListProperty = [1, 2, 3, 4, 5];
+ var testSequence = testObj.intListProperty;
+ if (testSequence[4] != 5)
+ referenceDeletion = false;
+ msco.deleteTestObject(testObj); // delete referenced object.
+ testSequence[4] = 5; // shouldn't work, since referenced object no longer exists.
+ if (testSequence[4] == 5)
+ referenceDeletion = false;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/threadScript.js b/tests/auto/declarative/qdeclarativeecmascript/data/threadScript.js
new file mode 100644
index 0000000000..9f94de1bc1
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/threadScript.js
@@ -0,0 +1,4 @@
+WorkerScript.onMessage = function(msg) {
+ WorkerScript.sendMessage(msg);
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/typeOf.js b/tests/auto/declarative/qdeclarativeecmascript/data/typeOf.js
new file mode 100644
index 0000000000..16a34234c0
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/typeOf.js
@@ -0,0 +1,25 @@
+var test1 = typeof a
+
+var b = {}
+var test2 = typeof b
+
+var c = 5
+var test3 = typeof c
+
+var d = "hello world"
+var test4 = typeof d
+
+var e = function() {}
+var test5 = typeof e
+
+var f = null
+var test6 = typeof f
+
+var g = undefined
+var test7 = typeof g
+
+var h = true
+var test8 = typeof h
+
+var i = []
+var test9 = typeof i
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/typeOf.qml b/tests/auto/declarative/qdeclarativeecmascript/data/typeOf.qml
new file mode 100644
index 0000000000..28f7debed5
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/typeOf.qml
@@ -0,0 +1,26 @@
+import QtQuick 2.0
+import "typeOf.js" as TypeOf
+
+QtObject {
+ property string test1
+ property string test2
+ property string test3
+ property string test4
+ property string test5
+ property string test6
+ property string test7
+ property string test8
+ property string test9
+
+ Component.onCompleted: {
+ test1 = TypeOf.test1
+ test2 = TypeOf.test2
+ test3 = TypeOf.test3
+ test4 = TypeOf.test4
+ test5 = TypeOf.test5
+ test6 = TypeOf.test6
+ test7 = TypeOf.test7
+ test8 = TypeOf.test8
+ test9 = TypeOf.test9
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp
index 513705d697..721c719911 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp
@@ -101,6 +101,12 @@ public:
void setWidth(int) { }
};
+void MyQmlObject::v8function(QDeclarativeV8Function *args)
+{
+ const char *error = "Exception thrown from within QObject slot";
+ v8::ThrowException(v8::Exception::Error(v8::String::New(error)));
+}
+
static QJSValue script_api(QDeclarativeEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
@@ -161,6 +167,7 @@ void registerTypes()
qmlRegisterExtendedType<DefaultPropertyExtendedObject, DefaultPropertyExtensionObject>("Qt.test", 1,0, "DefaultPropertyExtendedObject");
qmlRegisterType<OverrideDefaultPropertyObject>("Qt.test", 1,0, "OverrideDefaultPropertyObject");
qmlRegisterType<MyRevisionedClass>("Qt.test",1,0,"MyRevisionedClass");
+ qmlRegisterType<MyDeleteObject>("Qt.test", 1,0, "MyDeleteObject");
qmlRegisterType<MyRevisionedClass,1>("Qt.test",1,1,"MyRevisionedClass");
// test scarce resource property binding post-evaluation optimisation
@@ -196,6 +203,8 @@ void registerTypes()
qmlRegisterType<MyDynamicCreationDestructionObject>("Qt.test", 1, 0, "MyDynamicCreationDestructionObject");
qmlRegisterType<WriteCounter>("Qt.test", 1, 0, "WriteCounter");
+
+ qmlRegisterType<MySequenceConversionObject>("Qt.test", 1, 0, "MySequenceConversionObject");
}
#include "testtypes.moc"
diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
index 7684ddd438..06cc561c7f 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
+++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
@@ -59,6 +59,7 @@
#include <private/qv8gccallback_p.h>
#include <private/qdeclarativeengine_p.h>
+#include <private/qv8engine_p.h>
class MyQmlAttachedObject : public QObject
{
@@ -184,6 +185,7 @@ public slots:
void setString(const QString &s) { m_string = s; }
void myinvokable(MyQmlObject *o) { myinvokableObject = o; }
void variantMethod(const QVariant &v) { m_variant = v; }
+ void v8function(QDeclarativeV8Function*);
private:
friend class tst_qdeclarativeecmascript;
@@ -1148,6 +1150,113 @@ private:
int m_count;
};
+class MySequenceConversionObject : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY (QList<int> intListProperty READ intListProperty WRITE setIntListProperty NOTIFY intListPropertyChanged)
+ Q_PROPERTY (QList<int> intListProperty2 READ intListProperty2 WRITE setIntListProperty2 NOTIFY intListProperty2Changed)
+ Q_PROPERTY (QList<qreal> qrealListProperty READ qrealListProperty WRITE setQrealListProperty NOTIFY qrealListPropertyChanged)
+ Q_PROPERTY (QList<bool> boolListProperty READ boolListProperty WRITE setBoolListProperty NOTIFY boolListPropertyChanged)
+ Q_PROPERTY (QList<QString> stringListProperty READ stringListProperty WRITE setStringListProperty NOTIFY stringListPropertyChanged)
+ Q_PROPERTY (QList<QUrl> urlListProperty READ urlListProperty WRITE setUrlListProperty NOTIFY urlListPropertyChanged)
+ Q_PROPERTY (QStringList qstringListProperty READ qstringListProperty WRITE setQStringListProperty NOTIFY qstringListPropertyChanged)
+
+ Q_PROPERTY (QList<QPoint> pointListProperty READ pointListProperty WRITE setPointListProperty NOTIFY pointListPropertyChanged)
+ Q_PROPERTY (QList<QVariant> variantListProperty READ variantListProperty WRITE setVariantListProperty NOTIFY variantListPropertyChanged)
+
+public:
+ MySequenceConversionObject()
+ {
+ m_intList << 1 << 2 << 3 << 4;
+ m_intList2 << 1 << 2 << 3 << 4;
+ m_qrealList << 1.1 << 2.2 << 3.3 << 4.4;
+ m_boolList << true << false << true << false;
+ m_stringList << QLatin1String("first") << QLatin1String("second") << QLatin1String("third") << QLatin1String("fourth");
+ m_urlList << QUrl("http://www.example1.com") << QUrl("http://www.example2.com") << QUrl("http://www.example3.com");
+ m_qstringList << QLatin1String("first") << QLatin1String("second") << QLatin1String("third") << QLatin1String("fourth");
+
+ m_pointList << QPoint(1, 2) << QPoint(3, 4) << QPoint(5, 6);
+ m_variantList << QVariant(QLatin1String("one")) << QVariant(true) << QVariant(3);
+ }
+
+ ~MySequenceConversionObject() {}
+
+ QList<int> intListProperty() const { return m_intList; }
+ void setIntListProperty(const QList<int> &list) { m_intList = list; emit intListPropertyChanged(); }
+ QList<int> intListProperty2() const { return m_intList2; }
+ void setIntListProperty2(const QList<int> &list) { m_intList2 = list; emit intListProperty2Changed(); }
+ QList<qreal> qrealListProperty() const { return m_qrealList; }
+ void setQrealListProperty(const QList<qreal> &list) { m_qrealList = list; emit qrealListPropertyChanged(); }
+ QList<bool> boolListProperty() const { return m_boolList; }
+ void setBoolListProperty(const QList<bool> &list) { m_boolList = list; emit boolListPropertyChanged(); }
+ QList<QString> stringListProperty() const { return m_stringList; }
+ void setStringListProperty(const QList<QString> &list) { m_stringList = list; emit stringListPropertyChanged(); }
+ QList<QUrl> urlListProperty() const { return m_urlList; }
+ void setUrlListProperty(const QList<QUrl> &list) { m_urlList = list; emit urlListPropertyChanged(); }
+ QStringList qstringListProperty() const { return m_qstringList; }
+ void setQStringListProperty(const QStringList &list) { m_qstringList = list; emit qstringListPropertyChanged(); }
+ QList<QPoint> pointListProperty() const { return m_pointList; }
+ void setPointListProperty(const QList<QPoint> &list) { m_pointList = list; emit pointListPropertyChanged(); }
+ QList<QVariant> variantListProperty() const { return m_variantList; }
+ void setVariantListProperty(const QList<QVariant> &list) { m_variantList = list; emit variantListPropertyChanged(); }
+
+ // now for "copy resource" sequences:
+ Q_INVOKABLE QList<int> generateIntSequence() const { QList<int> retn; retn << 1 << 2 << 3; return retn; }
+ Q_INVOKABLE QList<qreal> generateQrealSequence() const { QList<qreal> retn; retn << 1.1 << 2.2 << 3.3; return retn; }
+ Q_INVOKABLE QList<bool> generateBoolSequence() const { QList<bool> retn; retn << true << false << true; return retn; }
+ Q_INVOKABLE QList<QString> generateStringSequence() const { QList<QString> retn; retn << "one" << "two" << "three"; return retn; }
+ Q_INVOKABLE QList<QUrl> generateUrlSequence() const { QList<QUrl> retn; retn << QUrl("http://www.example1.com") << QUrl("http://www.example2.com") << QUrl("http://www.example3.com"); return retn; }
+ Q_INVOKABLE QStringList generateQStringSequence() const { QStringList retn; retn << "one" << "two" << "three"; return retn; }
+
+ // "reference resource" underlying qobject deletion test:
+ Q_INVOKABLE MySequenceConversionObject *generateTestObject() const { return new MySequenceConversionObject; }
+ Q_INVOKABLE void deleteTestObject(QObject *object) const { delete object; }
+
+signals:
+ void intListPropertyChanged();
+ void intListProperty2Changed();
+ void qrealListPropertyChanged();
+ void boolListPropertyChanged();
+ void stringListPropertyChanged();
+ void urlListPropertyChanged();
+ void qstringListPropertyChanged();
+ void pointListPropertyChanged();
+ void variantListPropertyChanged();
+
+private:
+ QList<int> m_intList;
+ QList<int> m_intList2;
+ QList<qreal> m_qrealList;
+ QList<bool> m_boolList;
+ QList<QString> m_stringList;
+ QList<QUrl> m_urlList;
+ QStringList m_qstringList;
+
+ QList<QPoint> m_pointList; // not a supported sequence type
+ QList<QVariant> m_variantList; // not a supported sequence type, but QVariantList support is hardcoded.
+};
+
+class MyDeleteObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QObject *nestedObject READ nestedObject NOTIFY nestedObjectChanged);
+ Q_PROPERTY(int deleteNestedObject READ deleteNestedObject NOTIFY deleteNestedObjectChanged);
+
+public:
+ MyDeleteObject() : m_nestedObject(new MyQmlObject) {}
+
+ QObject *nestedObject() const { return m_nestedObject; }
+ int deleteNestedObject() { delete m_nestedObject; m_nestedObject = 0; return 1; }
+
+signals:
+ void nestedObjectChanged();
+ void deleteNestedObjectChanged();
+
+private:
+ MyQmlObject *m_nestedObject;
+};
+
void registerTypes();
#endif // TESTTYPES_H
diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
index 40072c9e60..492ed739b2 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
@@ -51,6 +51,7 @@
#include <private/qdeclarativeengine_p.h>
#include <private/qv8gccallback_p.h>
#include <private/qdeclarativevmemetaobject_p.h>
+#include <private/qv4compiler_p.h>
#include "testtypes.h"
#include "testhttpserver.h"
#include "../shared/util.h"
@@ -169,6 +170,13 @@ private slots:
void booleanConversion();
void handleReferenceManagement();
void stringArg();
+ void readonlyDeclaration();
+ void sequenceConversionRead();
+ void sequenceConversionWrite();
+ void sequenceConversionArray();
+ void sequenceConversionThreads();
+ void sequenceConversionBindings();
+ void sequenceConversionCopy();
void bug1();
void bug2();
@@ -195,6 +203,7 @@ private slots:
void nonscriptable();
void deleteLater();
void in();
+ void typeOf();
void sharedAttachedObject();
void objectName();
void writeRemovesBinding();
@@ -207,11 +216,13 @@ private slots:
void include();
void signalHandlers();
void doubleEvaluate();
-
+ void forInLoop();
+ void nonNotifyable();
+ void deleteWhileBindingRunning();
void callQtInvokables();
void invokableObjectArg();
void invokableObjectRet();
-
+ void qtbug_20344();
void revisionErrors();
void revision();
@@ -1579,7 +1590,8 @@ void tst_qdeclarativeecmascript::shutdownErrors()
void tst_qdeclarativeecmascript::compositePropertyType()
{
QDeclarativeComponent component(&engine, TEST_FILE("compositePropertyType.qml"));
- QTest::ignoreMessage(QtDebugMsg, "hello world");
+ QString messageFormat = QString(QLatin1String("hello world (%1:%2)")).arg(TEST_FILE("compositePropertyType.qml").toString()).arg(7);
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(messageFormat));
QObject *object = qobject_cast<QObject *>(component.create());
delete object;
}
@@ -4034,6 +4046,248 @@ void tst_qdeclarativeecmascript::stringArg()
delete object;
}
+void tst_qdeclarativeecmascript::readonlyDeclaration()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("readonlyDeclaration.qml"));
+
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toBool(), true);
+
+ delete object;
+}
+
+Q_DECLARE_METATYPE(QList<int>)
+Q_DECLARE_METATYPE(QList<qreal>)
+Q_DECLARE_METATYPE(QList<bool>)
+Q_DECLARE_METATYPE(QList<QString>)
+Q_DECLARE_METATYPE(QList<QUrl>)
+void tst_qdeclarativeecmascript::sequenceConversionRead()
+{
+ {
+ QUrl qmlFile = TEST_FILE("sequenceConversion.read.qml");
+ QDeclarativeComponent component(&engine, qmlFile);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ MySequenceConversionObject *seq = object->findChild<MySequenceConversionObject*>("msco");
+ QVERIFY(seq != 0);
+
+ QMetaObject::invokeMethod(object, "readSequences");
+ QList<int> intList; intList << 1 << 2 << 3 << 4;
+ QCOMPARE(object->property("intListLength").toInt(), intList.length());
+ QCOMPARE(object->property("intList").value<QList<int> >(), intList);
+ QList<qreal> qrealList; qrealList << 1.1 << 2.2 << 3.3 << 4.4;
+ QCOMPARE(object->property("qrealListLength").toInt(), qrealList.length());
+ QCOMPARE(object->property("qrealList").value<QList<qreal> >(), qrealList);
+ QList<bool> boolList; boolList << true << false << true << false;
+ QCOMPARE(object->property("boolListLength").toInt(), boolList.length());
+ QCOMPARE(object->property("boolList").value<QList<bool> >(), boolList);
+ QList<QString> stringList; stringList << QLatin1String("first") << QLatin1String("second") << QLatin1String("third") << QLatin1String("fourth");
+ QCOMPARE(object->property("stringListLength").toInt(), stringList.length());
+ QCOMPARE(object->property("stringList").value<QList<QString> >(), stringList);
+ QList<QUrl> urlList; urlList << QUrl("http://www.example1.com") << QUrl("http://www.example2.com") << QUrl("http://www.example3.com");
+ QCOMPARE(object->property("urlListLength").toInt(), urlList.length());
+ QCOMPARE(object->property("urlList").value<QList<QUrl> >(), urlList);
+ QStringList qstringList; qstringList << QLatin1String("first") << QLatin1String("second") << QLatin1String("third") << QLatin1String("fourth");
+ QCOMPARE(object->property("qstringListLength").toInt(), qstringList.length());
+ QCOMPARE(object->property("qstringList").value<QStringList>(), qstringList);
+
+ QMetaObject::invokeMethod(object, "readSequenceElements");
+ QCOMPARE(object->property("intVal").toInt(), 2);
+ QCOMPARE(object->property("qrealVal").toReal(), 2.2);
+ QCOMPARE(object->property("boolVal").toBool(), false);
+ QCOMPARE(object->property("stringVal").toString(), QString(QLatin1String("second")));
+ QCOMPARE(object->property("urlVal").toUrl(), QUrl("http://www.example2.com"));
+ QCOMPARE(object->property("qstringVal").toString(), QString(QLatin1String("second")));
+
+ QMetaObject::invokeMethod(object, "enumerateSequenceElements");
+ QCOMPARE(object->property("enumerationMatches").toBool(), true);
+
+ intList.clear(); intList << 1 << 2 << 3 << 4 << 5; // set by the enumerateSequenceElements test.
+ QDeclarativeProperty seqProp(seq, "intListProperty");
+ QCOMPARE(seqProp.read().value<QList<int> >(), intList);
+ QDeclarativeProperty seqProp2(seq, "intListProperty", &engine);
+ QCOMPARE(seqProp2.read().value<QList<int> >(), intList);
+
+ QMetaObject::invokeMethod(object, "testReferenceDeletion");
+ QCOMPARE(object->property("referenceDeletion").toBool(), true);
+
+ delete object;
+ }
+
+ {
+ QUrl qmlFile = TEST_FILE("sequenceConversion.read.error.qml");
+ QDeclarativeComponent component(&engine, qmlFile);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ MySequenceConversionObject *seq = object->findChild<MySequenceConversionObject*>("msco");
+ QVERIFY(seq != 0);
+
+ // we haven't registered QList<QPoint> as a sequence type.
+ QString warningOne = QLatin1String("QMetaProperty::read: Unable to handle unregistered datatype 'QList<QPoint>' for property 'MySequenceConversionObject::pointListProperty'");
+ QString warningTwo = qmlFile.toString() + QLatin1String(":18: TypeError: Cannot read property 'length' of undefined");
+ QTest::ignoreMessage(QtWarningMsg, warningOne.toAscii().constData());
+ QTest::ignoreMessage(QtWarningMsg, warningTwo.toAscii().constData());
+
+ QMetaObject::invokeMethod(object, "performTest");
+
+ // QList<QPoint> has not been registered as a sequence type.
+ QCOMPARE(object->property("pointListLength").toInt(), 0);
+ QVERIFY(!object->property("pointList").isValid());
+ QTest::ignoreMessage(QtWarningMsg, "QMetaProperty::read: Unable to handle unregistered datatype 'QList<QPoint>' for property 'MySequenceConversionObject::pointListProperty'");
+ QDeclarativeProperty seqProp(seq, "pointListProperty", &engine);
+ QVERIFY(!seqProp.read().isValid()); // not a valid/known sequence type
+
+ delete object;
+ }
+}
+
+void tst_qdeclarativeecmascript::sequenceConversionWrite()
+{
+ {
+ QUrl qmlFile = TEST_FILE("sequenceConversion.write.qml");
+ QDeclarativeComponent component(&engine, qmlFile);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ MySequenceConversionObject *seq = object->findChild<MySequenceConversionObject*>("msco");
+ QVERIFY(seq != 0);
+
+ QMetaObject::invokeMethod(object, "writeSequences");
+ QCOMPARE(object->property("success").toBool(), true);
+
+ QMetaObject::invokeMethod(object, "writeSequenceElements");
+ QCOMPARE(object->property("success").toBool(), true);
+
+ QMetaObject::invokeMethod(object, "writeOtherElements");
+ QCOMPARE(object->property("success").toBool(), true);
+
+ QMetaObject::invokeMethod(object, "testReferenceDeletion");
+ QCOMPARE(object->property("referenceDeletion").toBool(), true);
+
+ delete object;
+ }
+
+ {
+ QUrl qmlFile = TEST_FILE("sequenceConversion.write.error.qml");
+ QDeclarativeComponent component(&engine, qmlFile);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ MySequenceConversionObject *seq = object->findChild<MySequenceConversionObject*>("msco");
+ QVERIFY(seq != 0);
+
+ // we haven't registered QList<QPoint> as a sequence type, so writing shouldn't work.
+ QString warningOne = qmlFile.toString() + QLatin1String(":16: Error: Cannot assign QVariantList to void");
+ QTest::ignoreMessage(QtWarningMsg, warningOne.toAscii().constData());
+
+ QMetaObject::invokeMethod(object, "performTest");
+
+ QList<QPoint> pointList; pointList << QPoint(1, 2) << QPoint(3, 4) << QPoint(5, 6); // original values, shouldn't have changed
+ QCOMPARE(seq->pointListProperty(), pointList);
+
+ delete object;
+ }
+}
+
+void tst_qdeclarativeecmascript::sequenceConversionArray()
+{
+ // ensure that in JS the returned sequences act just like normal JS Arrays.
+ QUrl qmlFile = TEST_FILE("sequenceConversion.array.qml");
+ QDeclarativeComponent component(&engine, qmlFile);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ //QMetaObject::invokeMethod(object, "indexedAccess");
+ //QVERIFY(object->property("success").toBool());
+ //QMetaObject::invokeMethod(object, "arrayOperations");
+ //QVERIFY(object->property("success").toBool());
+ QMetaObject::invokeMethod(object, "testEqualitySemantics");
+ QVERIFY(object->property("success").toBool());
+ //QMetaObject::invokeMethod(object, "testReferenceDeletion");
+ //QCOMPARE(object->property("referenceDeletion").toBool(), true);
+ delete object;
+}
+
+void tst_qdeclarativeecmascript::sequenceConversionThreads()
+{
+ // ensure that sequence conversion operations work correctly in a worker thread
+ // and that serialisation between the main and worker thread succeeds.
+ QUrl qmlFile = TEST_FILE("sequenceConversion.threads.qml");
+ QDeclarativeComponent component(&engine, qmlFile);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QMetaObject::invokeMethod(object, "testIntSequence");
+ QTRY_VERIFY(object->property("finished").toBool());
+ QVERIFY(object->property("success").toBool());
+
+ QMetaObject::invokeMethod(object, "testQrealSequence");
+ QTRY_VERIFY(object->property("finished").toBool());
+ QVERIFY(object->property("success").toBool());
+
+ QMetaObject::invokeMethod(object, "testBoolSequence");
+ QTRY_VERIFY(object->property("finished").toBool());
+ QVERIFY(object->property("success").toBool());
+
+ QMetaObject::invokeMethod(object, "testStringSequence");
+ QTRY_VERIFY(object->property("finished").toBool());
+ QVERIFY(object->property("success").toBool());
+
+ QMetaObject::invokeMethod(object, "testQStringSequence");
+ QTRY_VERIFY(object->property("finished").toBool());
+ QVERIFY(object->property("success").toBool());
+
+ QMetaObject::invokeMethod(object, "testUrlSequence");
+ QTRY_VERIFY(object->property("finished").toBool());
+ QVERIFY(object->property("success").toBool());
+
+ QMetaObject::invokeMethod(object, "testVariantSequence");
+ QTRY_VERIFY(object->property("finished").toBool());
+ QVERIFY(object->property("success").toBool());
+
+ delete object;
+}
+
+void tst_qdeclarativeecmascript::sequenceConversionBindings()
+{
+ {
+ QUrl qmlFile = TEST_FILE("sequenceConversion.bindings.qml");
+ QDeclarativeComponent component(&engine, qmlFile);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QList<int> intList; intList << 1 << 2 << 3 << 12 << 7;
+ QCOMPARE(object->property("boundSequence").value<QList<int> >(), intList);
+ QCOMPARE(object->property("boundElement").toInt(), intList.at(3));
+ QList<int> intListTwo; intListTwo << 1 << 2 << 3 << 12 << 14;
+ QCOMPARE(object->property("boundSequenceTwo").value<QList<int> >(), intListTwo);
+ delete object;
+ }
+
+ {
+ QUrl qmlFile = TEST_FILE("sequenceConversion.bindings.error.qml");
+ QString warning = QString(QLatin1String("%1:17: Unable to assign QList<int> to QList<bool>")).arg(qmlFile.toString());
+ QTest::ignoreMessage(QtWarningMsg, warning.toAscii().constData());
+ QDeclarativeComponent component(&engine, qmlFile);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ delete object;
+ }
+}
+
+void tst_qdeclarativeecmascript::sequenceConversionCopy()
+{
+ QUrl qmlFile = TEST_FILE("sequenceConversion.copy.qml");
+ QDeclarativeComponent component(&engine, qmlFile);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QMetaObject::invokeMethod(object, "testCopySequences");
+ QCOMPARE(object->property("success").toBool(), true);
+ QMetaObject::invokeMethod(object, "readSequenceCopyElements");
+ QCOMPARE(object->property("success").toBool(), true);
+ QMetaObject::invokeMethod(object, "testEqualitySemantics");
+ QCOMPARE(object->property("success").toBool(), true);
+ delete object;
+}
+
// Test that assigning a null object works
// Regressed with: df1788b4dbbb2826ae63f26bdf166342595343f4
void tst_qdeclarativeecmascript::nullObjectBinding()
@@ -4109,7 +4363,8 @@ void tst_qdeclarativeecmascript::qtbug_9792()
MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create(context));
QVERIFY(object != 0);
- QTest::ignoreMessage(QtDebugMsg, "Hello world!");
+ QString message = QString(QLatin1String("Hello world! (%1:%2)")).arg(TEST_FILE("qtbug_9792.qml").toString()).arg(4);
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(message));
object->basicSignal();
delete context;
@@ -4511,6 +4766,25 @@ void tst_qdeclarativeecmascript::in()
delete o;
}
+void tst_qdeclarativeecmascript::typeOf()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("typeOf.qml"));
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+ QEXPECT_FAIL("", "QTBUG-21864", Abort);
+ QCOMPARE(o->property("test1").toString(), QLatin1String("undefined"));
+ QCOMPARE(o->property("test2").toString(), QLatin1String("object"));
+ QCOMPARE(o->property("test3").toString(), QLatin1String("number"));
+ QCOMPARE(o->property("test4").toString(), QLatin1String("string"));
+ QCOMPARE(o->property("test5").toString(), QLatin1String("function"));
+ QCOMPARE(o->property("test6").toString(), QLatin1String("object"));
+ QCOMPARE(o->property("test7").toString(), QLatin1String("undefined"));
+ QCOMPARE(o->property("test8").toString(), QLatin1String("boolean"));
+ QCOMPARE(o->property("test9").toString(), QLatin1String("object"));
+
+ delete o;
+}
+
void tst_qdeclarativeecmascript::sharedAttachedObject()
{
QDeclarativeComponent component(&engine, TEST_FILE("sharedAttachedObject.qml"));
@@ -4642,6 +4916,19 @@ void tst_qdeclarativeecmascript::aliasToCompositeElement()
delete object;
}
+void tst_qdeclarativeecmascript::qtbug_20344()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("qtbug_20344.qml"));
+
+ QString warning = component.url().toString() + ":5: Error: Exception thrown from within QObject slot";
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
+
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ delete object;
+}
+
void tst_qdeclarativeecmascript::revisionErrors()
{
{
@@ -4780,6 +5067,67 @@ void tst_qdeclarativeecmascript::doubleEvaluate()
delete object;
}
+static QStringList messages;
+static void captureMsgHandler(QtMsgType, const char *msg)
+{
+ messages.append(QLatin1String(msg));
+}
+
+void tst_qdeclarativeecmascript::nonNotifyable()
+{
+ QV4Compiler::enableV4(false);
+ QDeclarativeComponent component(&engine, TEST_FILE("nonNotifyable.qml"));
+ QV4Compiler::enableV4(true);
+
+ QtMsgHandler old = qInstallMsgHandler(captureMsgHandler);
+ messages.clear();
+ QObject *object = component.create();
+ qInstallMsgHandler(old);
+
+ QVERIFY(object != 0);
+
+ QString expected1 = QLatin1String("QDeclarativeExpression: Expression ") +
+ component.url().toString() +
+ QLatin1String(":5 depends on non-NOTIFYable properties:");
+ QString expected2 = QLatin1String(" ") +
+ QLatin1String(object->metaObject()->className()) +
+ QLatin1String("::value");
+
+ QCOMPARE(messages.length(), 2);
+ QCOMPARE(messages.at(0), expected1);
+ QCOMPARE(messages.at(1), expected2);
+
+ delete object;
+}
+
+void tst_qdeclarativeecmascript::forInLoop()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("forInLoop.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QMetaObject::invokeMethod(object, "listProperty");
+
+ QStringList r = object->property("listResult").toString().split("|", QString::SkipEmptyParts);
+ QCOMPARE(r.size(), 3);
+ QCOMPARE(r[0],QLatin1String("0=obj1"));
+ QCOMPARE(r[1],QLatin1String("1=obj2"));
+ QCOMPARE(r[2],QLatin1String("2=obj3"));
+
+ //TODO: should test for in loop for other objects (such as QObjects) as well.
+
+ delete object;
+}
+
+// An object the binding depends on is deleted while the binding is still running
+void tst_qdeclarativeecmascript::deleteWhileBindingRunning()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("deleteWhileBindingRunning.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ delete object;
+}
+
QTEST_MAIN(tst_qdeclarativeecmascript)
#include "tst_qdeclarativeecmascript.moc"
diff --git a/tests/auto/declarative/qdeclarativeexpression/tst_qdeclarativeexpression.cpp b/tests/auto/declarative/qdeclarativeexpression/tst_qdeclarativeexpression.cpp
index a05c06f23f..a65045b48f 100644
--- a/tests/auto/declarative/qdeclarativeexpression/tst_qdeclarativeexpression.cpp
+++ b/tests/auto/declarative/qdeclarativeexpression/tst_qdeclarativeexpression.cpp
@@ -54,6 +54,7 @@ public:
private slots:
void scriptString();
+ void syntaxError();
};
class TestObject : public QObject
@@ -106,6 +107,15 @@ void tst_qdeclarativeexpression::scriptString()
QCOMPARE(error.line(), 8);
}
+// QTBUG-21310 - crash test
+void tst_qdeclarativeexpression::syntaxError()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeExpression expression(engine.rootContext(), 0, "asd asd");
+ QVariant v = expression.evaluate();
+ QCOMPARE(v, QVariant());
+}
+
QTEST_MAIN(tst_qdeclarativeexpression)
#include "tst_qdeclarativeexpression.moc"
diff --git a/tests/auto/declarative/qdeclarativefontloader/data/qtbug-20268.qml b/tests/auto/declarative/qdeclarativefontloader/data/qtbug-20268.qml
new file mode 100644
index 0000000000..0eafdfa17b
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativefontloader/data/qtbug-20268.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: test
+ property variant fontloader: fontloaderelement
+ height: 100; width: 100
+ property bool usename: false
+ property int statenum: 1
+ property alias name: fontloaderelement.name
+ property alias source: fontloaderelement.source
+ property alias status: fontloaderelement.status
+
+ FontLoader {
+ id: fontloaderelement
+ }
+
+ states: [
+ State { name: "start"; when: !usename
+ PropertyChanges { target: fontloaderelement; source: "tarzeau_ocr_a.ttf" }
+ },
+ State { name: "changefont"; when: usename
+ PropertyChanges { target: fontloaderelement; name: "Tahoma" }
+ }
+ ]
+
+ Text { id: textelement; text: fontloaderelement.name; color: "black" }
+}
diff --git a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp
index 67a040dcf2..9831ac1087 100644
--- a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp
+++ b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp
@@ -46,6 +46,8 @@
#include <QtDeclarative/private/qdeclarativefontloader_p.h>
#include "../shared/util.h"
#include "../../declarative/shared/testhttpserver.h"
+#include <QQuickView>
+#include <QQuickItem>
#define SERVER_PORT 14448
@@ -65,6 +67,7 @@ private slots:
void redirWebFont();
void failWebFont();
void changeFont();
+ void changeFontSourceViaState();
private:
QDeclarativeEngine engine;
@@ -220,6 +223,26 @@ void tst_qdeclarativefontloader::changeFont()
QTRY_COMPARE(fontObject->name(), QString("Daniel"));
}
+void tst_qdeclarativefontloader::changeFontSourceViaState()
+{
+ QQuickView canvas(QUrl::fromLocalFile(TESTDATA("qtbug-20268.qml")));
+ canvas.show();
+ canvas.requestActivateWindow();
+ QTest::qWaitForWindowShown(&canvas);
+ QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
+
+ QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(qvariant_cast<QObject *>(canvas.rootObject()->property("fontloader")));
+ QVERIFY(fontObject != 0);
+ QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready);
+ QVERIFY(fontObject->source() != QUrl(""));
+ QTRY_COMPARE(fontObject->name(), QString("OCRA"));
+
+ canvas.rootObject()->setProperty("usename", true);
+ QEXPECT_FAIL("", "QTBUG-20268", Abort);
+ QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready);
+ QCOMPARE(canvas.rootObject()->property("name").toString(), QString("Tahoma"));
+}
+
QTEST_MAIN(tst_qdeclarativefontloader)
#include "tst_qdeclarativefontloader.moc"
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/chainInCompletion.qml b/tests/auto/declarative/qdeclarativeincubator/data/chainInCompletion.qml
new file mode 100644
index 0000000000..e79fed356a
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/chainInCompletion.qml
@@ -0,0 +1,5 @@
+import Qt.test 1.0
+
+SelfRegistering {
+ property variant a: CompletionCallback {}
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/testtypes.cpp b/tests/auto/declarative/qdeclarativeincubator/testtypes.cpp
index 99d2cb1005..6d6fb38daf 100644
--- a/tests/auto/declarative/qdeclarativeincubator/testtypes.cpp
+++ b/tests/auto/declarative/qdeclarativeincubator/testtypes.cpp
@@ -101,9 +101,37 @@ void CallbackRegisteringType::registerCallback(callback c, void *d)
m_data = d;
}
+CompletionCallbackType::callback CompletionCallbackType::m_callback = 0;
+void *CompletionCallbackType::m_data = 0;
+CompletionCallbackType::CompletionCallbackType()
+{
+}
+
+void CompletionCallbackType::classBegin()
+{
+}
+
+void CompletionCallbackType::componentComplete()
+{
+ if (m_callback) m_callback(this, m_data);
+}
+
+void CompletionCallbackType::clearCallback()
+{
+ m_callback = 0;
+ m_data = 0;
+}
+
+void CompletionCallbackType::registerCallback(callback c, void *d)
+{
+ m_callback = c;
+ m_data = d;
+}
+
void registerTypes()
{
qmlRegisterType<SelfRegisteringType>("Qt.test", 1,0, "SelfRegistering");
qmlRegisterType<CompletionRegisteringType>("Qt.test", 1,0, "CompletionRegistering");
qmlRegisterType<CallbackRegisteringType>("Qt.test", 1,0, "CallbackRegistering");
+ qmlRegisterType<CompletionCallbackType>("Qt.test", 1,0, "CompletionCallback");
}
diff --git a/tests/auto/declarative/qdeclarativeincubator/testtypes.h b/tests/auto/declarative/qdeclarativeincubator/testtypes.h
index 6e732548b2..8d9968de3c 100644
--- a/tests/auto/declarative/qdeclarativeincubator/testtypes.h
+++ b/tests/auto/declarative/qdeclarativeincubator/testtypes.h
@@ -100,6 +100,24 @@ private:
static CompletionRegisteringType *m_me;
};
+class CompletionCallbackType : public QObject, public QDeclarativeParserStatus
+{
+Q_OBJECT
+public:
+ CompletionCallbackType();
+
+ virtual void classBegin();
+ virtual void componentComplete();
+
+ typedef void (*callback)(CompletionCallbackType *, void *);
+ static void clearCallback();
+ static void registerCallback(callback, void *);
+
+private:
+ static callback m_callback;
+ static void *m_data;
+};
+
void registerTypes();
#endif // TESTTYPES_H
diff --git a/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp b/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp
index 684cd35613..54ca622753 100644
--- a/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp
+++ b/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp
@@ -83,6 +83,7 @@ private slots:
void asynchronousIfNested();
void nestedComponent();
void chainedAsynchronousIfNested();
+ void chainedAsynchronousIfNestedOnCompleted();
void selfDelete();
private:
@@ -773,6 +774,134 @@ void tst_qdeclarativeincubator::chainedAsynchronousIfNested()
QVERIFY(incubator2.isReady());
}
+// Checks that new AsynchronousIfNested incubators can be correctly chained if started in
+// componentCompleted().
+void tst_qdeclarativeincubator::chainedAsynchronousIfNestedOnCompleted()
+{
+ SelfRegisteringType::clearMe();
+
+ QDeclarativeComponent component(&engine, TEST_FILE("chainInCompletion.qml"));
+ QVERIFY(component.isReady());
+
+ QDeclarativeComponent c1(&engine, TEST_FILE("chainedAsynchronousIfNested.qml"));
+ QVERIFY(c1.isReady());
+
+ struct MyIncubator : public QDeclarativeIncubator {
+ MyIncubator(MyIncubator *next, QDeclarativeComponent *component, QDeclarativeContext *ctxt)
+ : QDeclarativeIncubator(AsynchronousIfNested), next(next), component(component), ctxt(ctxt) {}
+
+ protected:
+ virtual void statusChanged(Status s) {
+ if (s == Ready && next) {
+ component->create(*next, 0, ctxt);
+ }
+ }
+
+ private:
+ MyIncubator *next;
+ QDeclarativeComponent *component;
+ QDeclarativeContext *ctxt;
+ };
+
+ struct CallbackData {
+ CallbackData(QDeclarativeComponent *c, MyIncubator *i, QDeclarativeContext *ct)
+ : component(c), incubator(i), ctxt(ct) {}
+ QDeclarativeComponent *component;
+ MyIncubator *incubator;
+ QDeclarativeContext *ctxt;
+ static void callback(CompletionCallbackType *o, void *data) {
+ CallbackData *d = (CallbackData *)data;
+ d->component->create(*d->incubator, 0, d->ctxt);
+ }
+ };
+
+ QDeclarativeIncubator incubator(QDeclarativeIncubator::Asynchronous);
+ component.create(incubator);
+
+ QVERIFY(incubator.isLoading());
+ QVERIFY(SelfRegisteringType::me() == 0);
+
+ while (SelfRegisteringType::me() == 0 && incubator.isLoading()) {
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(SelfRegisteringType::me() != 0);
+ QVERIFY(incubator.isLoading());
+
+ MyIncubator incubator3(0, &c1, qmlContext(SelfRegisteringType::me()));
+ MyIncubator incubator2(&incubator3, &c1, qmlContext(SelfRegisteringType::me()));
+ MyIncubator incubator1(&incubator2, &c1, qmlContext(SelfRegisteringType::me()));
+
+ // start incubator1 in componentComplete
+ CallbackData cd(&c1, &incubator1, qmlContext(SelfRegisteringType::me()));
+ CompletionCallbackType::registerCallback(&CallbackData::callback, &cd);
+
+ while (!incubator1.isLoading()) {
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator2.isNull());
+ QVERIFY(incubator3.isNull());
+
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isLoading());
+ QVERIFY(incubator2.isNull());
+ QVERIFY(incubator3.isNull());
+
+ while (incubator1.isLoading()) {
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isLoading());
+ QVERIFY(incubator2.isNull());
+ QVERIFY(incubator3.isNull());
+
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isReady());
+ QVERIFY(incubator2.isLoading());
+ QVERIFY(incubator3.isNull());
+
+ while (incubator2.isLoading()) {
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isReady());
+ QVERIFY(incubator2.isLoading());
+ QVERIFY(incubator3.isNull());
+
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isReady());
+ QVERIFY(incubator2.isReady());
+ QVERIFY(incubator3.isLoading());
+
+ while (incubator3.isLoading()) {
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isReady());
+ QVERIFY(incubator2.isReady());
+ QVERIFY(incubator3.isLoading());
+
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ {
+ bool b = true;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator1.isReady());
+ QVERIFY(incubator2.isReady());
+ QVERIFY(incubator3.isReady());
+}
+
void tst_qdeclarativeincubator::selfDelete()
{
struct MyIncubator : public QDeclarativeIncubator {
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/ReadOnlyType.qml b/tests/auto/declarative/qdeclarativelanguage/data/ReadOnlyType.qml
new file mode 100644
index 0000000000..456ac762fc
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelanguage/data/ReadOnlyType.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+QtObject {
+ readonly property int readOnlyProperty: 19
+}
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/property.5.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/property.5.errors.txt
deleted file mode 100644
index 32a8dc11e1..0000000000
--- a/tests/auto/declarative/qdeclarativelanguage/data/property.5.errors.txt
+++ /dev/null
@@ -1 +0,0 @@
-4:5:Readonly not yet supported
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/property.5.qml b/tests/auto/declarative/qdeclarativelanguage/data/property.5.qml
deleted file mode 100644
index a1401d2fdc..0000000000
--- a/tests/auto/declarative/qdeclarativelanguage/data/property.5.qml
+++ /dev/null
@@ -1,6 +0,0 @@
-import QtQuick 2.0
-
-QtObject {
- readonly property int a: value
-}
-
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/readOnly.5.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/readOnly.5.errors.txt
index baf47667bc..e71ae4447c 100644
--- a/tests/auto/declarative/qdeclarativelanguage/data/readOnly.5.errors.txt
+++ b/tests/auto/declarative/qdeclarativelanguage/data/readOnly.5.errors.txt
@@ -1 +1 @@
-3:27:Invalid property assignment: "readOnlyEnumProperty" is a read-only property
+2:23:Invalid property assignment: "readOnlyProperty" is a read-only property
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/readOnly.5.qml b/tests/auto/declarative/qdeclarativelanguage/data/readOnly.5.qml
index 422d13d8d0..d80b27a1e3 100644
--- a/tests/auto/declarative/qdeclarativelanguage/data/readOnly.5.qml
+++ b/tests/auto/declarative/qdeclarativelanguage/data/readOnly.5.qml
@@ -1,4 +1,3 @@
-import Test 1.0
-MyTypeObject {
- readOnlyEnumProperty: MyTypeObject.EnumValue1
+ReadOnlyType {
+ readOnlyProperty: 13
}
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/readonly.qml b/tests/auto/declarative/qdeclarativelanguage/data/readonly.qml
new file mode 100644
index 0000000000..493a9ad502
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelanguage/data/readonly.qml
@@ -0,0 +1,17 @@
+import Test 1.0
+
+MyQmlObject {
+ property int testData: 9
+ property alias testData2: myObject.test1
+
+ readonly property int test1: 10
+ readonly property int test2: testData + 9
+ readonly property alias test3: myObject.test1
+
+
+ property variant dummy: MyQmlObject {
+ id: myObject
+ property int test1: 13
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
index 538ebbb1a3..a3fb5f0917 100644
--- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
+++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
@@ -156,6 +156,7 @@ private slots:
void inlineAssignmentsOverrideBindings();
void nestedComponentRoots();
void registrationOrder();
+ void readonly();
void basicRemote_data();
void basicRemote();
@@ -364,7 +365,6 @@ void tst_qdeclarativelanguage::errors_data()
QTest::newRow("property.2") << "property.2.qml" << "property.2.errors.txt" << false;
QTest::newRow("property.3") << "property.3.qml" << "property.3.errors.txt" << false;
QTest::newRow("property.4") << "property.4.qml" << "property.4.errors.txt" << false;
- QTest::newRow("property.5") << "property.5.qml" << "property.5.errors.txt" << false;
QTest::newRow("property.6") << "property.6.qml" << "property.6.errors.txt" << false;
QTest::newRow("property.7") << "property.7.qml" << "property.7.errors.txt" << false;
@@ -850,7 +850,8 @@ void tst_qdeclarativelanguage::dynamicObjectProperties()
// Tests the declaration of dynamic signals and slots
void tst_qdeclarativelanguage::dynamicSignalsAndSlots()
{
- QTest::ignoreMessage(QtDebugMsg, "1921");
+ QString message = QString(QLatin1String("1921 (%1:%2)")).arg(TEST_FILE("dynamicSignalsAndSlots.qml").toString()).arg(9);
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(message));
QDeclarativeComponent component(&engine, TEST_FILE("dynamicSignalsAndSlots.qml"));
VERIFY_ERRORS(0);
@@ -1288,9 +1289,10 @@ void tst_qdeclarativelanguage::onCompleted()
{
QDeclarativeComponent component(&engine, TEST_FILE("onCompleted.qml"));
VERIFY_ERRORS(0);
- QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
- QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
- QTest::ignoreMessage(QtDebugMsg, "Completed 10 11");
+ QString formatMessage = QString(QLatin1String("%1 (%2:%3)"));
+ QTest::ignoreMessage(QtDebugMsg, formatMessage.arg(QLatin1String("Completed 6 10")).arg(TEST_FILE("onCompleted.qml").toString()).arg(8).toLatin1());
+ QTest::ignoreMessage(QtDebugMsg, formatMessage.arg(QLatin1String("Completed 6 10")).arg(TEST_FILE("onCompleted.qml").toString()).arg(14).toLatin1());
+ QTest::ignoreMessage(QtDebugMsg, formatMessage.arg(QLatin1String("Completed 10 11")).arg(TEST_FILE("OnCompletedType.qml").toString()).arg(7).toLatin1());
QObject *object = component.create();
QVERIFY(object != 0);
}
@@ -1302,10 +1304,10 @@ void tst_qdeclarativelanguage::onDestruction()
VERIFY_ERRORS(0);
QObject *object = component.create();
QVERIFY(object != 0);
-
- QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
- QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
- QTest::ignoreMessage(QtDebugMsg, "Destruction 10 11");
+ QString formatMessage = QString(QLatin1String("%1 (%2:%3)"));
+ QTest::ignoreMessage(QtDebugMsg, formatMessage.arg(QLatin1String("Destruction 6 10")).arg(TEST_FILE("onDestruction.qml").toString()).arg(8).toLatin1());
+ QTest::ignoreMessage(QtDebugMsg, formatMessage.arg(QLatin1String("Destruction 6 10")).arg(TEST_FILE("onDestruction.qml").toString()).arg(14).toLatin1());
+ QTest::ignoreMessage(QtDebugMsg, formatMessage.arg(QLatin1String("Destruction 10 11")).arg(TEST_FILE("OnDestructionType.qml").toString()).arg(7).toLatin1());
delete object;
}
@@ -2142,6 +2144,40 @@ void tst_qdeclarativelanguage::registrationOrder()
delete o;
}
+void tst_qdeclarativelanguage::readonly()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("readonly.qml"));
+
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+
+ QCOMPARE(o->property("test1").toInt(), 10);
+ QCOMPARE(o->property("test2").toInt(), 18);
+ QCOMPARE(o->property("test3").toInt(), 13);
+
+ o->setProperty("testData", 13);
+
+ QCOMPARE(o->property("test1").toInt(), 10);
+ QCOMPARE(o->property("test2").toInt(), 22);
+ QCOMPARE(o->property("test3").toInt(), 13);
+
+ o->setProperty("testData2", 2);
+
+ QCOMPARE(o->property("test1").toInt(), 10);
+ QCOMPARE(o->property("test2").toInt(), 22);
+ QCOMPARE(o->property("test3").toInt(), 2);
+
+ o->setProperty("test1", 11);
+ o->setProperty("test2", 11);
+ o->setProperty("test3", 11);
+
+ QCOMPARE(o->property("test1").toInt(), 10);
+ QCOMPARE(o->property("test2").toInt(), 22);
+ QCOMPARE(o->property("test3").toInt(), 2);
+
+ delete o;
+}
+
// QTBUG-18268
void tst_qdeclarativelanguage::remoteLoadCrash()
{
diff --git a/tests/auto/declarative/qdeclarativelistcompositor/tst_qdeclarativelistcompositor.cpp b/tests/auto/declarative/qdeclarativelistcompositor/tst_qdeclarativelistcompositor.cpp
index 67bced6da8..425f35cc08 100644
--- a/tests/auto/declarative/qdeclarativelistcompositor/tst_qdeclarativelistcompositor.cpp
+++ b/tests/auto/declarative/qdeclarativelistcompositor/tst_qdeclarativelistcompositor.cpp
@@ -146,6 +146,10 @@ class tst_qdeclarativelistcompositor : public QObject
}
private slots:
+ void find_data();
+ void find();
+ void findInsertPosition_data();
+ void findInsertPosition();
void insert();
void clearFlags_data();
void clearFlags();
@@ -164,6 +168,131 @@ private slots:
void listItemsChanged();
};
+void tst_qdeclarativelistcompositor::find_data()
+{
+ QTest::addColumn<RangeList>("ranges");
+ QTest::addColumn<C::Group>("startGroup");
+ QTest::addColumn<int>("startIndex");
+ QTest::addColumn<C::Group>("group");
+ QTest::addColumn<int>("index");
+ QTest::addColumn<int>("selectionIndex");
+ QTest::addColumn<int>("visibleIndex");
+ QTest::addColumn<int>("defaultIndex");
+ QTest::addColumn<int>("cacheIndex");
+ QTest::addColumn<int>("rangeFlags");
+ QTest::addColumn<int>("rangeIndex");
+
+ int listA; void *a = &listA;
+
+ QTest::newRow("Start")
+ << (RangeList()
+ << Range(a, 0, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 1, 1, int(C::AppendFlag | C::PrependFlag | C::CacheFlag))
+ << Range(0, 0, 1, int(VisibleFlag| C::CacheFlag)))
+ << C::Cache << 2
+ << Selection << 0
+ << 0 << 0 << 0 << 0
+ << int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag) << 0;
+}
+
+void tst_qdeclarativelistcompositor::find()
+{
+ QFETCH(RangeList, ranges);
+ QFETCH(C::Group, startGroup);
+ QFETCH(int, startIndex);
+ QFETCH(C::Group, group);
+ QFETCH(int, index);
+ QFETCH(int, cacheIndex);
+ QFETCH(int, defaultIndex);
+ QFETCH(int, visibleIndex);
+ QFETCH(int, selectionIndex);
+ QFETCH(int, rangeFlags);
+ QFETCH(int, rangeIndex);
+
+ QDeclarativeListCompositor compositor;
+ compositor.setGroupCount(4);
+ compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
+
+ foreach (const Range &range, ranges)
+ compositor.append(range.list, range.index, range.count, range.flags);
+
+ compositor.find(startGroup, startIndex);
+
+ QDeclarativeListCompositor::iterator it = compositor.find(group, index);
+ QCOMPARE(it.index[C::Cache], cacheIndex);
+ QCOMPARE(it.index[C::Default], defaultIndex);
+ QCOMPARE(it.index[Visible], visibleIndex);
+ QCOMPARE(it.index[Selection], selectionIndex);
+ QCOMPARE(it->flags, rangeFlags);
+ QCOMPARE(it->index, rangeIndex);
+}
+
+void tst_qdeclarativelistcompositor::findInsertPosition_data()
+{
+ QTest::addColumn<RangeList>("ranges");
+ QTest::addColumn<C::Group>("startGroup");
+ QTest::addColumn<int>("startIndex");
+ QTest::addColumn<C::Group>("group");
+ QTest::addColumn<int>("index");
+ QTest::addColumn<int>("selectionIndex");
+ QTest::addColumn<int>("visibleIndex");
+ QTest::addColumn<int>("defaultIndex");
+ QTest::addColumn<int>("cacheIndex");
+ QTest::addColumn<int>("rangeFlags");
+ QTest::addColumn<int>("rangeIndex");
+
+ int listA; void *a = &listA;
+
+ QTest::newRow("Start")
+ << (RangeList()
+ << Range(a, 0, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 1, 1, int(C::AppendFlag | C::PrependFlag | C::CacheFlag))
+ << Range(0, 0, 1, int(VisibleFlag| C::CacheFlag)))
+ << C::Cache << 2
+ << Selection << 0
+ << 0 << 0 << 0 << 0
+ << int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag) << 0;
+ QTest::newRow("1")
+ << (RangeList()
+ << Range(a, 0, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 1, 1, int(C::AppendFlag | C::PrependFlag | C::CacheFlag))
+ << Range(0, 0, 1, int(VisibleFlag| C::CacheFlag)))
+ << C::Cache << 2
+ << Selection << 1
+ << 1 << 0 << 1 << 1
+ << int(C::AppendFlag | C::PrependFlag | C::CacheFlag) << 1;
+}
+
+void tst_qdeclarativelistcompositor::findInsertPosition()
+{
+ QFETCH(RangeList, ranges);
+ QFETCH(C::Group, startGroup);
+ QFETCH(int, startIndex);
+ QFETCH(C::Group, group);
+ QFETCH(int, index);
+ QFETCH(int, cacheIndex);
+ QFETCH(int, defaultIndex);
+ QFETCH(int, visibleIndex);
+ QFETCH(int, selectionIndex);
+ QFETCH(int, rangeFlags);
+ QFETCH(int, rangeIndex);
+
+ QDeclarativeListCompositor compositor;
+ compositor.setGroupCount(4);
+ compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
+
+ foreach (const Range &range, ranges)
+ compositor.append(range.list, range.index, range.count, range.flags);
+
+ QDeclarativeListCompositor::insert_iterator it = compositor.findInsertPosition(group, index);
+ QCOMPARE(it.index[C::Cache], cacheIndex);
+ QCOMPARE(it.index[C::Default], defaultIndex);
+ QCOMPARE(it.index[Visible], visibleIndex);
+ QCOMPARE(it.index[Selection], selectionIndex);
+ QCOMPARE(it->flags, rangeFlags);
+ QCOMPARE(it->index, rangeIndex);
+}
+
void tst_qdeclarativelistcompositor::insert()
{
QDeclarativeListCompositor compositor;
@@ -547,6 +676,27 @@ void tst_qdeclarativelistcompositor::setFlags_data()
<< IndexArray(defaultIndexes) << ListArray(defaultLists)
<< IndexArray(visibleIndexes) << ListArray(visibleLists)
<< IndexArray(selectionIndexes) << ListArray(selectionLists);
+ } { static const int cacheIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11};
+ static const void *cacheLists[] = {a,a,a,a,a,a,a,a,a,a, a, a};
+ static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11};
+ static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a};
+ static const int visibleIndexes[] = {0,1,3,4,5,6,7,8,9,10,11};
+ static const void *visibleLists[] = {a,a,a,a,a,a,a,a,a, a, a};
+ static const int selectionIndexes[] = {2,6,7,8,9};
+ static const void *selectionLists[] = {a,a,a,a,a};
+ QTest::newRow("Existing flag, sparse selection")
+ << (RangeList()
+ << Range(a, 0, 2, C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 2, 1, C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 3, 3, C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 6, 4, C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a,10, 2, C::AppendFlag | C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << C::Cache << 3 << 1 << int(VisibleFlag)
+ << InsertList()
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray(visibleIndexes) << ListArray(visibleLists)
+ << IndexArray(selectionIndexes) << ListArray(selectionLists);
}
}
@@ -756,6 +906,35 @@ void tst_qdeclarativelistcompositor::move_data()
<< IndexArray(defaultIndexes) << ListArray(defaultLists)
<< IndexArray() << ListArray()
<< IndexArray() << ListArray();
+ } { static const int cacheIndexes[] = {8,9,10,4,11,0,1,2,3,5,6,7};
+ static const void *cacheLists[] = {a,a, a,a, a,a,a,a,a,a,a,a};
+ static const int defaultIndexes[] = {8,9,10,4,11,0,1,2,3,5,6,7};
+ static const void *defaultLists[] = {a,a, a,a, a,a,a,a,a,a,a,a};
+ static const int visibleIndexes[] = {8,9,10,4,11,0,1,2,3,5,6,7};
+ static const void *visibleLists[] = {a,a, a,a, a,a,a,a,a,a,a,a};
+ QTest::newRow("3, 4, 5")
+ << (RangeList()
+ << Range(a, 8, 4, VisibleFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 0, 2, C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 2, 1, C::PrependFlag)
+ << Range(a, 2, 1, VisibleFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 3, 5, C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 8, 4, C::AppendFlag | C::PrependFlag))
+ << C::Default << 3 << C::Default << 4 << 5
+ << (RemoveList()
+ << Remove(0, 3, 3, 3, 1, VisibleFlag | C::DefaultFlag | C::CacheFlag, 0)
+ << Remove(0, 3, 3, 3, 2, VisibleFlag | C::DefaultFlag | C::CacheFlag, 1)
+ << Remove(0, 3, 3, 3, 1, VisibleFlag | C::DefaultFlag | C::CacheFlag, 2)
+ << Remove(0, 3, 3, 3, 1, VisibleFlag | C::DefaultFlag | C::CacheFlag, 3))
+ << (InsertList()
+ << Insert(0, 4, 4, 4, 1, VisibleFlag | C::DefaultFlag | C::CacheFlag, 0)
+ << Insert(0, 5, 5, 5, 2, VisibleFlag | C::DefaultFlag | C::CacheFlag, 1)
+ << Insert(0, 7, 7, 7, 1, VisibleFlag | C::DefaultFlag | C::CacheFlag, 2)
+ << Insert(0, 8, 8, 8, 1, VisibleFlag | C::DefaultFlag | C::CacheFlag, 3))
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray(visibleIndexes) << ListArray(visibleLists)
+ << IndexArray() << ListArray();
}
}
@@ -955,6 +1134,21 @@ void tst_qdeclarativelistcompositor::listItemsInserted_data()
<< IndexArray(defaultIndexes)
<< IndexArray(visibleIndexes)
<< IndexArray();
+ } { static const int cacheIndexes[] = {/*A*/0,1,2,3,4};
+ static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5,6};
+ static const int visibleIndexes[] = {/*A*/0,1,2,3,4,5,6};
+ QTest::newRow("Consecutive appends")
+ << (RangeList()
+ << Range(a, 0, 5, C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 5, 1, C::PrependFlag | VisibleFlag | C::DefaultFlag)
+ << Range(a, 6, 0, C::AppendFlag | VisibleFlag | C::PrependFlag | C::DefaultFlag | C::CacheFlag))
+ << a << 6 << 1
+ << (InsertList()
+ << Insert(0, 6, 6, 5, 1, VisibleFlag | C::DefaultFlag))
+ << IndexArray(cacheIndexes)
+ << IndexArray(defaultIndexes)
+ << IndexArray(visibleIndexes)
+ << IndexArray();
}
}
@@ -1067,6 +1261,30 @@ void tst_qdeclarativelistcompositor::listItemsRemoved_data()
<< IndexArray(defaultIndexes)
<< IndexArray()
<< IndexArray();
+ } { static const int cacheIndexes[] = {/*A*/-1,-1,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1};
+ static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5,6};
+ QTest::newRow("Sparse remove")
+ << (RangeList()
+ << Range(a, 0, 2, C::CacheFlag)
+ << Range(a, 0, 1, C::DefaultFlag | C::CacheFlag)
+ << Range(a, 0, 1, C::CacheFlag)
+ << Range(a, 1, 5, C::DefaultFlag | C::CacheFlag)
+ << Range(a, 0, 1, C::CacheFlag)
+ << Range(a, 6, 2, C::DefaultFlag | C::CacheFlag)
+ << Range(a, 0, 1, C::CacheFlag)
+ << Range(a, 8, 3, C::DefaultFlag | C::CacheFlag)
+ << Range(a, 0, 1, C::CacheFlag)
+ << Range(a, 11, 1, C::DefaultFlag | C::CacheFlag)
+ << Range(a, 12, 5, C::DefaultFlag))
+ << a << 1 << 10
+ << (RemoveList()
+ << Remove(0, 0, 1, 4, 5, C::DefaultFlag | C::CacheFlag)
+ << Remove(0, 0, 1,10, 2, C::DefaultFlag | C::CacheFlag)
+ << Remove(0, 0, 1,13, 3, C::DefaultFlag | C::CacheFlag))
+ << IndexArray(cacheIndexes)
+ << IndexArray(defaultIndexes)
+ << IndexArray()
+ << IndexArray();
}
}
@@ -1205,6 +1423,24 @@ void tst_qdeclarativelistcompositor::listItemsMoved_data()
<< IndexArray(defaultIndexes)
<< IndexArray()
<< IndexArray();
+ } { static const int cacheIndexes[] = {/*A*/0,1,5,6,7,8,9,10,11,12};
+ static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5,6,7,8,9,10,11,12};
+ QTest::newRow("Move merge tail")
+ << (RangeList()
+ << Range(a, 0, 10, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 10, 3, C::PrependFlag | C::DefaultFlag)
+ << Range(a, 13, 0, C::AppendFlag | C::PrependFlag | C::DefaultFlag | C::CacheFlag))
+ << a << 8 << 0 << 5
+ << (RemoveList()
+ << Remove(0, 0, 8, 8, 2, C::DefaultFlag | C::CacheFlag, 0)
+ << Remove(0, 0, 8, 8, 3, C::DefaultFlag, 1))
+ << (InsertList()
+ << Insert(0, 0, 0, 0, 2, C::DefaultFlag | C::CacheFlag, 0)
+ << Insert(0, 0, 2, 2, 3, C::DefaultFlag, 1))
+ << IndexArray(cacheIndexes)
+ << IndexArray(defaultIndexes)
+ << IndexArray()
+ << IndexArray();
}
}
diff --git a/tests/auto/declarative/qdeclarativelistmodel/data/workerremoveelement.js b/tests/auto/declarative/qdeclarativelistmodel/data/workerremoveelement.js
new file mode 100644
index 0000000000..cb9dfa66aa
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelistmodel/data/workerremoveelement.js
@@ -0,0 +1,8 @@
+WorkerScript.onMessage = function(msg) {
+ if (msg.action == 'removeItem') {
+ msg.model.remove(0);
+ } else if (msg.action == 'dosync') {
+ msg.model.sync();
+ }
+ WorkerScript.sendMessage({'done': true})
+}
diff --git a/tests/auto/declarative/qdeclarativelistmodel/data/workerremoveelement.qml b/tests/auto/declarative/qdeclarativelistmodel/data/workerremoveelement.qml
new file mode 100644
index 0000000000..e2361acf6b
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelistmodel/data/workerremoveelement.qml
@@ -0,0 +1,33 @@
+import QtQuick 2.0
+
+Item {
+ id: item
+ property variant model
+ property bool done: false
+
+ WorkerScript {
+ id: worker
+ source: "workerremoveelement.js"
+ onMessage: {
+ item.done = true
+ }
+ }
+
+ function addItem() {
+ model.append({ 'data': 1 });
+
+ var element = model.get(0);
+ }
+
+ function removeItemViaWorker() {
+ done = false
+ var msg = { 'action': 'removeItem', 'model': model }
+ worker.sendMessage(msg);
+ }
+
+ function doSync() {
+ done = false
+ var msg = { 'action': 'dosync', 'model': model }
+ worker.sendMessage(msg);
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativelistmodel/data/workerremovelist.js b/tests/auto/declarative/qdeclarativelistmodel/data/workerremovelist.js
new file mode 100644
index 0000000000..f63dd68839
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelistmodel/data/workerremovelist.js
@@ -0,0 +1,9 @@
+WorkerScript.onMessage = function(msg) {
+ if (msg.action == 'removeList') {
+ msg.model.remove(0);
+ } else if (msg.action == 'dosync') {
+ msg.model.sync();
+ }
+ WorkerScript.sendMessage({'done': true})
+}
+
diff --git a/tests/auto/declarative/qdeclarativelistmodel/data/workerremovelist.qml b/tests/auto/declarative/qdeclarativelistmodel/data/workerremovelist.qml
new file mode 100644
index 0000000000..bdb5e024d8
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelistmodel/data/workerremovelist.qml
@@ -0,0 +1,33 @@
+import QtQuick 2.0
+
+Item {
+ id: item
+ property variant model
+ property bool done: false
+
+ WorkerScript {
+ id: worker
+ source: "workerremovelist.js"
+ onMessage: {
+ item.done = true
+ }
+ }
+
+ function addList() {
+ model.append({ 'data': [ { 'subData': 1 } ] });
+
+ var element = model.get(0);
+ }
+
+ function removeListViaWorker() {
+ done = false
+ var msg = { 'action': 'removeList', 'model': model }
+ worker.sendMessage(msg);
+ }
+
+ function doSync() {
+ done = false
+ var msg = { 'action': 'dosync', 'model': model }
+ worker.sendMessage(msg);
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativelistmodel/data/workersync.js b/tests/auto/declarative/qdeclarativelistmodel/data/workersync.js
new file mode 100644
index 0000000000..9b8d8fa7f3
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelistmodel/data/workersync.js
@@ -0,0 +1,8 @@
+WorkerScript.onMessage = function(msg) {
+ if (msg.action == 'addItem') {
+ msg.model.get(0).level0.append({ 'level1': 33 });
+ } else if (msg.action == 'dosync') {
+ msg.model.sync();
+ }
+ WorkerScript.sendMessage({'done': true})
+}
diff --git a/tests/auto/declarative/qdeclarativelistmodel/data/workersync.qml b/tests/auto/declarative/qdeclarativelistmodel/data/workersync.qml
new file mode 100644
index 0000000000..c21cd43e7e
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelistmodel/data/workersync.qml
@@ -0,0 +1,32 @@
+import QtQuick 2.0
+
+Item {
+ id: item
+ property variant model
+ property bool done: false
+
+ WorkerScript {
+ id: worker
+ source: "workersync.js"
+ onMessage: {
+ item.done = true
+ }
+ }
+
+ function addItem0() {
+ model.append({ 'level0': [ { 'level1': 29 } ] });
+ model.append({ 'level0': [ { 'level1': 37 } ] });
+ }
+
+ function addItemViaWorker() {
+ done = false
+ var msg = { 'action': 'addItem', 'model': model }
+ worker.sendMessage(msg);
+ }
+
+ function doSync() {
+ done = false
+ var msg = { 'action': 'dosync', 'model': model }
+ worker.sendMessage(msg);
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro b/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro
index 1586e68281..fc8a3178ae 100644
--- a/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro
+++ b/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro
@@ -4,7 +4,9 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativelistmodel.cpp
-DEFINES += SRCDIR=\\\"$$PWD\\\"
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
index bc6c99102e..e5e12092e3 100644
--- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
+++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
@@ -51,9 +51,22 @@
#include <QtCore/qtranslator.h>
#include <QSignalSpy>
+#include "../shared/util.h"
+
Q_DECLARE_METATYPE(QList<int>)
Q_DECLARE_METATYPE(QList<QVariantHash>)
+#define RUNEVAL(object, string) \
+ QVERIFY(QMetaObject::invokeMethod(object, "runEval", Q_ARG(QVariant, QString(string))));
+
+inline QVariant runexpr(QDeclarativeEngine *engine, const QString &str)
+{
+ QDeclarativeExpression expr(engine->rootContext(), 0, str);
+ return expr.evaluate();
+}
+
+#define RUNEXPR(string) runexpr(&engine, QString(string))
+
class tst_qdeclarativelistmodel : public QObject
{
Q_OBJECT
@@ -65,6 +78,8 @@ private:
QQuickItem *createWorkerTest(QDeclarativeEngine *eng, QDeclarativeComponent *component, QDeclarativeListModel *model);
void waitForWorker(QQuickItem *item);
+ static bool compareVariantList(const QVariantList &testList, QVariant object);
+
private slots:
void static_types();
void static_types_data();
@@ -78,16 +93,12 @@ private slots:
void dynamic_worker();
void dynamic_worker_sync_data();
void dynamic_worker_sync();
- void convertNestedToFlat_fail();
- void convertNestedToFlat_fail_data();
- void convertNestedToFlat_ok();
- void convertNestedToFlat_ok_data();
void enumerate();
void error_data();
void error();
void syncError();
- void set();
void get();
+ void set();
void get_data();
void get_worker();
void get_worker_data();
@@ -101,8 +112,64 @@ private slots:
void property_changes_worker_data();
void clear();
void signal_handlers();
+ void worker_sync();
+ void worker_remove_element();
+ void worker_remove_list();
};
+bool tst_qdeclarativelistmodel::compareVariantList(const QVariantList &testList, QVariant object)
+{
+ bool allOk = true;
+
+ QDeclarativeListModel *model = qobject_cast<QDeclarativeListModel *>(object.value<QObject *>());
+ if (model == 0)
+ return false;
+
+ if (model->count() != testList.count())
+ return false;
+
+ for (int i=0 ; i < testList.count() ; ++i) {
+ const QVariant &testVariant = testList.at(i);
+ if (testVariant.type() != QVariant::Map)
+ return false;
+ const QVariantMap &map = testVariant.toMap();
+
+ const QList<int> &roles = model->roles();
+
+ QVariantMap::const_iterator it = map.begin();
+ QVariantMap::const_iterator end = map.end();
+
+ while (it != end) {
+ const QString &testKey = it.key();
+ const QVariant &testData = it.value();
+
+ int roleIndex = -1;
+ for (int j=0 ; j < roles.count() ; ++j) {
+ if (model->toString(roles[j]).compare(testKey) == 0) {
+ roleIndex = j;
+ break;
+ }
+ }
+
+ if (roleIndex == -1)
+ return false;
+
+ const QVariant &modelData = model->data(i, roleIndex);
+
+ if (testData.type() == QVariant::List) {
+ const QVariantList &subList = testData.toList();
+ allOk = allOk && compareVariantList(subList, modelData);
+ } else {
+ allOk = allOk && (testData == modelData);
+ }
+
+ ++it;
+ }
+ }
+
+ return allOk;
+}
+
int tst_qdeclarativelistmodel::roleFromName(const QDeclarativeListModel *model, const QString &roleName)
{
QList<int> roles = model->roles();
@@ -118,7 +185,7 @@ QQuickItem *tst_qdeclarativelistmodel::createWorkerTest(QDeclarativeEngine *eng,
QQuickItem *item = qobject_cast<QQuickItem*>(component->create());
QDeclarativeEngine::setContextForObject(model, eng->rootContext());
if (item)
- item->setProperty("model", qVariantFromValue(model));
+ item->setProperty("model", qVariantFromValue(model));
return item;
}
@@ -141,43 +208,66 @@ void tst_qdeclarativelistmodel::static_types_data()
{
QTest::addColumn<QString>("qml");
QTest::addColumn<QVariant>("value");
+ QTest::addColumn<QString>("error");
QTest::newRow("string")
<< "ListElement { foo: \"bar\" }"
- << QVariant(QString("bar"));
+ << QVariant(QString("bar"))
+ << QString();
QTest::newRow("real")
<< "ListElement { foo: 10.5 }"
- << QVariant(10.5);
+ << QVariant(10.5)
+ << QString();
QTest::newRow("real0")
<< "ListElement { foo: 0 }"
- << QVariant(double(0));
+ << QVariant(double(0))
+ << QString();
QTest::newRow("bool")
<< "ListElement { foo: false }"
- << QVariant(false);
+ << QVariant(false)
+ << QString();
QTest::newRow("bool")
<< "ListElement { foo: true }"
- << QVariant(true);
+ << QVariant(true)
+ << QString();
QTest::newRow("enum")
<< "ListElement { foo: Text.AlignHCenter }"
- << QVariant(double(QQuickText::AlignHCenter));
+ << QVariant(double(QQuickText::AlignHCenter))
+ << QString();
QTest::newRow("Qt enum")
<< "ListElement { foo: Qt.AlignBottom }"
- << QVariant(double(Qt::AlignBottom));
+ << QVariant(double(Qt::AlignBottom))
+ << QString();
+
+ QTest::newRow("role error")
+ << "ListElement { foo: 1 } ListElement { foo: 'string' }"
+ << QVariant()
+ << QString("<Unknown File>: Can't assign to existing role 'foo' of different type [String -> Number]");
+
+ QTest::newRow("list type error")
+ << "ListElement { foo: 1 } ListElement { foo: ListElement { bar: 1 } }"
+ << QVariant()
+ << QString("<Unknown File>: Can't assign to existing role 'foo' of different type [List -> Number]");
}
void tst_qdeclarativelistmodel::static_types()
{
QFETCH(QString, qml);
QFETCH(QVariant, value);
+ QFETCH(QString, error);
qml = "import QtQuick 2.0\nItem { property variant test: model.get(0).foo; ListModel { id: model; " + qml + " } }";
+ if (!error.isEmpty()) {
+ QTest::ignoreMessage(QtWarningMsg, error.toLatin1());
+ }
+
QDeclarativeEngine engine;
QDeclarativeComponent component(&engine);
component.setData(qml.toUtf8(),
@@ -188,10 +278,12 @@ void tst_qdeclarativelistmodel::static_types()
QObject *obj = component.create();
QVERIFY(obj != 0);
- QVariant actual = obj->property("test");
+ if (error.isEmpty()) {
+ QVariant actual = obj->property("test");
- QCOMPARE(actual, value);
- QCOMPARE(actual.toString(), value.toString());
+ QCOMPARE(actual, value);
+ QCOMPARE(actual.toString(), value.toString());
+ }
delete obj;
}
@@ -270,11 +362,11 @@ void tst_qdeclarativelistmodel::static_nestedElements()
QFETCH(int, elementCount);
QStringList elements;
- for (int i=0; i<elementCount; i++)
+ for (int i=0; i<elementCount; i++)
elements.append("ListElement { a: 1; b: 2 }");
QString elementsStr = elements.join(",\n") + "\n";
- QString componentStr =
+ QString componentStr =
"import QtQuick 2.0\n"
"Item {\n"
" property variant count: model.get(0).attributes.count\n"
@@ -283,7 +375,7 @@ void tst_qdeclarativelistmodel::static_nestedElements()
" ListElement {\n"
" attributes: [\n";
componentStr += elementsStr.toUtf8().constData();
- componentStr +=
+ componentStr +=
" ]\n"
" }\n"
" }\n"
@@ -320,7 +412,6 @@ void tst_qdeclarativelistmodel::dynamic_data()
QTest::addColumn<QString>("warning");
// Simple flat model
-
QTest::newRow("count") << "count" << 0 << "";
QTest::newRow("get1") << "{get(0) === undefined}" << 1 << "";
@@ -336,7 +427,8 @@ void tst_qdeclarativelistmodel::dynamic_data()
QTest::newRow("append3a") << "{append({'foo':123});append({'foo':456});get(0).foo}" << 123 << "";
QTest::newRow("append3b") << "{append({'foo':123});append({'foo':456});get(1).foo}" << 456 << "";
QTest::newRow("append4a") << "{append(123)}" << 0 << "<Unknown File>: QML ListModel: append: value is not an object";
- QTest::newRow("append4b") << "{append([1,2,3])}" << 0 << "<Unknown File>: QML ListModel: append: value is not an object";
+ QTest::newRow("append4b") << "{append([{'foo':123},{'foo':456},{'foo':789}]);count}" << 3 << "";
+ QTest::newRow("append4c") << "{append([{'foo':123},{'foo':456},{'foo':789}]);get(1).foo}" << 456 << "";
QTest::newRow("clear1") << "{append({'foo':456});clear();count}" << 0 << "";
QTest::newRow("clear2") << "{append({'foo':123});append({'foo':456});clear();count}" << 0 << "";
@@ -361,7 +453,8 @@ void tst_qdeclarativelistmodel::dynamic_data()
QTest::newRow("insert3e") << "{append({'foo':123});insert(0,{'foo':456});get(1).foo}" << 123 << "";
QTest::newRow("insert4") << "{append({'foo':123});insert(-1,{'foo':456});count}" << 1 << "<Unknown File>: QML ListModel: insert: index -1 out of range";
QTest::newRow("insert5a") << "{insert(0,123)}" << 0 << "<Unknown File>: QML ListModel: insert: value is not an object";
- QTest::newRow("insert5b") << "{insert(0,[1,2,3])}" << 0 << "<Unknown File>: QML ListModel: insert: value is not an object";
+ QTest::newRow("insert5b") << "{insert(0,[{'foo':11},{'foo':22},{'foo':33}]);count}" << 3 << "";
+ QTest::newRow("insert5c") << "{insert(0,[{'foo':11},{'foo':22},{'foo':33}]);get(2).foo}" << 33 << "";
QTest::newRow("set1") << "{append({'foo':123});set(0,{'foo':456});count}" << 1 << "";
QTest::newRow("set2") << "{append({'foo':123});set(0,{'foo':456});get(0).foo}" << 456 << "";
@@ -396,8 +489,38 @@ void tst_qdeclarativelistmodel::dynamic_data()
QTest::newRow("move3c") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(1,0,-1);count}" << 3 << "<Unknown File>: QML ListModel: move: out of range";
QTest::newRow("move3d") << "{append({'foo':123});append({'foo':456});append({'foo':789});move(0,3,1);count}" << 3 << "<Unknown File>: QML ListModel: move: out of range";
- // Nested models
+ QTest::newRow("large1") << "{append({'a':1,'b':2,'c':3,'d':4,'e':5,'f':6,'g':7,'h':8});get(0).h}" << 8 << "";
+
+ QTest::newRow("datatypes1") << "{append({'a':1});append({'a':'string'});}" << 0 << "<Unknown File>: Can't assign to existing role 'a' of different type [String -> Number]";
+
+ QTest::newRow("null") << "{append({'a':null});}" << 0 << "";
+ QTest::newRow("setNull") << "{append({'a':1});set(0, {'a':null});}" << 0 << "";
+ QTest::newRow("setString") << "{append({'a':'hello'});set(0, {'a':'world'});get(0).a == 'world'}" << 1 << "";
+ QTest::newRow("setInt") << "{append({'a':5});set(0, {'a':10});get(0).a}" << 10 << "";
+ QTest::newRow("setNumber") << "{append({'a':6});set(0, {'a':5.5});get(0).a < 5.6}" << 1 << "";
+ QTest::newRow("badType0") << "{append({'a':'hello'});set(0, {'a':1});}" << 0 << "<Unknown File>: Can't assign to existing role 'a' of different type [Number -> String]";
+ QTest::newRow("invalidInsert0") << "{insert(0);}" << 0 << "<Unknown File>: QML ListModel: insert: value is not an object";
+ QTest::newRow("invalidAppend0") << "{append();}" << 0 << "<Unknown File>: QML ListModel: append: value is not an object";
+ QTest::newRow("invalidInsert1") << "{insert(0, 34);}" << 0 << "<Unknown File>: QML ListModel: insert: value is not an object";
+ QTest::newRow("invalidAppend1") << "{append(37);}" << 0 << "<Unknown File>: QML ListModel: append: value is not an object";
+
+ // QObjects
+ QTest::newRow("qobject0") << "{append({'a':dummyItem0});}" << 0 << "";
+ QTest::newRow("qobject1") << "{append({'a':dummyItem0});set(0,{'a':dummyItem1});get(0).a == dummyItem1;}" << 1 << "";
+ QTest::newRow("qobject2") << "{append({'a':dummyItem0});get(0).a == dummyItem0;}" << 1 << "";
+ QTest::newRow("qobject3") << "{append({'a':dummyItem0});append({'b':1});}" << 0 << "";
+
+ // JS objects
+ QTest::newRow("js1") << "{append({'foo':{'prop':1}});count}" << 1 << "";
+ QTest::newRow("js2") << "{append({'foo':{'prop':27}});get(0).foo.prop}" << 27 << "";
+ QTest::newRow("js3") << "{append({'foo':{'prop':27}});append({'bar':1});count}" << 2 << "";
+ QTest::newRow("js4") << "{append({'foo':{'prop':27}});append({'bar':1});set(0, {'foo':{'prop':28}});get(0).foo.prop}" << 28 << "";
+ QTest::newRow("js5") << "{append({'foo':{'prop':27}});append({'bar':1});set(1, {'foo':{'prop':33}});get(1).foo.prop}" << 33 << "";
+ QTest::newRow("js6") << "{append({'foo':{'prop':27}});clear();count}" << 0 << "";
+ QTest::newRow("js7") << "{append({'foo':{'prop':27}});set(0, {'foo':null});count}" << 1 << "";
+ QTest::newRow("js8") << "{append({'foo':{'prop':27}});set(0, {'foo':{'prop2':31}});get(0).foo.prop2}" << 31 << "";
+ // Nested models
QTest::newRow("nested-append1") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});count}" << 1 << "";
QTest::newRow("nested-append2") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});get(0).bars.get(1).a}" << 2 << "";
QTest::newRow("nested-append3") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});get(0).bars.append({'a':4});get(0).bars.get(3).a}" << 4 << "";
@@ -415,10 +538,13 @@ void tst_qdeclarativelistmodel::dynamic()
QFETCH(int, result);
QFETCH(QString, warning);
+ QQuickItem dummyItem0, dummyItem1;
QDeclarativeEngine engine;
QDeclarativeListModel model;
QDeclarativeEngine::setContextForObject(&model,engine.rootContext());
engine.rootContext()->setContextObject(&model);
+ engine.rootContext()->setContextProperty("dummyItem0", QVariant::fromValue(&dummyItem0));
+ engine.rootContext()->setContextProperty("dummyItem1", QVariant::fromValue(&dummyItem1));
QDeclarativeExpression e(engine.rootContext(), &model, script);
if (!warning.isEmpty())
QTest::ignoreMessage(QtWarningMsg, warning.toLatin1());
@@ -446,16 +572,15 @@ void tst_qdeclarativelistmodel::dynamic_worker()
QFETCH(int, result);
QFETCH(QString, warning);
- if (QByteArray(QTest::currentDataTag()).startsWith("nested"))
+ if (QByteArray(QTest::currentDataTag()).startsWith("qobject"))
return;
- // This is same as dynamic() except it applies the test to a ListModel called
- // from a WorkerScript (i.e. testing the internal FlatListModel that is created
- // by the WorkerListModelAgent)
+ // This is same as dynamic() except it applies the test to a ListModel called
+ // from a WorkerScript.
QDeclarativeListModel model;
QDeclarativeEngine eng;
- QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
+ QDeclarativeComponent component(&eng, QUrl::fromLocalFile(TESTDATA("model.qml")));
QQuickItem *item = createWorkerTest(&eng, &component, &model);
QVERIFY(item != 0);
@@ -495,13 +620,16 @@ void tst_qdeclarativelistmodel::dynamic_worker_sync()
QFETCH(int, result);
QFETCH(QString, warning);
+ if (QByteArray(QTest::currentDataTag()).startsWith("qobject"))
+ return;
+
// This is the same as dynamic_worker() except that it executes a set of list operations
// from the worker script, calls sync(), and tests the changes are reflected in the
// list in the main thread
-
+
QDeclarativeListModel model;
QDeclarativeEngine eng;
- QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
+ QDeclarativeComponent component(&eng, QUrl::fromLocalFile(TESTDATA("model.qml")));
QQuickItem *item = createWorkerTest(&eng, &component, &model);
QVERIFY(item != 0);
@@ -518,139 +646,55 @@ void tst_qdeclarativelistmodel::dynamic_worker_sync()
// execute a set of commands on the worker list model, then check the
// changes are reflected in the list model in the main thread
- if (QByteArray(QTest::currentDataTag()).startsWith("nested"))
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML ListModel: Cannot add list-type data when modifying or after modification from a worker script");
-
- if (QByteArray(QTest::currentDataTag()).startsWith("nested-set"))
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML ListModel: Cannot add list-type data when modifying or after modification from a worker script");
-
- QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker",
+ QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker",
Q_ARG(QVariant, operations.mid(0, operations.length()-1))));
waitForWorker(item);
QDeclarativeExpression e(eng.rootContext(), &model, operations.last().toString());
- if (!QByteArray(QTest::currentDataTag()).startsWith("nested"))
- QCOMPARE(e.evaluate().toInt(), result);
+ QCOMPARE(e.evaluate().toInt(), result);
delete item;
qApp->processEvents();
}
-#define RUNEVAL(object, string) \
- QVERIFY(QMetaObject::invokeMethod(object, "runEval", Q_ARG(QVariant, QString(string))));
-
-inline QVariant runexpr(QDeclarativeEngine *engine, const QString &str)
-{
- QDeclarativeExpression expr(engine->rootContext(), 0, str);
- return expr.evaluate();
-}
-
-#define RUNEXPR(string) runexpr(&engine, QString(string))
-
-void tst_qdeclarativelistmodel::convertNestedToFlat_fail()
-{
- // If a model has nested data, it cannot be used at all from a worker script
-
- QFETCH(QString, script);
-
- QDeclarativeListModel model;
- QDeclarativeEngine eng;
- QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
- QQuickItem *item = createWorkerTest(&eng, &component, &model);
- QVERIFY(item != 0);
-
- RUNEVAL(item, "model.append({foo: 123})");
- RUNEVAL(item, "model.append({foo: [{}, {}]})");
-
- QCOMPARE(model.count(), 2);
-
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML ListModel: List contains list-type data and cannot be used from a worker script");
- QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker", Q_ARG(QVariant, script)));
- waitForWorker(item);
-
- QCOMPARE(model.count(), 2);
-
- delete item;
- qApp->processEvents();
-}
-
-void tst_qdeclarativelistmodel::convertNestedToFlat_fail_data()
-{
- QTest::addColumn<QString>("script");
-
- QTest::newRow("clear") << "clear()";
- QTest::newRow("remove") << "remove(0)";
- QTest::newRow("append") << "append({'x':1})";
- QTest::newRow("insert") << "insert(0, {'x':1})";
- QTest::newRow("set") << "set(0, {'foo':1})";
- QTest::newRow("setProperty") << "setProperty(0, 'foo', 1})";
- QTest::newRow("move") << "move(0, 1, 1})";
- QTest::newRow("get") << "get(0)";
-}
-
-void tst_qdeclarativelistmodel::convertNestedToFlat_ok()
-
+void tst_qdeclarativelistmodel::enumerate()
{
- // If a model only has plain data, it can be modified from a worker script. However,
- // once the model is used from a worker script, it no longer accepts nested data
-
- QFETCH(QString, script);
-
- QDeclarativeListModel model;
QDeclarativeEngine eng;
- QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
- QQuickItem *item = createWorkerTest(&eng, &component, &model);
+ QDeclarativeComponent component(&eng, QUrl::fromLocalFile(TESTDATA("enumerate.qml")));
+ QVERIFY(!component.isError());
+ QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
QVERIFY(item != 0);
- RUNEVAL(item, "model.append({foo: 123})");
-
- QCOMPARE(model.count(), 1);
-
- QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker", Q_ARG(QVariant, script)));
- waitForWorker(item);
-
- // can still add plain data
- int count = model.count();
-
- RUNEVAL(item, "model.append({foo: 123})");
-
- QCOMPARE(model.count(), count+1);
+ QLatin1String expectedStrings[] = {
+ QLatin1String("val1=1Y"),
+ QLatin1String("val2=2Y"),
+ QLatin1String("val3=strY"),
+ QLatin1String("val4=falseN"),
+ QLatin1String("val5=trueY")
+ };
- const char *warning = "<Unknown File>: QML ListModel: Cannot add list-type data when modifying or after modification from a worker script";
+ int expectedStringCount = sizeof(expectedStrings) / sizeof(expectedStrings[0]);
- QTest::ignoreMessage(QtWarningMsg, warning);
- RUNEVAL(item, "model.append({foo: [{}, {}]})");
-
- QTest::ignoreMessage(QtWarningMsg, warning);
- RUNEVAL(item, "model.insert(0, {foo: [{}, {}]})");
+ QStringList r = item->property("result").toString().split(":");
- QTest::ignoreMessage(QtWarningMsg, warning);
- RUNEVAL(item, "model.set(0, {foo: [{}, {}]})");
+ int matchCount = 0;
+ for (int i=0 ; i < expectedStringCount ; ++i) {
+ const QLatin1String &expectedString = expectedStrings[i];
- QCOMPARE(model.count(), count+1);
+ QStringList::const_iterator it = r.begin();
+ QStringList::const_iterator end = r.end();
- delete item;
- qApp->processEvents();
-}
+ while (it != end) {
+ if (it->compare(expectedString) == 0) {
+ ++matchCount;
+ break;
+ }
+ ++it;
+ }
+ }
-void tst_qdeclarativelistmodel::convertNestedToFlat_ok_data()
-{
- convertNestedToFlat_fail_data();
-}
+ QVERIFY(matchCount == expectedStringCount);
-void tst_qdeclarativelistmodel::enumerate()
-{
- QDeclarativeEngine eng;
- QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/enumerate.qml"));
- QVERIFY(!component.isError());
- QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
- QVERIFY(item != 0);
- QStringList r = item->property("result").toString().split(":");
- QCOMPARE(r[0],QLatin1String("val1=1Y"));
- QCOMPARE(r[1],QLatin1String("val2=2Y"));
- QCOMPARE(r[2],QLatin1String("val3=strY"));
- QCOMPARE(r[3],QLatin1String("val4=falseN"));
- QCOMPARE(r[4],QLatin1String("val5=trueY"));
delete item;
}
@@ -752,11 +796,15 @@ void tst_qdeclarativelistmodel::set()
RUNEXPR("model.set(0, {test:true})");
QCOMPARE(RUNEXPR("model.get(0).test").toBool(), true); // triggers creation of model cache
- QCOMPARE(model.data(0, model.roles()[0]), qVariantFromValue(true));
+ QCOMPARE(model.data(0, model.roles()[0]), qVariantFromValue(true));
RUNEXPR("model.set(0, {test:false})");
QCOMPARE(RUNEXPR("model.get(0).test").toBool(), false); // tests model cache is updated
- QCOMPARE(model.data(0, model.roles()[0]), qVariantFromValue(false));
+ QCOMPARE(model.data(0, model.roles()[0]), qVariantFromValue(false));
+
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: Can't create role for unsupported data type");
+ QVariant invalidData = QColor();
+ model.setProperty(0, "test", invalidData);
}
/*
@@ -773,21 +821,31 @@ void tst_qdeclarativelistmodel::get()
QDeclarativeComponent component(&engine);
component.setData(
"import QtQuick 2.0\n"
- "ListModel { \n"
- "ListElement { roleA: 100 }\n"
- "ListElement { roleA: 200; roleB: 400 } \n"
- "ListElement { roleA: 200; roleB: 400 } \n"
- "}", QUrl());
+ "ListModel {}\n", QUrl());
QDeclarativeListModel *model = qobject_cast<QDeclarativeListModel*>(component.create());
- int role = roleFromName(model, roleName);
- QVERIFY(role >= 0);
+ engine.rootContext()->setContextProperty("model", model);
+
+ RUNEXPR("model.append({roleA: 100})");
+ RUNEXPR("model.append({roleA: 200, roleB: 400})");
+ RUNEXPR("model.append({roleA: 200, roleB: 400})");
+ RUNEXPR("model.append({roleC: {} })");
+ RUNEXPR("model.append({roleD: [ { a:1, b:2 }, { c: 3 } ] })");
QSignalSpy spy(model, SIGNAL(itemsChanged(int, int, QList<int>)));
QDeclarativeExpression expr(engine.rootContext(), model, expression);
expr.evaluate();
QVERIFY(!expr.hasError());
- QCOMPARE(model->data(index, role), roleValue);
+ int role = roleFromName(model, roleName);
+ QVERIFY(role >= 0);
+
+ if (roleValue.type() == QVariant::List) {
+ const QVariantList &list = roleValue.toList();
+ QVERIFY(compareVariantList(list, model->data(index, role)));
+ } else {
+ QCOMPARE(model->data(index, role), roleValue);
+ }
+
QCOMPARE(spy.count(), 1);
QList<QVariant> spyResult = spy.takeFirst();
@@ -805,19 +863,16 @@ void tst_qdeclarativelistmodel::get_data()
QTest::addColumn<QString>("roleName");
QTest::addColumn<QVariant>("roleValue");
- QTest::newRow("simple value") << "get(0).roleA = 500" << 0 << "roleA" << QVariant(500);
- QTest::newRow("simple value 2") << "get(1).roleB = 500" << 1 << "roleB" << QVariant(500);
+ QTest::newRow("simple value") << "get(0).roleA = 500" << 0 << "roleA" << QVariant(500);
+ QTest::newRow("simple value 2") << "get(1).roleB = 500" << 1 << "roleB" << QVariant(500);
QVariantMap map;
- map["zzz"] = 123;
- QTest::newRow("object value") << "get(1).roleB = {'zzz':123}" << 1 << "roleB" << QVariant::fromValue(map);
-
QVariantList list;
map.clear(); map["a"] = 50; map["b"] = 500;
list << map;
map.clear(); map["c"] = 1000;
list << map;
- QTest::newRow("list of objects") << "get(2).roleB = [{'a': 50, 'b': 500}, {'c': 1000}]" << 2 << "roleB" << QVariant::fromValue(list);
+ QTest::newRow("list of objects") << "get(2).roleD = [{'a': 50, 'b': 500}, {'c': 1000}]" << 2 << "roleD" << QVariant::fromValue(list);
}
void tst_qdeclarativelistmodel::get_worker()
@@ -829,7 +884,7 @@ void tst_qdeclarativelistmodel::get_worker()
QDeclarativeListModel model;
QDeclarativeEngine eng;
- QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
+ QDeclarativeComponent component(&eng, QUrl::fromLocalFile(TESTDATA("model.qml")));
QQuickItem *item = createWorkerTest(&eng, &component, &model);
QVERIFY(item != 0);
@@ -837,13 +892,12 @@ void tst_qdeclarativelistmodel::get_worker()
RUNEVAL(item, "model.append({roleA: 100})");
RUNEVAL(item, "model.append({roleA: 200, roleB: 400})");
RUNEVAL(item, "model.append({roleA: 200, roleB: 400})");
+ RUNEVAL(item, "model.append({roleC: {} })");
+ RUNEVAL(item, "model.append({roleD: [ { a:1, b:2 }, { c: 3 } ] })");
int role = roleFromName(&model, roleName);
QVERIFY(role >= 0);
- const char *warning = "<Unknown File>: QML ListModel: Cannot add list-type data when modifying or after modification from a worker script";
- if (roleValue.type() == QVariant::List || roleValue.type() == QVariant::Map)
- QTest::ignoreMessage(QtWarningMsg, warning);
QSignalSpy spy(&model, SIGNAL(itemsChanged(int, int, QList<int>)));
// in the worker thread, change the model data and call sync()
@@ -852,18 +906,19 @@ void tst_qdeclarativelistmodel::get_worker()
waitForWorker(item);
// see if we receive the model changes in the main thread's model
- if (roleValue.type() == QVariant::List || roleValue.type() == QVariant::Map) {
- QVERIFY(model.data(index, role) != roleValue);
- QCOMPARE(spy.count(), 0);
+ if (roleValue.type() == QVariant::List) {
+ const QVariantList &list = roleValue.toList();
+ QVERIFY(compareVariantList(list, model.data(index, role)));
} else {
QCOMPARE(model.data(index, role), roleValue);
- QCOMPARE(spy.count(), 1);
-
- QList<QVariant> spyResult = spy.takeFirst();
- QCOMPARE(spyResult.at(0).toInt(), index);
- QCOMPARE(spyResult.at(1).toInt(), 1); // only 1 item is modified at a time
- QVERIFY(spyResult.at(2).value<QList<int> >().contains(role));
}
+
+ QCOMPARE(spy.count(), 1);
+
+ QList<QVariant> spyResult = spy.takeFirst();
+ QCOMPARE(spyResult.at(0).toInt(), index);
+ QCOMPARE(spyResult.at(1).toInt(), 1); // only 1 item is modified at a time
+ QVERIFY(spyResult.at(2).value<QList<int> >().contains(role));
}
void tst_qdeclarativelistmodel::get_worker_data()
@@ -881,39 +936,48 @@ void tst_qdeclarativelistmodel::get_nested()
QFETCH(QString, roleName);
QFETCH(QVariant, roleValue);
- QDeclarativeEngine eng;
- QDeclarativeComponent component(&eng);
+ if (roleValue.type() == QVariant::Map)
+ return;
+
+ QDeclarativeEngine engine;
+ QDeclarativeComponent component(&engine);
component.setData(
"import QtQuick 2.0\n"
- "ListModel { \n"
- "ListElement {\n"
- "listRoleA: [\n"
- "ListElement { roleA: 100 },\n"
- "ListElement { roleA: 200; roleB: 400 },\n"
- "ListElement { roleA: 200; roleB: 400 } \n"
- "]\n"
- "}\n"
- "ListElement {\n"
- "listRoleA: [\n"
- "ListElement { roleA: 100 },\n"
- "ListElement { roleA: 200; roleB: 400 },\n"
- "ListElement { roleA: 200; roleB: 400 } \n"
- "]\n"
- "listRoleB: [\n"
- "ListElement { roleA: 100 },\n"
- "ListElement { roleA: 200; roleB: 400 },\n"
- "ListElement { roleA: 200; roleB: 400 } \n"
- "]\n"
- "listRoleC: [\n"
- "ListElement { roleA: 100 },\n"
- "ListElement { roleA: 200; roleB: 400 },\n"
- "ListElement { roleA: 200; roleB: 400 } \n"
- "]\n"
- "}\n"
- "}", QUrl());
+ "ListModel {}", QUrl());
QDeclarativeListModel *model = qobject_cast<QDeclarativeListModel*>(component.create());
QVERIFY(component.errorString().isEmpty());
QDeclarativeListModel *childModel;
+ engine.rootContext()->setContextProperty("model", model);
+
+ RUNEXPR("model.append({ listRoleA: [\n"
+ "{ roleA: 100 },\n"
+ "{ roleA: 200, roleB: 400 },\n"
+ "{ roleA: 200, roleB: 400 }, \n"
+ "{ roleC: {} }, \n"
+ "{ roleD: [ { a: 1, b:2 }, { c: 3 } ] } \n"
+ "] })\n");
+
+ RUNEXPR("model.append({ listRoleA: [\n"
+ "{ roleA: 100 },\n"
+ "{ roleA: 200, roleB: 400 },\n"
+ "{ roleA: 200, roleB: 400 }, \n"
+ "{ roleC: {} }, \n"
+ "{ roleD: [ { a: 1, b:2 }, { c: 3 } ] } \n"
+ "],\n"
+ "listRoleB: [\n"
+ "{ roleA: 100 },\n"
+ "{ roleA: 200, roleB: 400 },\n"
+ "{ roleA: 200, roleB: 400 }, \n"
+ "{ roleC: {} }, \n"
+ "{ roleD: [ { a: 1, b:2 }, { c: 3 } ] } \n"
+ "],\n"
+ "listRoleC: [\n"
+ "{ roleA: 100 },\n"
+ "{ roleA: 200, roleB: 400 },\n"
+ "{ roleA: 200, roleB: 400 }, \n"
+ "{ roleC: {} }, \n"
+ "{ roleD: [ { a: 1, b:2 }, { c: 3 } ] } \n"
+ "] })\n");
// Test setting the inner list data for:
// get(0).listRoleA
@@ -937,7 +1001,7 @@ void tst_qdeclarativelistmodel::get_nested()
QVERIFY(childModel);
QString extendedExpression = QString("get(%1).%2.%3").arg(outerListIndex).arg(outerListRoleName).arg(expression);
- QDeclarativeExpression expr(eng.rootContext(), model, extendedExpression);
+ QDeclarativeExpression expr(engine.rootContext(), model, extendedExpression);
QSignalSpy spy(childModel, SIGNAL(itemsChanged(int, int, QList<int>)));
expr.evaluate();
@@ -945,7 +1009,11 @@ void tst_qdeclarativelistmodel::get_nested()
int role = roleFromName(childModel, roleName);
QVERIFY(role >= 0);
- QCOMPARE(childModel->data(index, role), roleValue);
+ if (roleValue.type() == QVariant::List) {
+ QVERIFY(compareVariantList(roleValue.toList(), childModel->data(index, role)));
+ } else {
+ QCOMPARE(childModel->data(index, role), roleValue);
+ }
QCOMPARE(spy.count(), 1);
QList<QVariant> spyResult = spy.takeFirst();
@@ -966,7 +1034,7 @@ void tst_qdeclarativelistmodel::get_nested_data()
void tst_qdeclarativelistmodel::crash_model_with_multiple_roles()
{
QDeclarativeEngine eng;
- QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/multipleroles.qml"));
+ QDeclarativeComponent component(&eng, QUrl::fromLocalFile(TESTDATA("multipleroles.qml")));
QObject *rootItem = component.create();
QVERIFY(component.errorString().isEmpty());
QVERIFY(rootItem != 0);
@@ -983,7 +1051,7 @@ void tst_qdeclarativelistmodel::crash_model_with_multiple_roles()
void tst_qdeclarativelistmodel::set_model_cache()
{
QDeclarativeEngine eng;
- QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/setmodelcachelist.qml"));
+ QDeclarativeComponent component(&eng, QUrl::fromLocalFile(TESTDATA("setmodelcachelist.qml")));
QObject *model = component.create();
QVERIFY2(component.errorString().isEmpty(), QTest::toString(component.errorString()));
QVERIFY(model != 0);
@@ -1017,6 +1085,7 @@ void tst_qdeclarativelistmodel::property_changes()
"target: model.get(" + QString::number(listIndex) + ")\n"
+ signalHandler + " gotSignal = true\n"
"}\n";
+
QDeclarativeComponent component(&engine);
component.setData(qml.toUtf8(), QUrl::fromLocalFile(""));
engine.rootContext()->setContextProperty("model", &model);
@@ -1117,10 +1186,6 @@ void tst_qdeclarativelistmodel::property_changes_data()
void tst_qdeclarativelistmodel::property_changes_worker()
{
- // nested models are not supported when WorkerScript is involved
- if (QByteArray(QTest::currentDataTag()).startsWith("nested-"))
- return;
-
QFETCH(QString, script_setup);
QFETCH(QString, script_change);
QFETCH(QString, roleName);
@@ -1129,7 +1194,7 @@ void tst_qdeclarativelistmodel::property_changes_worker()
QDeclarativeListModel model;
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml")));
QVERIFY2(component.errorString().isEmpty(), component.errorString().toUtf8());
QQuickItem *item = createWorkerTest(&engine, &component, &model);
QVERIFY(item != 0);
@@ -1199,7 +1264,7 @@ void tst_qdeclarativelistmodel::clear()
void tst_qdeclarativelistmodel::signal_handlers()
{
QDeclarativeEngine eng;
- QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/signalhandlers.qml"));
+ QDeclarativeComponent component(&eng, QUrl::fromLocalFile(TESTDATA("signalhandlers.qml")));
QObject *model = component.create();
QVERIFY2(component.errorString().isEmpty(), QTest::toString(component.errorString()));
QVERIFY(model != 0);
@@ -1208,6 +1273,129 @@ void tst_qdeclarativelistmodel::signal_handlers()
delete model;
}
+void tst_qdeclarativelistmodel::worker_sync()
+{
+ QDeclarativeListModel model;
+ QDeclarativeEngine eng;
+ QDeclarativeComponent component(&eng, QUrl::fromLocalFile(TESTDATA("workersync.qml")));
+ QQuickItem *item = createWorkerTest(&eng, &component, &model);
+ QVERIFY(item != 0);
+
+ QVERIFY(model.count() == 0);
+
+ QVERIFY(QMetaObject::invokeMethod(item, "addItem0"));
+
+ QVERIFY(model.count() == 2);
+ QVariant childData = model.data(0, 0);
+ QDeclarativeListModel *childModel = qobject_cast<QDeclarativeListModel *>(childData.value<QObject *>());
+ QVERIFY(childModel);
+ QVERIFY(childModel->count() == 1);
+
+ QSignalSpy spyModelInserted(&model, SIGNAL(itemsInserted(int,int)));
+ QSignalSpy spyChildInserted(childModel, SIGNAL(itemsInserted(int,int)));
+
+ QVERIFY(QMetaObject::invokeMethod(item, "addItemViaWorker"));
+ waitForWorker(item);
+
+ QVERIFY(model.count() == 2);
+ QVERIFY(childModel->count() == 1);
+ QVERIFY(spyModelInserted.count() == 0);
+ QVERIFY(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);
+
+ QVERIFY(QMetaObject::invokeMethod(item, "addItemViaWorker"));
+ waitForWorker(item);
+
+ QVERIFY(model.count() == 2);
+ QVERIFY(childModel->count() == 2);
+ QVERIFY(spyModelInserted.count() == 0);
+ QVERIFY(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);
+
+ delete item;
+ qApp->processEvents();
+}
+
+void tst_qdeclarativelistmodel::worker_remove_element()
+{
+ QDeclarativeListModel model;
+ QDeclarativeEngine eng;
+ QDeclarativeComponent component(&eng, QUrl::fromLocalFile(TESTDATA("workerremoveelement.qml")));
+ QQuickItem *item = createWorkerTest(&eng, &component, &model);
+ QVERIFY(item != 0);
+
+ QSignalSpy spyModelRemoved(&model, SIGNAL(itemsRemoved(int,int)));
+
+ QVERIFY(model.count() == 0);
+ QVERIFY(spyModelRemoved.count() == 0);
+
+ QVERIFY(QMetaObject::invokeMethod(item, "addItem"));
+
+ QVERIFY(model.count() == 1);
+
+ QVERIFY(QMetaObject::invokeMethod(item, "removeItemViaWorker"));
+ waitForWorker(item);
+
+ QVERIFY(model.count() == 1);
+ QVERIFY(spyModelRemoved.count() == 0);
+
+ QVERIFY(QMetaObject::invokeMethod(item, "doSync"));
+ waitForWorker(item);
+
+ QVERIFY(model.count() == 0);
+ QVERIFY(spyModelRemoved.count() == 1);
+
+ delete item;
+ qApp->processEvents();
+}
+
+void tst_qdeclarativelistmodel::worker_remove_list()
+{
+ QDeclarativeListModel model;
+ QDeclarativeEngine eng;
+ QDeclarativeComponent component(&eng, QUrl::fromLocalFile(TESTDATA("workerremovelist.qml")));
+ QQuickItem *item = createWorkerTest(&eng, &component, &model);
+ QVERIFY(item != 0);
+
+ QSignalSpy spyModelRemoved(&model, SIGNAL(itemsRemoved(int,int)));
+
+ QVERIFY(model.count() == 0);
+ QVERIFY(spyModelRemoved.count() == 0);
+
+ QVERIFY(QMetaObject::invokeMethod(item, "addList"));
+
+ QVERIFY(model.count() == 1);
+
+ QVERIFY(QMetaObject::invokeMethod(item, "removeListViaWorker"));
+ waitForWorker(item);
+
+ QVERIFY(model.count() == 1);
+ QVERIFY(spyModelRemoved.count() == 0);
+
+ QVERIFY(QMetaObject::invokeMethod(item, "doSync"));
+ waitForWorker(item);
+
+ QVERIFY(model.count() == 0);
+ QVERIFY(spyModelRemoved.count() == 1);
+
+ delete item;
+ qApp->processEvents();
+}
+
QTEST_MAIN(tst_qdeclarativelistmodel)
#include "tst_qdeclarativelistmodel.moc"
diff --git a/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp b/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp
index a85e73ed57..ce8b3357fa 100644
--- a/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp
+++ b/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp
@@ -202,17 +202,6 @@ void tst_qdeclarativemetatype::copy()
QT_COPY_TEST(QPalette, QPalette(Qt::green));
{
- QPixmap icon(100, 100);
-
- QIcon v = QIcon(icon); QIcon v2 = QIcon(icon);
- QEXPECT_FAIL("", "QTBUG-21629 - copy() test function failure.", Abort);
- QVERIFY(QDeclarativeMetaType::copy(QMetaType::QIcon, &v, 0));
- QVERIFY(v.isNull() == QIcon().isNull());
- QVERIFY(QDeclarativeMetaType::copy(QMetaType::QIcon , &v, &v2));
- QVERIFY(v.isNull() == QIcon(icon).isNull());
- }
-
- {
QImage v = QImage(100, 100, QImage::Format_RGB32);
QImage v2 = QImage(100, 100, QImage::Format_RGB32);
QVERIFY(QDeclarativeMetaType::copy(QMetaType::QImage, &v, 0));
@@ -240,7 +229,6 @@ void tst_qdeclarativemetatype::copy()
QVERIFY(v.shape() == QCursor(Qt::SizeFDiagCursor).shape());
}
- QT_COPY_TEST(QSizePolicy, QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Maximum));
QT_COPY_TEST(QKeySequence, QKeySequence("Ctrl+O"));
QT_COPY_TEST(QPen, QPen(Qt::red));
QT_COPY_TEST(QTextLength, QTextLength(QTextLength::FixedLength, 10.2));
diff --git a/tests/auto/declarative/qdeclarativeqt/data/consoleLog.qml b/tests/auto/declarative/qdeclarativeqt/data/consoleLog.qml
index 4c581cf245..afb758a21f 100644
--- a/tests/auto/declarative/qdeclarativeqt/data/consoleLog.qml
+++ b/tests/auto/declarative/qdeclarativeqt/data/consoleLog.qml
@@ -1,8 +1,30 @@
import QtQuick 2.0
QtObject {
+ id: root
Component.onCompleted: {
+ var a = [1, 2]
+ var b = {a: "hello", d: 1 }
+ var c
+ var d = 12
+ var e = function() { return 5;}
+ var f = true
+ var g = {toString: function() { throw new Error('toString'); }}
+
+
console.log("completed", "ok")
console.log("completed ok")
+ console.debug("completed ok")
+ console.warn("completed ok")
+ console.error("completed ok")
+ console.log(a)
+ console.log(b)
+ console.log(c)
+ console.log(d)
+ console.log(e)
+ console.log(f)
+ console.log(root)
+ console.log(g)
+ console.log(exception) //This has to be at the end
}
}
diff --git a/tests/auto/declarative/qdeclarativeqt/data/resolvedUrl.qml b/tests/auto/declarative/qdeclarativeqt/data/resolvedUrl.qml
new file mode 100644
index 0000000000..06ef48b82b
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeqt/data/resolvedUrl.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+
+QtObject {
+ property string result
+ property bool isString: false
+
+ Component.onCompleted: {
+ var a = Qt.resolvedUrl("resolvedUrl.qml");
+ result = a;
+ isString = (typeof a) == "string"
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp
index b4ac2dfc66..c550ac2f5b 100644
--- a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp
+++ b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp
@@ -89,6 +89,7 @@ private slots:
void atob();
void fontFamilies();
void quit();
+ void resolvedUrl();
private:
QDeclarativeEngine engine;
@@ -436,8 +437,8 @@ void tst_qdeclarativeqt::createQmlObject()
QString warning3 = component.url().toString()+ ":11: Error: Qt.createQmlObject(): failed to create object: \n " + TEST_FILE("main.qml").toString() + ":4:1: Duplicate property name";
QString warning4 = component.url().toString()+ ":9: Error: Qt.createQmlObject(): Missing parent object";
QString warning5 = component.url().toString()+ ":8: Error: Qt.createQmlObject(): Invalid arguments";
- QString warning6 = "RunTimeError: Qt.createQmlObject(): failed to create object: \n " + TEST_FILE("inline").toString() + ":3: Cannot assign object type QObject with no default method";
-
+ QString messageFormat = QString(QLatin1String("%1 (%2:%3)"));
+ QString warning6 = messageFormat.arg("RunTimeError: Qt.createQmlObject(): failed to create object: \n " + TEST_FILE("inline").toString() + ":3: Cannot assign object type QObject with no default method").arg(TEST_FILE("createQmlObject.qml").toString()).arg(23);
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning3));
@@ -460,9 +461,34 @@ void tst_qdeclarativeqt::createQmlObject()
void tst_qdeclarativeqt::consoleLog()
{
- QTest::ignoreMessage(QtDebugMsg, "completed ok");
- QTest::ignoreMessage(QtDebugMsg, "completed ok");
- QDeclarativeComponent component(&engine, TEST_FILE("consoleLog.qml"));
+ int startLineNumber = 15;
+ QUrl testFileUrl = TEST_FILE("consoleLog.qml");
+ QString testString = QString(QLatin1String("completed ok (%1:%2)")).arg(testFileUrl.toString());
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(testString.arg(startLineNumber++)));
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(testString.arg(startLineNumber++)));
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(testString.arg(startLineNumber++)));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(testString.arg(startLineNumber++)));
+ QTest::ignoreMessage(QtCriticalMsg, qPrintable(testString.arg(startLineNumber++)));
+
+ QString testArray = QString(QLatin1String("[1,2] (%1:%2)")).arg(testFileUrl.toString());
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(testArray.arg(startLineNumber++)));
+ QString testObject = QString(QLatin1String("Object (%1:%2)")).arg(testFileUrl.toString());
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(testObject.arg(startLineNumber++)));
+ QString testUndefined = QString(QLatin1String("undefined (%1:%2)")).arg(testFileUrl.toString());
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(testUndefined.arg(startLineNumber++)));
+ QString testNumber = QString(QLatin1String("12 (%1:%2)")).arg(testFileUrl.toString());
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(testNumber.arg(startLineNumber++)));
+ QString testFunction = QString(QLatin1String("function () { return 5;} (%1:%2)")).arg(testFileUrl.toString());
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(testFunction.arg(startLineNumber++)));
+ QString testBoolean = QString(QLatin1String("true (%1:%2)")).arg(testFileUrl.toString());
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(testBoolean.arg(startLineNumber++)));
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(testObject.arg(startLineNumber++)));
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(testObject.arg(startLineNumber++)));
+
+ QString testException = QString(QLatin1String("%1:%2: ReferenceError: Can't find variable: exception")).arg(testFileUrl.toString());
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(testException.arg(startLineNumber++)));
+
+ QDeclarativeComponent component(&engine, testFileUrl);
QObject *object = component.create();
QVERIFY(object != 0);
delete object;
@@ -727,6 +753,19 @@ void tst_qdeclarativeqt::quit()
delete object;
}
+void tst_qdeclarativeqt::resolvedUrl()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("resolvedUrl.qml"));
+
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("result").toString(), component.url().toString());
+ QCOMPARE(object->property("isString").toBool(), true);
+
+ delete object;
+}
+
QTEST_MAIN(tst_qdeclarativeqt)
#include "tst_qdeclarativeqt.moc"
diff --git a/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash3.qml b/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash3.qml
new file mode 100644
index 0000000000..98d4c57219
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash3.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: myRect
+ width: 400
+ height: 400
+
+ onHeightChanged: console.log("base state")
+
+ states: [
+ State {
+ name: "state1"
+ PropertyChanges {
+ target: myRect
+ onHeightChanged: console.log("state1")
+ color: "green"
+ }
+ },
+ State {
+ name: "state2";
+ PropertyChanges {
+ target: myRect
+ onHeightChanged: console.log("state2")
+ color: "red"
+ }
+ }]
+}
diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp
index f6ab6526aa..5c9760aba3 100644
--- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp
+++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp
@@ -111,6 +111,7 @@ private slots:
void signalOverride();
void signalOverrideCrash();
void signalOverrideCrash2();
+ void signalOverrideCrash3();
void parentChange();
void parentChangeErrors();
void anchorChanges();
@@ -519,6 +520,22 @@ void tst_qdeclarativestates::signalOverrideCrash2()
delete rect;
}
+void tst_qdeclarativestates::signalOverrideCrash3()
+{
+ QDeclarativeEngine engine;
+
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverrideCrash3.qml"));
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QQuickItemPrivate::get(rect)->setState("state1");
+ QQuickItemPrivate::get(rect)->setState("");
+ QQuickItemPrivate::get(rect)->setState("state2");
+ QQuickItemPrivate::get(rect)->setState("");
+
+ delete rect;
+}
+
void tst_qdeclarativestates::parentChange()
{
QDeclarativeEngine engine;
@@ -1211,8 +1228,9 @@ void tst_qdeclarativestates::tempState()
QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
- QTest::ignoreMessage(QtDebugMsg, "entering placed");
- QTest::ignoreMessage(QtDebugMsg, "entering idle");
+ QString messageFormat = QString(QLatin1String("%1 (file://%2:%3)"));
+ QTest::ignoreMessage(QtDebugMsg, messageFormat.arg(QLatin1String("entering placed")).arg(TESTDATA("legalTempState.qml")).arg(11).toLatin1());
+ QTest::ignoreMessage(QtDebugMsg, messageFormat.arg(QLatin1String("entering idle")).arg(TESTDATA("legalTempState.qml")).arg(15).toLatin1());
rectPrivate->setState("placed");
QCOMPARE(rectPrivate->state(), QLatin1String("idle"));
}
diff --git a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp
index db0e05bcf2..b9a249fa92 100644
--- a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp
+++ b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp
@@ -1059,8 +1059,9 @@ void tst_qdeclarativevaluetypes::bindingConflict()
// doesn't crash
void tst_qdeclarativevaluetypes::deletedObject()
{
+ QString messageFormat = QString(QLatin1String("%1 (%2:%3)"));
QDeclarativeComponent component(&engine, TEST_FILE("deletedObject.qml"));
- QTest::ignoreMessage(QtDebugMsg, "Test: 2");
+ QTest::ignoreMessage(QtDebugMsg, messageFormat.arg(QLatin1String("Test: 2")).arg(TEST_FILE("deletedObject.js").toString()).arg(6).toLatin1());
MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
QVERIFY(object != 0);
@@ -1068,7 +1069,7 @@ void tst_qdeclarativevaluetypes::deletedObject()
QVERIFY(dObject != 0);
delete dObject;
- QTest::ignoreMessage(QtDebugMsg, "Test: undefined");
+ QTest::ignoreMessage(QtDebugMsg, messageFormat.arg(QLatin1String("Test: undefined")).arg(TEST_FILE("deletedObject.js").toString()).arg(11).toLatin1());
object->emitRunScript();
delete object;
diff --git a/tests/auto/declarative/qdeclarativeworkerscript/data/externalObjectWorker.qml b/tests/auto/declarative/qdeclarativeworkerscript/data/externalObjectWorker.qml
new file mode 100644
index 0000000000..1dae608b50
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeworkerscript/data/externalObjectWorker.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+
+ function testExternalObject() {
+ worker.sendMessage(Qt.vector3d(1,2,3));
+ }
+
+ WorkerScript {
+ id: worker
+ source: "script.js"
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp b/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp
index bb7921c8e3..eb3413ec10 100644
--- a/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp
+++ b/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp
@@ -69,6 +69,7 @@ private slots:
void messaging_data();
void messaging_sendQObjectList();
void messaging_sendJsObject();
+ void messaging_sendExternalObject();
void script_with_pragma();
void script_included();
void scriptError_onLoad();
@@ -200,6 +201,16 @@ void tst_QDeclarativeWorkerScript::messaging_sendJsObject()
delete worker;
}
+void tst_QDeclarativeWorkerScript::messaging_sendExternalObject()
+{
+ QDeclarativeComponent component(&m_engine, TESTDATA("externalObjectWorker.qml"));
+ QObject *obj = component.create();
+ QVERIFY(obj);
+ QMetaObject::invokeMethod(obj, "testExternalObject");
+ QTest::qWait(100); // shouldn't crash.
+ delete obj;
+}
+
void tst_QDeclarativeWorkerScript::script_with_pragma()
{
QVariant value(100);
diff --git a/tests/auto/declarative/qjsengine/tst_qjsengine.cpp b/tests/auto/declarative/qjsengine/tst_qjsengine.cpp
index f83a1b3efd..8517850c5b 100644
--- a/tests/auto/declarative/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/declarative/qjsengine/tst_qjsengine.cpp
@@ -929,13 +929,11 @@ void tst_QJSEngine::jsParseDate()
}
// Date.parse() should be able to parse the output of Date().toString()
-#ifndef Q_WS_WIN // TODO: Test and remove this since 169701 has been fixed
{
QJSValue ret = eng.evaluate("var x = new Date(); var s = x.toString(); s == new Date(Date.parse(s)).toString()");
QVERIFY(ret.isBoolean());
QCOMPARE(ret.toBoolean(), true);
}
-#endif
}
void tst_QJSEngine::newQObject()
@@ -1073,7 +1071,7 @@ void tst_QJSEngine::newQObject_promoteObject()
void tst_QJSEngine::newQObject_sameQObject()
{
#if 0 // ###FIXME: No QObjectWrapOptions API
- QSKIP("This test stongly relay on strictlyEquals feature that would change in near future");
+ QSKIP("This test strongly relies on strictlyEquals feature that would change in near future");
QScriptEngine eng;
// calling newQObject() several times with same object
for (int x = 0; x < 2; ++x) {
@@ -2170,7 +2168,6 @@ void tst_QJSEngine::evaluate()
ret = eng.evaluate(code, /*fileName =*/QString(), lineNumber);
else
ret = eng.evaluate(code);
- QEXPECT_FAIL("/a/gimp", "v8 ignore invalid flags", Abort);
QCOMPARE(eng.hasUncaughtException(), expectHadError);
#if 0 // ###FIXME: No support for the line number of an uncaught exception
QEXPECT_FAIL("f()", "SyntaxError do not report line number", Continue);
diff --git a/tests/auto/declarative/qmlplugindump/tst_qmlplugindump.cpp b/tests/auto/declarative/qmlplugindump/tst_qmlplugindump.cpp
index 234d4bc04c..57e3abb72c 100644
--- a/tests/auto/declarative/qmlplugindump/tst_qmlplugindump.cpp
+++ b/tests/auto/declarative/qmlplugindump/tst_qmlplugindump.cpp
@@ -66,10 +66,16 @@ tst_qmlplugindump::tst_qmlplugindump()
void tst_qmlplugindump::initTestCase()
{
- qmlplugindumpPath = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/qmlplugindump");
-#ifdef Q_OS_WIN
- qmlplugindumpPath += QLatin1String(".exe");
+ qmlplugindumpPath = QLibraryInfo::location(QLibraryInfo::BinariesPath);
+
+#if defined(Q_OS_MAC)
+ qmlplugindumpPath += QLatin1String("/qmlplugindump.app/Contents/MacOS/qmlplugindump");
+#elif defined(Q_OS_WIN)
+ qmlplugindumpPath += QLatin1String("/qmlplugindump.exe");
+#else
+ qmlplugindumpPath += QLatin1String("/qmlplugindump");
#endif
+
if (!QFileInfo(qmlplugindumpPath).exists()) {
QString message = QString::fromLatin1("qmlplugindump executable not found (looked for %0)")
.arg(qmlplugindumpPath);
diff --git a/tests/auto/declarative/qquickanchors/data/anchors.qml b/tests/auto/declarative/qquickanchors/data/anchors.qml
new file mode 100644
index 0000000000..4be49a3468
--- /dev/null
+++ b/tests/auto/declarative/qquickanchors/data/anchors.qml
@@ -0,0 +1,162 @@
+import QtQuick 2.0
+
+Rectangle {
+ color: "white"
+ width: 240
+ height: 320
+ Rectangle { id: masterRect; objectName: "masterRect"; x: 26; width: 96; height: 20; color: "red" }
+ Rectangle {
+ id: rect1; objectName: "rect1"
+ y: 20; width: 10; height: 10
+ anchors.left: masterRect.left
+ }
+ Rectangle {
+ id: rect2; objectName: "rect2"
+ y: 20; width: 10; height: 10
+ anchors.left: masterRect.right
+ }
+ Rectangle {
+ id: rect3; objectName: "rect3"
+ y: 20; width: 10; height: 10
+ anchors.left: masterRect.horizontalCenter
+ }
+ Rectangle {
+ id: rect4; objectName: "rect4"
+ y: 30; width: 10; height: 10
+ anchors.right: masterRect.left
+ }
+ Rectangle {
+ id: rect5; objectName: "rect5"
+ y: 30; width: 10; height: 10
+ anchors.right: masterRect.right
+ }
+ Rectangle {
+ id: rect6; objectName: "rect6"
+ y: 30; width: 10; height: 10
+ anchors.right: masterRect.horizontalCenter
+ }
+ Rectangle {
+ id: rect7; objectName: "rect7"
+ y: 50; width: 10; height: 10
+ anchors.left: parent.left
+ }
+ Rectangle {
+ id: rect8; objectName: "rect8"
+ y: 50; width: 10; height: 10
+ anchors.left: parent.right
+ }
+ Rectangle {
+ id: rect9; objectName: "rect9"
+ y: 50; width: 10; height: 10
+ anchors.left: parent.horizontalCenter
+ }
+ Rectangle {
+ id: rect10; objectName: "rect10"
+ y: 60; width: 10; height: 10
+ anchors.right: parent.left
+ }
+ Rectangle {
+ id: rect11; objectName: "rect11"
+ y: 60; width: 10; height: 10
+ anchors.right: parent.right
+ }
+ Rectangle {
+ id: rect12; objectName: "rect12"
+ y: 60; width: 10; height: 10
+ anchors.right: parent.horizontalCenter
+ }
+ Rectangle {
+ id: rect13; objectName: "rect13"
+ x: 200; width: 10; height: 10
+ anchors.top: masterRect.bottom
+ }
+ Rectangle {
+ id: rect14; objectName: "rect14"
+ width: 10; height: 10; color: "steelblue"
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ Rectangle {
+ id: rect15; objectName: "rect15"
+ y: 200; height: 10
+ anchors.left: masterRect.left
+ anchors.right: masterRect.right
+ }
+ Rectangle {
+ id: rect16; objectName: "rect16"
+ y: 220; height: 10
+ anchors.left: masterRect.left
+ anchors.horizontalCenter: masterRect.right
+ }
+ Rectangle {
+ id: rect17; objectName: "rect17"
+ y: 240; height: 10
+ anchors.right: masterRect.right
+ anchors.horizontalCenter: masterRect.left
+ }
+ Rectangle {
+ id: rect18; objectName: "rect18"
+ x: 180; width: 10
+ anchors.top: masterRect.bottom
+ anchors.bottom: rect12.top
+ }
+ Rectangle {
+ id: rect19; objectName: "rect19"
+ y: 70; width: 10; height: 10
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ Rectangle {
+ id: rect20; objectName: "rect20"
+ y: 70; width: 10; height: 10
+ anchors.horizontalCenter: parent.right
+ }
+ Rectangle {
+ id: rect21; objectName: "rect21"
+ y: 70; width: 10; height: 10
+ anchors.horizontalCenter: parent.left
+ }
+ Rectangle {
+ id: rect22; objectName: "rect22"
+ width: 10; height: 10
+ anchors.centerIn: masterRect
+ }
+ Rectangle {
+ id: rect23; objectName: "rect23"
+ anchors.left: masterRect.left
+ anchors.leftMargin: 5
+ anchors.right: masterRect.right
+ anchors.rightMargin: 5
+ anchors.top: masterRect.top
+ anchors.topMargin: 5
+ anchors.bottom: masterRect.bottom
+ anchors.bottomMargin: 5
+ }
+ Rectangle {
+ id: rect24; objectName: "rect24"
+ width: 10; height: 10
+ anchors.horizontalCenter: masterRect.left
+ anchors.horizontalCenterOffset: width/2
+ }
+ Rectangle {
+ id: rect25; objectName: "rect25"
+ width: 10; height: 10
+ anchors.verticalCenter: rect12.top
+ anchors.verticalCenterOffset: height/2
+ }
+ Rectangle {
+ id: rect26; objectName: "rect26"
+ width: 10; height: 10
+ anchors.baseline: masterRect.top
+ anchors.baselineOffset: height/2
+ }
+ Text {
+ id: text1; objectName: "text1"
+ y: 200;
+ text: "Hello"
+ }
+ Text {
+ id: text2; objectName: "text2"
+ anchors.baseline: text1.baseline
+ anchors.left: text1.right
+ text: "World"
+ }
+}
diff --git a/tests/auto/declarative/qquickanchors/data/centerin.qml b/tests/auto/declarative/qquickanchors/data/centerin.qml
new file mode 100644
index 0000000000..e5f64f1e47
--- /dev/null
+++ b/tests/auto/declarative/qquickanchors/data/centerin.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 200; height: 200
+ Rectangle {
+ objectName: "centered"
+ width: 50; height: 50; color: "blue"
+ anchors.centerIn: parent;
+ anchors.verticalCenterOffset: 30
+ anchors.horizontalCenterOffset: 10
+ }
+}
diff --git a/tests/auto/declarative/qquickanchors/data/centerinRotation.qml b/tests/auto/declarative/qquickanchors/data/centerinRotation.qml
new file mode 100644
index 0000000000..933a25c100
--- /dev/null
+++ b/tests/auto/declarative/qquickanchors/data/centerinRotation.qml
@@ -0,0 +1,17 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 200; height: 200
+ Rectangle {
+ objectName: "outer"
+ rotation: 90
+ width: 101; height: 101; color: "blue"
+ anchors.centerIn: parent;
+
+ Rectangle {
+ objectName: "inner"
+ width: 50; height: 50; color: "blue"
+ anchors.centerIn: parent;
+ }
+ }
+}
diff --git a/tests/auto/declarative/qquickanchors/data/crash1.qml b/tests/auto/declarative/qquickanchors/data/crash1.qml
new file mode 100644
index 0000000000..98dd6cfa41
--- /dev/null
+++ b/tests/auto/declarative/qquickanchors/data/crash1.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.0
+
+Column {
+ Text {
+ text: "foo"
+ anchors.fill: parent
+ }
+ Text {
+ text: "bar"
+ }
+}
diff --git a/tests/auto/declarative/qquickanchors/data/fill.qml b/tests/auto/declarative/qquickanchors/data/fill.qml
new file mode 100644
index 0000000000..08db199d7b
--- /dev/null
+++ b/tests/auto/declarative/qquickanchors/data/fill.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 200; height: 200
+ Rectangle {
+ objectName: "filler"
+ width: 50; height: 50; color: "blue"
+ anchors.fill: parent;
+ anchors.leftMargin: 10;
+ anchors.rightMargin: 20;
+ anchors.topMargin: 30;
+ anchors.bottomMargin: 40;
+ }
+}
diff --git a/tests/auto/declarative/qquickanchors/data/hvCenter.qml b/tests/auto/declarative/qquickanchors/data/hvCenter.qml
new file mode 100644
index 0000000000..6763f8eb75
--- /dev/null
+++ b/tests/auto/declarative/qquickanchors/data/hvCenter.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 77; height: 95
+ Rectangle {
+ objectName: "centered"
+ width: 57; height: 57; color: "blue"
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+}
diff --git a/tests/auto/declarative/qquickanchors/data/loop1.qml b/tests/auto/declarative/qquickanchors/data/loop1.qml
new file mode 100644
index 0000000000..342b2af052
--- /dev/null
+++ b/tests/auto/declarative/qquickanchors/data/loop1.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: rect
+ width: 120; height: 200; color: "white"
+ Text { id: text1; anchors.right: text2.right; text: "Hello" }
+ Text { id: text2; anchors.right: text1.right; anchors.rightMargin: 10; text: "World" }
+}
diff --git a/tests/auto/declarative/qquickanchors/data/loop2.qml b/tests/auto/declarative/qquickanchors/data/loop2.qml
new file mode 100644
index 0000000000..e1875be025
--- /dev/null
+++ b/tests/auto/declarative/qquickanchors/data/loop2.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: container;
+ width: 600;
+ height: 600;
+
+ Image {
+ id: image1
+ source: "http://labs.trolltech.com/blogs/wp-content/uploads/2009/03/3311388091_ac2a257feb.jpg"
+ anchors.right: image2.left
+ }
+
+ Image {
+ id: image2
+ source: "http://labs.trolltech.com/blogs/wp-content/uploads/2009/03/oslo_groupphoto.jpg"
+ anchors.left: image1.right
+ anchors.leftMargin: 20
+ }
+}
diff --git a/tests/auto/declarative/qquickanchors/data/margins.qml b/tests/auto/declarative/qquickanchors/data/margins.qml
new file mode 100644
index 0000000000..9403f65a61
--- /dev/null
+++ b/tests/auto/declarative/qquickanchors/data/margins.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 200; height: 200
+ Rectangle {
+ objectName: "filler"
+ width: 50; height: 50; color: "blue"
+ anchors.fill: parent;
+ anchors.margins: 10
+ anchors.leftMargin: 5
+ anchors.topMargin: 6
+ }
+}
diff --git a/tests/auto/declarative/qquickanchors/qquickanchors.pro b/tests/auto/declarative/qquickanchors/qquickanchors.pro
new file mode 100644
index 0000000000..0d085d367d
--- /dev/null
+++ b/tests/auto/declarative/qquickanchors/qquickanchors.pro
@@ -0,0 +1,12 @@
+TARGET = tst_qquickanchors
+CONFIG += testcase
+SOURCES += tst_qquickanchors.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private v8-private testlib
diff --git a/tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp b/tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp
new file mode 100644
index 0000000000..cfdab7f14c
--- /dev/null
+++ b/tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp
@@ -0,0 +1,693 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qtest.h>
+#include <QSignalSpy>
+#include <private/qquickitem_p.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qquickview.h>
+#include <QtDeclarative/private/qquickrectangle_p.h>
+#include <QtDeclarative/private/qquicktext_p.h>
+#include <QtDeclarative/private/qquickanchors_p_p.h>
+#include <QtDeclarative/private/qquickitem_p.h>
+#include "../shared/util.h"
+
+Q_DECLARE_METATYPE(QQuickAnchors::Anchor)
+Q_DECLARE_METATYPE(QQuickAnchorLine::AnchorLine)
+
+class tst_qquickanchors : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qquickanchors() {}
+
+private slots:
+ void basicAnchors();
+ void basicAnchorsRTL();
+ void loops();
+ void illegalSets();
+ void illegalSets_data();
+ void reset();
+ void reset_data();
+ void resetConvenience();
+ void nullItem();
+ void nullItem_data();
+ void crash1();
+ void centerIn();
+ void centerInRTL();
+ void centerInRotation();
+ void hvCenter();
+ void hvCenterRTL();
+ void fill();
+ void fillRTL();
+ void margins();
+ void marginsRTL();
+};
+
+/*
+ Find an item with the specified objectName.
+*/
+template<typename T>
+T *findItem(QQuickItem *parent, const QString &objectName)
+{
+ if (!parent)
+ return 0;
+
+ const QMetaObject &mo = T::staticMetaObject;
+ //qDebug() << parent->QQuickItem::children().count() << "children";
+ for (int i = 0; i < parent->childItems().count(); ++i) {
+ QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
+ if (!item)
+ continue;
+ //qDebug() << "try" << item;
+ if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
+ return static_cast<T*>(item);
+ item = findItem<T>(item, objectName);
+ if (item)
+ return static_cast<T*>(item);
+ }
+
+ return 0;
+}
+
+void tst_qquickanchors::basicAnchors()
+{
+ QQuickView *view = new QQuickView;
+ view->setSource(QUrl::fromLocalFile(TESTDATA("anchors.qml")));
+
+ qApp->processEvents();
+
+ //sibling horizontal
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect1"))->x(), 26.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect2"))->x(), 122.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect3"))->x(), 74.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect4"))->x(), 16.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect5"))->x(), 112.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect6"))->x(), 64.0);
+
+ //parent horizontal
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect7"))->x(), 0.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect8"))->x(), 240.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect9"))->x(), 120.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect10"))->x(), -10.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect11"))->x(), 230.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect12"))->x(), 110.0);
+
+ //vertical
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect13"))->y(), 20.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect14"))->y(), 155.0);
+
+ //stretch
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect15"))->x(), 26.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect15"))->width(), 96.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect16"))->x(), 26.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect16"))->width(), 192.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect17"))->x(), -70.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect17"))->width(), 192.0);
+
+ //vertical stretch
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect18"))->y(), 20.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect18"))->height(), 40.0);
+
+ //more parent horizontal
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect19"))->x(), 115.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect20"))->x(), 235.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect21"))->x(), -5.0);
+
+ //centerIn
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect22"))->x(), 69.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect22"))->y(), 5.0);
+
+ //margins
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect23"))->x(), 31.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect23"))->y(), 5.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect23"))->width(), 86.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect23"))->height(), 10.0);
+
+ // offsets
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect24"))->x(), 26.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect25"))->y(), 60.0);
+ QCOMPARE(findItem<QQuickRectangle>(view->rootObject(), QLatin1String("rect26"))->y(), 5.0);
+
+ //baseline
+ QQuickText *text1 = findItem<QQuickText>(view->rootObject(), QLatin1String("text1"));
+ QQuickText *text2 = findItem<QQuickText>(view->rootObject(), QLatin1String("text2"));
+ QCOMPARE(text1->y(), text2->y());
+
+ delete view;
+}
+
+QQuickItem* childItem(QQuickItem *parentItem, const char * itemString) {
+ return findItem<QQuickItem>(parentItem, QLatin1String(itemString));
+}
+
+qreal offsetMasterRTL(QQuickItem *rootItem, const char * itemString) {
+ QQuickItem* masterItem = findItem<QQuickItem>(rootItem, QLatin1String("masterRect"));
+ return masterItem->width()+2*masterItem->x()-findItem<QQuickItem>(rootItem, QLatin1String(itemString))->width();
+}
+
+qreal offsetParentRTL(QQuickItem *rootItem, const char * itemString) {
+ return rootItem->width()+2*rootItem->x()-findItem<QQuickItem>(rootItem, QLatin1String(itemString))->width();
+}
+
+void mirrorAnchors(QQuickItem *item) {
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->setLayoutMirror(true);
+}
+
+void tst_qquickanchors::basicAnchorsRTL()
+{
+ QQuickView *view = new QQuickView;
+ view->setSource(QUrl::fromLocalFile(TESTDATA("anchors.qml")));
+
+ qApp->processEvents();
+
+ QQuickItem* rootItem = qobject_cast<QQuickItem*>(view->rootObject());
+ foreach (QObject *child, rootItem->children()) {
+ bool mirrored = QQuickItemPrivate::get(qobject_cast<QQuickItem*>(child))->anchors()->property("mirrored").toBool();
+ QCOMPARE(mirrored, false);
+ }
+
+ foreach (QObject *child, rootItem->children())
+ mirrorAnchors(qobject_cast<QQuickItem*>(child));
+
+ foreach (QObject *child, rootItem->children()) {
+ bool mirrored = QQuickItemPrivate::get(qobject_cast<QQuickItem*>(child))->anchors()->property("mirrored").toBool();
+ QCOMPARE(mirrored, true);
+ }
+
+ //sibling horizontal
+ QCOMPARE(childItem(rootItem, "rect1")->x(), offsetMasterRTL(rootItem, "rect1")-26.0);
+ QCOMPARE(childItem(rootItem, "rect2")->x(), offsetMasterRTL(rootItem, "rect2")-122.0);
+ QCOMPARE(childItem(rootItem, "rect3")->x(), offsetMasterRTL(rootItem, "rect3")-74.0);
+ QCOMPARE(childItem(rootItem, "rect4")->x(), offsetMasterRTL(rootItem, "rect4")-16.0);
+ QCOMPARE(childItem(rootItem, "rect5")->x(), offsetMasterRTL(rootItem, "rect5")-112.0);
+ QCOMPARE(childItem(rootItem, "rect6")->x(), offsetMasterRTL(rootItem, "rect6")-64.0);
+
+ //parent horizontal
+ QCOMPARE(childItem(rootItem, "rect7")->x(), offsetParentRTL(rootItem, "rect7")-0.0);
+ QCOMPARE(childItem(rootItem, "rect8")->x(), offsetParentRTL(rootItem, "rect8")-240.0);
+ QCOMPARE(childItem(rootItem, "rect9")->x(), offsetParentRTL(rootItem, "rect9")-120.0);
+ QCOMPARE(childItem(rootItem, "rect10")->x(), offsetParentRTL(rootItem, "rect10")+10.0);
+ QCOMPARE(childItem(rootItem, "rect11")->x(), offsetParentRTL(rootItem, "rect11")-230.0);
+ QCOMPARE(childItem(rootItem, "rect12")->x(), offsetParentRTL(rootItem, "rect12")-110.0);
+
+ //vertical
+ QCOMPARE(childItem(rootItem, "rect13")->y(), 20.0);
+ QCOMPARE(childItem(rootItem, "rect14")->y(), 155.0);
+
+ //stretch
+ QCOMPARE(childItem(rootItem, "rect15")->x(), offsetMasterRTL(rootItem, "rect15")-26.0);
+ QCOMPARE(childItem(rootItem, "rect15")->width(), 96.0);
+ QCOMPARE(childItem(rootItem, "rect16")->x(), offsetMasterRTL(rootItem, "rect16")-26.0);
+ QCOMPARE(childItem(rootItem, "rect16")->width(), 192.0);
+ QCOMPARE(childItem(rootItem, "rect17")->x(), offsetMasterRTL(rootItem, "rect17")+70.0);
+ QCOMPARE(childItem(rootItem, "rect17")->width(), 192.0);
+
+ //vertical stretch
+ QCOMPARE(childItem(rootItem, "rect18")->y(), 20.0);
+ QCOMPARE(childItem(rootItem, "rect18")->height(), 40.0);
+
+ //more parent horizontal
+ QCOMPARE(childItem(rootItem, "rect19")->x(), offsetParentRTL(rootItem, "rect19")-115.0);
+ QCOMPARE(childItem(rootItem, "rect20")->x(), offsetParentRTL(rootItem, "rect20")-235.0);
+ QCOMPARE(childItem(rootItem, "rect21")->x(), offsetParentRTL(rootItem, "rect21")+5.0);
+
+ //centerIn
+ QCOMPARE(childItem(rootItem, "rect22")->x(), offsetMasterRTL(rootItem, "rect22")-69.0);
+ QCOMPARE(childItem(rootItem, "rect22")->y(), 5.0);
+
+ //margins
+ QCOMPARE(childItem(rootItem, "rect23")->x(), offsetMasterRTL(rootItem, "rect23")-31.0);
+ QCOMPARE(childItem(rootItem, "rect23")->y(), 5.0);
+ QCOMPARE(childItem(rootItem, "rect23")->width(), 86.0);
+ QCOMPARE(childItem(rootItem, "rect23")->height(), 10.0);
+
+ // offsets
+ QCOMPARE(childItem(rootItem, "rect24")->x(), offsetMasterRTL(rootItem, "rect24")-26.0);
+ QCOMPARE(childItem(rootItem, "rect25")->y(), 60.0);
+ QCOMPARE(childItem(rootItem, "rect26")->y(), 5.0);
+
+ //baseline
+ QQuickText *text1 = findItem<QQuickText>(rootItem, QLatin1String("text1"));
+ QQuickText *text2 = findItem<QQuickText>(rootItem, QLatin1String("text2"));
+ QCOMPARE(text1->y(), text2->y());
+
+ delete view;
+}
+
+// mostly testing that we don't crash
+void tst_qquickanchors::loops()
+{
+ {
+ QUrl source(QUrl::fromLocalFile(TESTDATA("loop1.qml")));
+
+ QString expect = source.toString() + ":6:5: QML Text: Possible anchor loop detected on horizontal anchor.";
+ QTest::ignoreMessage(QtWarningMsg, expect.toLatin1());
+ QTest::ignoreMessage(QtWarningMsg, expect.toLatin1());
+ QTest::ignoreMessage(QtWarningMsg, expect.toLatin1());
+
+ QQuickView *view = new QQuickView;
+ view->setSource(source);
+ qApp->processEvents();
+
+ delete view;
+ }
+
+ {
+ QUrl source(QUrl::fromLocalFile(TESTDATA("loop2.qml")));
+
+ QString expect = source.toString() + ":8:3: QML Image: Possible anchor loop detected on horizontal anchor.";
+ QTest::ignoreMessage(QtWarningMsg, expect.toLatin1());
+
+ QQuickView *view = new QQuickView;
+ view->setSource(source);
+ qApp->processEvents();
+
+ delete view;
+ }
+}
+
+void tst_qquickanchors::illegalSets()
+{
+ QFETCH(QString, qml);
+ QFETCH(QString, warning);
+
+ QTest::ignoreMessage(QtWarningMsg, warning.toLatin1());
+
+ QDeclarativeEngine engine;
+ QDeclarativeComponent component(&engine);
+ component.setData(QByteArray("import QtQuick 1.0\n" + qml.toUtf8()), QUrl::fromLocalFile(""));
+ if (!component.isReady())
+ qWarning() << "Test errors:" << component.errors();
+ QVERIFY(component.isReady());
+ QObject *o = component.create();
+ delete o;
+}
+
+void tst_qquickanchors::illegalSets_data()
+{
+ QTest::addColumn<QString>("qml");
+ QTest::addColumn<QString>("warning");
+
+ QTest::newRow("H - too many anchors")
+ << "Rectangle { id: rect; Rectangle { anchors.left: rect.left; anchors.right: rect.right; anchors.horizontalCenter: rect.horizontalCenter } }"
+ << "file::2:23: QML Rectangle: Cannot specify left, right, and hcenter anchors.";
+
+ foreach (const QString &side, QStringList() << "left" << "right") {
+ QTest::newRow("H - anchor to V")
+ << QString("Rectangle { Rectangle { anchors.%1: parent.top } }").arg(side)
+ << "file::2:13: QML Rectangle: Cannot anchor a horizontal edge to a vertical edge.";
+
+ QTest::newRow("H - anchor to non parent/sibling")
+ << QString("Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.%1: rect.%1 } }").arg(side)
+ << "file::2:45: QML Rectangle: Cannot anchor to an item that isn't a parent or sibling.";
+
+ QTest::newRow("H - anchor to self")
+ << QString("Rectangle { id: rect; anchors.%1: rect.%1 }").arg(side)
+ << "file::2:1: QML Rectangle: Cannot anchor item to self.";
+ }
+
+
+ QTest::newRow("V - too many anchors")
+ << "Rectangle { id: rect; Rectangle { anchors.top: rect.top; anchors.bottom: rect.bottom; anchors.verticalCenter: rect.verticalCenter } }"
+ << "file::2:23: QML Rectangle: Cannot specify top, bottom, and vcenter anchors.";
+
+ QTest::newRow("V - too many anchors with baseline")
+ << "Rectangle { Text { id: text1; text: \"Hello\" } Text { anchors.baseline: text1.baseline; anchors.top: text1.top; } }"
+ << "file::2:47: QML Text: Baseline anchor cannot be used in conjunction with top, bottom, or vcenter anchors.";
+
+ foreach (const QString &side, QStringList() << "top" << "bottom" << "baseline") {
+
+ QTest::newRow("V - anchor to H")
+ << QString("Rectangle { Rectangle { anchors.%1: parent.left } }").arg(side)
+ << "file::2:13: QML Rectangle: Cannot anchor a vertical edge to a horizontal edge.";
+
+ QTest::newRow("V - anchor to non parent/sibling")
+ << QString("Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.%1: rect.%1 } }").arg(side)
+ << "file::2:45: QML Rectangle: Cannot anchor to an item that isn't a parent or sibling.";
+
+ QTest::newRow("V - anchor to self")
+ << QString("Rectangle { id: rect; anchors.%1: rect.%1 }").arg(side)
+ << "file::2:1: QML Rectangle: Cannot anchor item to self.";
+ }
+
+
+ QTest::newRow("centerIn - anchor to non parent/sibling")
+ << "Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.centerIn: rect} }"
+ << "file::2:45: QML Rectangle: Cannot anchor to an item that isn't a parent or sibling.";
+
+
+ QTest::newRow("fill - anchor to non parent/sibling")
+ << "Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.fill: rect} }"
+ << "file::2:45: QML Rectangle: Cannot anchor to an item that isn't a parent or sibling.";
+}
+
+void tst_qquickanchors::reset()
+{
+ QFETCH(QString, side);
+ QFETCH(QQuickAnchorLine::AnchorLine, anchorLine);
+ QFETCH(QQuickAnchors::Anchor, usedAnchor);
+
+ QQuickItem *baseItem = new QQuickItem;
+
+ QQuickAnchorLine anchor;
+ anchor.item = baseItem;
+ anchor.anchorLine = anchorLine;
+
+ QQuickItem *item = new QQuickItem;
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+
+ const QMetaObject *meta = itemPrivate->anchors()->metaObject();
+ QMetaProperty p = meta->property(meta->indexOfProperty(side.toUtf8().constData()));
+
+ QVERIFY(p.write(itemPrivate->anchors(), qVariantFromValue(anchor)));
+ QCOMPARE(itemPrivate->anchors()->usedAnchors().testFlag(usedAnchor), true);
+
+ QVERIFY(p.reset(itemPrivate->anchors()));
+ QCOMPARE(itemPrivate->anchors()->usedAnchors().testFlag(usedAnchor), false);
+
+ delete item;
+ delete baseItem;
+}
+
+void tst_qquickanchors::reset_data()
+{
+ QTest::addColumn<QString>("side");
+ QTest::addColumn<QQuickAnchorLine::AnchorLine>("anchorLine");
+ QTest::addColumn<QQuickAnchors::Anchor>("usedAnchor");
+
+ QTest::newRow("left") << "left" << QQuickAnchorLine::Left << QQuickAnchors::LeftAnchor;
+ QTest::newRow("top") << "top" << QQuickAnchorLine::Top << QQuickAnchors::TopAnchor;
+ QTest::newRow("right") << "right" << QQuickAnchorLine::Right << QQuickAnchors::RightAnchor;
+ QTest::newRow("bottom") << "bottom" << QQuickAnchorLine::Bottom << QQuickAnchors::BottomAnchor;
+
+ QTest::newRow("hcenter") << "horizontalCenter" << QQuickAnchorLine::HCenter << QQuickAnchors::HCenterAnchor;
+ QTest::newRow("vcenter") << "verticalCenter" << QQuickAnchorLine::VCenter << QQuickAnchors::VCenterAnchor;
+ QTest::newRow("baseline") << "baseline" << QQuickAnchorLine::Baseline << QQuickAnchors::BaselineAnchor;
+}
+
+void tst_qquickanchors::resetConvenience()
+{
+ QQuickItem *baseItem = new QQuickItem;
+ QQuickItem *item = new QQuickItem;
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+
+ //fill
+ itemPrivate->anchors()->setFill(baseItem);
+ QVERIFY(itemPrivate->anchors()->fill() == baseItem);
+ itemPrivate->anchors()->resetFill();
+ QVERIFY(itemPrivate->anchors()->fill() == 0);
+
+ //centerIn
+ itemPrivate->anchors()->setCenterIn(baseItem);
+ QVERIFY(itemPrivate->anchors()->centerIn() == baseItem);
+ itemPrivate->anchors()->resetCenterIn();
+ QVERIFY(itemPrivate->anchors()->centerIn() == 0);
+
+ delete item;
+ delete baseItem;
+}
+
+void tst_qquickanchors::nullItem()
+{
+ QFETCH(QString, side);
+
+ QQuickAnchorLine anchor;
+ QQuickItem *item = new QQuickItem;
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+
+ const QMetaObject *meta = itemPrivate->anchors()->metaObject();
+ QMetaProperty p = meta->property(meta->indexOfProperty(side.toUtf8().constData()));
+
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML Item: Cannot anchor to a null item.");
+ QVERIFY(p.write(itemPrivate->anchors(), qVariantFromValue(anchor)));
+
+ delete item;
+}
+
+void tst_qquickanchors::nullItem_data()
+{
+ QTest::addColumn<QString>("side");
+
+ QTest::newRow("left") << "left";
+ QTest::newRow("top") << "top";
+ QTest::newRow("right") << "right";
+ QTest::newRow("bottom") << "bottom";
+
+ QTest::newRow("hcenter") << "horizontalCenter";
+ QTest::newRow("vcenter") << "verticalCenter";
+ QTest::newRow("baseline") << "baseline";
+}
+
+//QTBUG-5428
+void tst_qquickanchors::crash1()
+{
+ QUrl source(QUrl::fromLocalFile(TESTDATA("crash1.qml")));
+
+ QString expect = source.toString() + ":3:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column";
+
+ QTest::ignoreMessage(QtWarningMsg, expect.toLatin1());
+
+ QQuickView *view = new QQuickView(source);
+ qApp->processEvents();
+
+ delete view;
+}
+
+void tst_qquickanchors::fill()
+{
+ QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("fill.qml")));
+
+ qApp->processEvents();
+ QQuickRectangle* rect = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("filler"));
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QCOMPARE(rect->x(), 0.0 + 10.0);
+ QCOMPARE(rect->y(), 0.0 + 30.0);
+ QCOMPARE(rect->width(), 200.0 - 10.0 - 20.0);
+ QCOMPARE(rect->height(), 200.0 - 30.0 - 40.0);
+ //Alter Offsets (tests QTBUG-6631)
+ rectPrivate->anchors()->setLeftMargin(20.0);
+ rectPrivate->anchors()->setRightMargin(0.0);
+ rectPrivate->anchors()->setBottomMargin(0.0);
+ rectPrivate->anchors()->setTopMargin(10.0);
+ QCOMPARE(rect->x(), 0.0 + 20.0);
+ QCOMPARE(rect->y(), 0.0 + 10.0);
+ QCOMPARE(rect->width(), 200.0 - 20.0);
+ QCOMPARE(rect->height(), 200.0 - 10.0);
+
+ delete view;
+}
+
+void tst_qquickanchors::fillRTL()
+{
+ QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("fill.qml")));
+
+ qApp->processEvents();
+ QQuickRectangle* rect = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("filler"));
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ mirrorAnchors(rect);
+
+ QCOMPARE(rect->x(), 0.0 + 20.0);
+ QCOMPARE(rect->y(), 0.0 + 30.0);
+ QCOMPARE(rect->width(), 200.0 - 10.0 - 20.0);
+ QCOMPARE(rect->height(), 200.0 - 30.0 - 40.0);
+ //Alter Offsets (tests QTBUG-6631)
+ rectPrivate->anchors()->setLeftMargin(20.0);
+ rectPrivate->anchors()->setRightMargin(0.0);
+ rectPrivate->anchors()->setBottomMargin(0.0);
+ rectPrivate->anchors()->setTopMargin(10.0);
+ QCOMPARE(rect->x(), 0.0 + 0.0);
+ QCOMPARE(rect->y(), 0.0 + 10.0);
+ QCOMPARE(rect->width(), 200.0 - 20.0);
+ QCOMPARE(rect->height(), 200.0 - 10.0);
+
+ delete view;
+}
+
+void tst_qquickanchors::centerIn()
+{
+ QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("centerin.qml")));
+
+ qApp->processEvents();
+ QQuickRectangle* rect = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("centered"));
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+
+ QCOMPARE(rect->x(), 75.0 + 10);
+ QCOMPARE(rect->y(), 75.0 + 30);
+ //Alter Offsets (tests QTBUG-6631)
+ rectPrivate->anchors()->setHorizontalCenterOffset(-20.0);
+ rectPrivate->anchors()->setVerticalCenterOffset(-10.0);
+ QCOMPARE(rect->x(), 75.0 - 20.0);
+ QCOMPARE(rect->y(), 75.0 - 10.0);
+
+ delete view;
+}
+
+void tst_qquickanchors::centerInRTL()
+{
+ QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("centerin.qml")));
+
+ qApp->processEvents();
+ QQuickRectangle* rect = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("centered"));
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ mirrorAnchors(rect);
+
+ QCOMPARE(rect->x(), 75.0 - 10);
+ QCOMPARE(rect->y(), 75.0 + 30);
+ //Alter Offsets (tests QTBUG-6631)
+ rectPrivate->anchors()->setHorizontalCenterOffset(-20.0);
+ rectPrivate->anchors()->setVerticalCenterOffset(-10.0);
+ QCOMPARE(rect->x(), 75.0 + 20.0);
+ QCOMPARE(rect->y(), 75.0 - 10.0);
+
+ delete view;
+}
+
+//QTBUG-12441
+void tst_qquickanchors::centerInRotation()
+{
+ QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("centerinRotation.qml")));
+
+ qApp->processEvents();
+ QQuickRectangle* outer = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("outer"));
+ QQuickRectangle* inner = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("inner"));
+
+ QEXPECT_FAIL("", "QTBUG-12441", Abort);
+ QCOMPARE(outer->x(), qreal(49.5));
+ QCOMPARE(outer->y(), qreal(49.5));
+ QCOMPARE(inner->x(), qreal(25.5));
+ QCOMPARE(inner->y(), qreal(25.5));
+
+ delete view;
+}
+
+void tst_qquickanchors::hvCenter()
+{
+ QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("hvCenter.qml")));
+
+ qApp->processEvents();
+ QQuickRectangle* rect = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("centered"));
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+
+ // test QTBUG-10999
+ QCOMPARE(rect->x(), 10.0);
+ QCOMPARE(rect->y(), 19.0);
+
+ rectPrivate->anchors()->setHorizontalCenterOffset(-5.0);
+ rectPrivate->anchors()->setVerticalCenterOffset(5.0);
+ QCOMPARE(rect->x(), 10.0 - 5.0);
+ QCOMPARE(rect->y(), 19.0 + 5.0);
+
+ delete view;
+}
+
+void tst_qquickanchors::hvCenterRTL()
+{
+ QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("hvCenter.qml")));
+
+ qApp->processEvents();
+ QQuickRectangle* rect = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("centered"));
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ mirrorAnchors(rect);
+
+ // test QTBUG-10999
+ QCOMPARE(rect->x(), 10.0);
+ QCOMPARE(rect->y(), 19.0);
+
+ rectPrivate->anchors()->setHorizontalCenterOffset(-5.0);
+ rectPrivate->anchors()->setVerticalCenterOffset(5.0);
+ QCOMPARE(rect->x(), 10.0 + 5.0);
+ QCOMPARE(rect->y(), 19.0 + 5.0);
+
+ delete view;
+}
+void tst_qquickanchors::margins()
+{
+ QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("margins.qml")));
+
+ qApp->processEvents();
+ QQuickRectangle* rect = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("filler"));
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ QCOMPARE(rect->x(), 5.0);
+ QCOMPARE(rect->y(), 6.0);
+ QCOMPARE(rect->width(), 200.0 - 5.0 - 10.0);
+ QCOMPARE(rect->height(), 200.0 - 6.0 - 10.0);
+
+ rectPrivate->anchors()->setTopMargin(0.0);
+ rectPrivate->anchors()->setMargins(20.0);
+
+ QCOMPARE(rect->x(), 5.0);
+ QCOMPARE(rect->y(), 20.0);
+ QCOMPARE(rect->width(), 200.0 - 5.0 - 20.0);
+ QCOMPARE(rect->height(), 200.0 - 20.0 - 20.0);
+
+ delete view;
+}
+
+void tst_qquickanchors::marginsRTL()
+{
+ QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("margins.qml")));
+
+ QQuickRectangle* rect = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("filler"));
+ QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+ mirrorAnchors(rect);
+
+ QCOMPARE(rect->x(), 10.0);
+ QCOMPARE(rect->y(), 6.0);
+ QCOMPARE(rect->width(), 200.0 - 5.0 - 10.0);
+ QCOMPARE(rect->height(), 200.0 - 6.0 - 10.0);
+
+ rectPrivate->anchors()->setTopMargin(0.0);
+ rectPrivate->anchors()->setMargins(20.0);
+
+ QCOMPARE(rect->x(), 20.0);
+ QCOMPARE(rect->y(), 20.0);
+ QCOMPARE(rect->width(), 200.0 - 5.0 - 20.0);
+ QCOMPARE(rect->height(), 200.0 - 20.0 - 20.0);
+
+ delete view;
+}
+
+
+QTEST_MAIN(tst_qquickanchors)
+
+#include "tst_qquickanchors.moc"
diff --git a/tests/auto/declarative/qquickcanvas/tst_qquickcanvas.cpp b/tests/auto/declarative/qquickcanvas/tst_qquickcanvas.cpp
index d2b691d461..640b4b4f40 100644
--- a/tests/auto/declarative/qquickcanvas/tst_qquickcanvas.cpp
+++ b/tests/auto/declarative/qquickcanvas/tst_qquickcanvas.cpp
@@ -153,8 +153,9 @@ protected:
mousePressId = ++mousePressNum;
}
- bool childMouseEventFilter(QQuickItem *, QEvent *) {
- mousePressId = ++mousePressNum;
+ bool childMouseEventFilter(QQuickItem *, QEvent *event) {
+ if (event->type() == QEvent::MouseButtonPress)
+ mousePressId = ++mousePressNum;
return false;
}
diff --git a/tests/auto/declarative/qquickflickable/tst_qquickflickable.cpp b/tests/auto/declarative/qquickflickable/tst_qquickflickable.cpp
index 2f155e298e..a02db06616 100644
--- a/tests/auto/declarative/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/declarative/qquickflickable/tst_qquickflickable.cpp
@@ -533,7 +533,7 @@ void tst_qquickflickable::disabled()
void tst_qquickflickable::flickVelocity()
{
-#ifdef Q_WS_MAC
+#ifdef Q_OS_MAC
QSKIP("Producing flicks on Mac CI impossible due to timing problems");
#endif
diff --git a/tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp b/tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp
index ffb9660262..d0149ed1d6 100644
--- a/tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp
+++ b/tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp
@@ -557,6 +557,7 @@ void tst_qquickfocusscope::canvasFocus()
QSignalSpy scope2ActiveFocusSpy(scope2, SIGNAL(activeFocusChanged(bool)));
QSignalSpy item2ActiveFocusSpy(item2, SIGNAL(activeFocusChanged(bool)));
+ QEXPECT_FAIL("", "QTBUG-22415", Abort);
QCOMPARE(rootItem->hasFocus(), false);
QCOMPARE(rootItem->hasActiveFocus(), false);
QCOMPARE(scope1->hasFocus(), true);
@@ -585,6 +586,7 @@ void tst_qquickfocusscope::canvasFocus()
QCOMPARE(scope2->hasActiveFocus(), false);
QCOMPARE(item2->hasFocus(), false);
QCOMPARE(item2->hasActiveFocus(), false);
+
QCOMPARE(rootFocusSpy.count(), 1);
QCOMPARE(rootActiveFocusSpy.count(), 1);
QCOMPARE(scope1FocusSpy.count(), 0);
@@ -605,6 +607,7 @@ void tst_qquickfocusscope::canvasFocus()
QCOMPARE(scope1->hasActiveFocus(), false);
QCOMPARE(item1->hasFocus(), true);
QCOMPARE(item1->hasActiveFocus(), false);
+
QCOMPARE(rootFocusSpy.count(), 2);
QCOMPARE(rootActiveFocusSpy.count(), 2);
QCOMPARE(scope1FocusSpy.count(), 0);
@@ -612,6 +615,7 @@ void tst_qquickfocusscope::canvasFocus()
QCOMPARE(item1FocusSpy.count(), 0);
QCOMPARE(item1ActiveFocusSpy.count(), 2);
+
// canvas does not have focus, so item2 will not get active focus
item2->forceActiveFocus();
diff --git a/tests/auto/declarative/qquickgridview/tst_qquickgridview.cpp b/tests/auto/declarative/qquickgridview/tst_qquickgridview.cpp
index 5f3842a660..a190d878ad 100644
--- a/tests/auto/declarative/qquickgridview/tst_qquickgridview.cpp
+++ b/tests/auto/declarative/qquickgridview/tst_qquickgridview.cpp
@@ -72,6 +72,8 @@ private slots:
void inserted_more();
void inserted_more_data();
void removed();
+ void addOrRemoveBeforeVisible();
+ void addOrRemoveBeforeVisible_data();
void clear();
void moved();
void moved_data();
@@ -740,6 +742,91 @@ void tst_QQuickGridView::removed()
delete canvas;
}
+void tst_QQuickGridView::addOrRemoveBeforeVisible()
+{
+ // QTBUG-21588: ensure re-layout is done on grid after adding or removing
+ // items from before the visible area
+
+ QFETCH(bool, doAdd);
+ QFETCH(qreal, newTopContentY);
+
+ QQuickView *canvas = createView();
+ canvas->show();
+
+ TestModel model;
+ for (int i = 0; i < 30; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+ ctxt->setContextProperty("testRightToLeft", QVariant(false));
+ ctxt->setContextProperty("testTopToBottom", QVariant(false));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
+
+ QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+ QTRY_VERIFY(gridview != 0);
+ QQuickItem *contentItem = gridview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ QQuickText *name = findItem<QQuickText>(contentItem, "textName", 0);
+ QTRY_COMPARE(name->text(), QString("Item0"));
+
+ gridview->setCurrentIndex(0);
+ qApp->processEvents();
+
+ // scroll down until item 0 is no longer drawn
+ // (bug not triggered if we just move using content y, since that doesn't
+ // refill and change the visible items)
+ gridview->setCurrentIndex(24);
+ qApp->processEvents();
+
+ QTRY_COMPARE(gridview->currentIndex(), 24);
+ QTRY_COMPARE(gridview->contentY(), 220.0);
+
+ QTest::qWait(100); // wait for refill to complete
+ QTRY_VERIFY(!findItem<QQuickItem>(contentItem, "wrapper", 0)); // 0 shouldn't be visible
+
+ if (doAdd) {
+ model.insertItem(0, "New Item", "New Item number");
+ QTRY_COMPARE(gridview->count(), 31);
+ } else {
+ model.removeItem(0);
+ QTRY_COMPARE(gridview->count(), 29);
+ }
+
+ // scroll back up and item 0 should be gone
+ gridview->setCurrentIndex(0);
+ qApp->processEvents();
+ QTRY_COMPARE(gridview->currentIndex(), 0);
+ QTRY_COMPARE(gridview->contentY(), newTopContentY);
+
+ name = findItem<QQuickText>(contentItem, "textName", 0);
+ if (doAdd)
+ QCOMPARE(name->text(), QString("New Item"));
+ else
+ QCOMPARE(name->text(), QString("Item1"));
+
+ // Confirm items positioned correctly
+ int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+ 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_VERIFY(item->y() == (i/3)*60 + newTopContentY);
+ }
+
+ delete canvas;
+}
+
+void tst_QQuickGridView::addOrRemoveBeforeVisible_data()
+{
+ QTest::addColumn<bool>("doAdd");
+ QTest::addColumn<qreal>("newTopContentY");
+
+ QTest::newRow("add") << true << -60.0;
+ QTest::newRow("remove") << false << 0.0;
+}
+
void tst_QQuickGridView::clear()
{
QQuickView *canvas = createView();
@@ -2356,18 +2443,17 @@ void tst_QQuickGridView::enforceRange_rightToLeft()
QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
QTRY_VERIFY(gridview != 0);
- QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0);
- QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0);
- QTRY_COMPARE(gridview->highlightRangeMode(), QQuickGridView::StrictlyEnforceRange);
+ QCOMPARE(gridview->preferredHighlightBegin(), 100.0);
+ QCOMPARE(gridview->preferredHighlightEnd(), 100.0);
+ QCOMPARE(gridview->highlightRangeMode(), QQuickGridView::StrictlyEnforceRange);
QQuickItem *contentItem = gridview->contentItem();
- QTRY_VERIFY(contentItem != 0);
+ QVERIFY(contentItem != 0);
// view should be positioned at the top of the range.
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 0);
- QTRY_VERIFY(item);
- QEXPECT_FAIL("", "QTBUG-22162", Abort);
- QTRY_COMPARE(gridview->contentX(), -100.);
+ QVERIFY(item);
+ QTRY_COMPARE(gridview->contentX(), -140.);
QTRY_COMPARE(gridview->contentY(), 0.0);
QQuickText *name = findItem<QQuickText>(contentItem, "textName", 0);
@@ -2378,11 +2464,11 @@ void tst_QQuickGridView::enforceRange_rightToLeft()
QTRY_COMPARE(number->text(), model.number(0));
// Check currentIndex is updated when contentItem moves
- gridview->setContentX(-200);
+ gridview->setContentX(-240);
QTRY_COMPARE(gridview->currentIndex(), 3);
gridview->setCurrentIndex(7);
- QTRY_COMPARE(gridview->contentX(), -300.);
+ QTRY_COMPARE(gridview->contentX(), -340.);
QTRY_COMPARE(gridview->contentY(), 0.0);
TestModel model2;
diff --git a/tests/auto/declarative/qquickitem/tst_qquickitem.cpp b/tests/auto/declarative/qquickitem/tst_qquickitem.cpp
index 35346c8236..a5f908ce86 100644
--- a/tests/auto/declarative/qquickitem/tst_qquickitem.cpp
+++ b/tests/auto/declarative/qquickitem/tst_qquickitem.cpp
@@ -137,11 +137,6 @@ private:
w->show();
w->requestActivateWindow();
qApp->processEvents();
-
-#ifdef Q_WS_X11
- // to be safe and avoid failing setFocus with window managers
- qt_x11_wait_for_window_manager(w);
-#endif
}
};
diff --git a/tests/auto/declarative/qquickitem2/qquickitem2.pro b/tests/auto/declarative/qquickitem2/qquickitem2.pro
index 47b31d98e9..2fe1eb1e3a 100644
--- a/tests/auto/declarative/qquickitem2/qquickitem2.pro
+++ b/tests/auto/declarative/qquickitem2/qquickitem2.pro
@@ -1,5 +1,5 @@
CONFIG += testcase
-TARGET = tst_qquickitem
+TARGET = tst_qquickitem2
macx:CONFIG -= app_bundle
SOURCES += tst_qquickitem.cpp
diff --git a/tests/auto/declarative/qquickmultipointtoucharea/data/inFlickable.qml b/tests/auto/declarative/qquickmultipointtoucharea/data/inFlickable.qml
new file mode 100644
index 0000000000..53a2bf87f9
--- /dev/null
+++ b/tests/auto/declarative/qquickmultipointtoucharea/data/inFlickable.qml
@@ -0,0 +1,25 @@
+import QtQuick 2.0
+
+Flickable {
+ width: 240
+ height: 320
+
+ contentWidth: width
+ contentHeight: height * 2
+
+ MultiPointTouchArea {
+ anchors.fill: parent
+ minimumTouchPoints: 2
+ maximumTouchPoints: 2
+ onGestureStarted: {
+ if ((Math.abs(point2.x - point2.startX) > gesture.dragThreshold/2) && (Math.abs(point1.x - point1.startX) > gesture.dragThreshold/2)) {
+ gesture.grab()
+ }
+ }
+ touchPoints: [
+ TouchPoint { id: point1; objectName: "point1" },
+ TouchPoint { id: point2; objectName: "point2" }
+ ]
+ }
+}
+
diff --git a/tests/auto/declarative/qquickmultipointtoucharea/data/nested.qml b/tests/auto/declarative/qquickmultipointtoucharea/data/nested.qml
new file mode 100644
index 0000000000..37b8820aa0
--- /dev/null
+++ b/tests/auto/declarative/qquickmultipointtoucharea/data/nested.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.0
+
+MultiPointTouchArea {
+ width: 240
+ height: 320
+
+ property bool grabInnerArea: true
+
+ minimumTouchPoints: 2
+ maximumTouchPoints: 3
+ touchPoints: [
+ TouchPoint { objectName: "point11" },
+ TouchPoint { objectName: "point12" }
+ ]
+
+ MultiPointTouchArea {
+ anchors.fill: parent
+ minimumTouchPoints: 3
+ maximumTouchPoints: 3
+ onGestureStarted: if (grabInnerArea) gesture.grab()
+ touchPoints: [
+ TouchPoint { objectName: "point21" },
+ TouchPoint { objectName: "point22" },
+ TouchPoint { objectName: "point23" }
+ ]
+ }
+}
diff --git a/tests/auto/declarative/qquickmultipointtoucharea/data/nonOverlapping.qml b/tests/auto/declarative/qquickmultipointtoucharea/data/nonOverlapping.qml
new file mode 100644
index 0000000000..039607e26c
--- /dev/null
+++ b/tests/auto/declarative/qquickmultipointtoucharea/data/nonOverlapping.qml
@@ -0,0 +1,32 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 240
+ height: 320
+
+ MultiPointTouchArea {
+ width: parent.width
+ height: 160
+ minimumTouchPoints: 2
+ maximumTouchPoints: 2
+ onGestureStarted: gesture.grab()
+ touchPoints: [
+ TouchPoint { objectName: "point11" },
+ TouchPoint { objectName: "point12" }
+ ]
+ }
+
+ MultiPointTouchArea {
+ width: parent.width
+ height: 160
+ y: 160
+ minimumTouchPoints: 3
+ maximumTouchPoints: 3
+ onGestureStarted: gesture.grab()
+ touchPoints: [
+ TouchPoint { objectName: "point21" },
+ TouchPoint { objectName: "point22" },
+ TouchPoint { objectName: "point23" }
+ ]
+ }
+}
diff --git a/tests/auto/declarative/qquickmultipointtoucharea/data/properties.qml b/tests/auto/declarative/qquickmultipointtoucharea/data/properties.qml
new file mode 100644
index 0000000000..98ef1a9cbe
--- /dev/null
+++ b/tests/auto/declarative/qquickmultipointtoucharea/data/properties.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+
+MultiPointTouchArea {
+ width: 240
+ height: 320
+
+ minimumTouchPoints: 2
+ maximumTouchPoints: 4
+ touchPoints: [
+ TouchPoint {},
+ TouchPoint {},
+ TouchPoint {},
+ TouchPoint {}
+ ]
+}
diff --git a/tests/auto/declarative/qquickmultipointtoucharea/data/signalTest.qml b/tests/auto/declarative/qquickmultipointtoucharea/data/signalTest.qml
new file mode 100644
index 0000000000..3a6aa86a1c
--- /dev/null
+++ b/tests/auto/declarative/qquickmultipointtoucharea/data/signalTest.qml
@@ -0,0 +1,25 @@
+import QtQuick 2.0
+
+MultiPointTouchArea {
+ width: 240
+ height: 320
+
+ function clearCounts() {
+ touchPointPressCount = 0;
+ touchPointUpdateCount = 0;
+ touchPointReleaseCount = 0;
+ touchCount = 0;
+ }
+
+ property int touchPointPressCount: 0
+ property int touchPointUpdateCount: 0
+ property int touchPointReleaseCount: 0
+ property int touchCount: 0
+
+ maximumTouchPoints: 5
+
+ onTouchPointsPressed: { touchPointPressCount = touchPoints.length }
+ onTouchPointsUpdated: { touchPointUpdateCount = touchPoints.length }
+ onTouchPointsReleased: { touchPointReleaseCount = touchPoints.length }
+ onTouchUpdated: { touchCount = touchPoints.length }
+}
diff --git a/tests/auto/declarative/qquickmultipointtoucharea/qquickmultipointtoucharea.pro b/tests/auto/declarative/qquickmultipointtoucharea/qquickmultipointtoucharea.pro
new file mode 100644
index 0000000000..8be4b1f1fd
--- /dev/null
+++ b/tests/auto/declarative/qquickmultipointtoucharea/qquickmultipointtoucharea.pro
@@ -0,0 +1,11 @@
+TARGET = tst_qquickmultipointtoucharea
+CONFIG += testcase
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquickmultipointtoucharea.cpp
+
+importFiles.files = data
+importFiles.path = .
+DEPLOYMENT += importFiles
+
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/declarative/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
new file mode 100644
index 0000000000..9acef50645
--- /dev/null
+++ b/tests/auto/declarative/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
@@ -0,0 +1,586 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtTest/QSignalSpy>
+#include <private/qquickmultipointtoucharea_p.h>
+#include <private/qquickflickable_p.h>
+#include <QtDeclarative/qquickview.h>
+
+class tst_QQuickMultiPointTouchArea: public QObject
+{
+ Q_OBJECT
+private slots:
+ void initTestCase() {}
+ void cleanupTestCase() {}
+
+ void properties();
+ void signalTest();
+ void nonOverlapping();
+ void nested();
+ void inFlickable();
+
+private:
+ QQuickView *createAndShowView(const QString &file);
+};
+
+void tst_QQuickMultiPointTouchArea::properties()
+{
+ QQuickView *canvas = createAndShowView("properties.qml");
+ QVERIFY(canvas->rootObject() != 0);
+
+ QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(canvas->rootObject());
+ QVERIFY(area != 0);
+
+ QCOMPARE(area->minimumTouchPoints(), 2);
+ QCOMPARE(area->maximumTouchPoints(), 4);
+
+ QDeclarativeListReference ref(area, "touchPoints");
+ QCOMPARE(ref.count(), 4);
+
+ delete canvas;
+}
+
+void tst_QQuickMultiPointTouchArea::signalTest()
+{
+ QQuickView *canvas = createAndShowView("signalTest.qml");
+ QVERIFY(canvas->rootObject() != 0);
+
+ QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(canvas->rootObject());
+ QVERIFY(area != 0);
+
+ QPoint p1(20,100);
+ QPoint p2(40,100);
+ QPoint p3(60,100);
+ QPoint p4(80,100);
+ QPoint p5(100,100);
+
+ QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas);
+
+ sequence.press(0, p1).press(1, p2).commit();
+
+ QCOMPARE(area->property("touchPointPressCount").toInt(), 2);
+ QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
+ QCOMPARE(area->property("touchCount").toInt(), 2);
+ QMetaObject::invokeMethod(area, "clearCounts");
+
+ sequence.stationary(0).stationary(1).press(2, p3).commit();
+
+ QCOMPARE(area->property("touchPointPressCount").toInt(), 1);
+ QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
+ QCOMPARE(area->property("touchCount").toInt(), 3);
+ QMetaObject::invokeMethod(area, "clearCounts");
+
+ p1 -= QPoint(10,10);
+ p2 += QPoint(10,10);
+ sequence.move(0, p1).move(1, p2).stationary(2).commit();
+
+ QCOMPARE(area->property("touchPointPressCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointUpdateCount").toInt(), 2);
+ QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
+ QCOMPARE(area->property("touchCount").toInt(), 3);
+ QMetaObject::invokeMethod(area, "clearCounts");
+
+ p3 += QPoint(10,10);
+ sequence.release(0, p1).release(1, p2)
+ .move(2, p3).press(3, p4).press(4, p5).commit();
+
+ QCOMPARE(area->property("touchPointPressCount").toInt(), 2);
+ QCOMPARE(area->property("touchPointUpdateCount").toInt(), 1);
+ QCOMPARE(area->property("touchPointReleaseCount").toInt(), 2);
+ QCOMPARE(area->property("touchCount").toInt(), 3);
+ QMetaObject::invokeMethod(area, "clearCounts");
+
+ sequence.release(2, p3).release(3, p4).release(4, p5).commit();
+
+ QCOMPARE(area->property("touchPointPressCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
+ QCOMPARE(area->property("touchPointReleaseCount").toInt(), 3);
+ QCOMPARE(area->property("touchCount").toInt(), 0);
+ QMetaObject::invokeMethod(area, "clearCounts");
+
+ delete canvas;
+}
+
+void tst_QQuickMultiPointTouchArea::nonOverlapping()
+{
+ QQuickView *canvas = createAndShowView("nonOverlapping.qml");
+ QVERIFY(canvas->rootObject() != 0);
+
+ QQuickTouchPoint *point11 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point11");
+ QQuickTouchPoint *point12 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point12");
+ QQuickTouchPoint *point21 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point21");
+ QQuickTouchPoint *point22 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point22");
+ QQuickTouchPoint *point23 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point23");
+
+ QCOMPARE(point11->isValid(), false);
+ QCOMPARE(point12->isValid(), false);
+ QCOMPARE(point21->isValid(), false);
+ QCOMPARE(point22->isValid(), false);
+ QCOMPARE(point23->isValid(), false);
+
+ QPoint p1(20,100);
+ QPoint p2(40,100);
+ QPoint p3(60,180);
+ QPoint p4(80,180);
+ QPoint p5(100,180);
+
+ QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas);
+
+ sequence.press(0, p1).commit();
+
+ QCOMPARE(point11->isValid(), false);
+ QCOMPARE(point12->isValid(), false);
+ QCOMPARE(point21->isValid(), false);
+ QCOMPARE(point22->isValid(), false);
+ QCOMPARE(point23->isValid(), false);
+
+ sequence.stationary(0).press(1, p2).commit();
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+ QCOMPARE(point21->isValid(), false);
+ QCOMPARE(point22->isValid(), false);
+ QCOMPARE(point23->isValid(), false);
+
+ QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(100));
+ QCOMPARE(point12->x(), qreal(40)); QCOMPARE(point12->y(), qreal(100));
+
+ p1 += QPoint(0,10);
+ p2 += QPoint(5,0);
+ sequence.move(0, p1).move(1, p2).commit();
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+ QCOMPARE(point21->isValid(), false);
+ QCOMPARE(point22->isValid(), false);
+ QCOMPARE(point23->isValid(), false);
+
+ QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110));
+ QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
+
+ sequence.stationary(0).stationary(1).press(2, p3).commit();
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+ QCOMPARE(point21->isValid(), false);
+ QCOMPARE(point22->isValid(), false);
+ QCOMPARE(point23->isValid(), false);
+
+ sequence.stationary(0).stationary(1).stationary(2).press(3, p4).press(4, p5).commit();
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+ QCOMPARE(point21->isValid(), true);
+ QCOMPARE(point22->isValid(), true);
+ QCOMPARE(point23->isValid(), true);
+
+ QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110));
+ QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
+ QCOMPARE(point21->x(), qreal(60)); QCOMPARE(point21->y(), qreal(20));
+ QCOMPARE(point22->x(), qreal(80)); QCOMPARE(point22->y(), qreal(20));
+ QCOMPARE(point23->x(), qreal(100)); QCOMPARE(point23->y(), qreal(20));
+
+ p1 += QPoint(4,10);
+ p2 += QPoint(17,17);
+ p3 += QPoint(3,0);
+ p4 += QPoint(1,-1);
+ p5 += QPoint(-7,10);
+ sequence.move(0, p1).move(1, p2).move(2, p3).move(3, p4).move(4, p5).commit();
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+ QCOMPARE(point21->isValid(), true);
+ QCOMPARE(point22->isValid(), true);
+ QCOMPARE(point23->isValid(), true);
+
+ QCOMPARE(point11->x(), qreal(24)); QCOMPARE(point11->y(), qreal(120));
+ QCOMPARE(point12->x(), qreal(62)); QCOMPARE(point12->y(), qreal(117));
+ QCOMPARE(point21->x(), qreal(63)); QCOMPARE(point21->y(), qreal(20));
+ QCOMPARE(point22->x(), qreal(81)); QCOMPARE(point22->y(), qreal(19));
+ QCOMPARE(point23->x(), qreal(93)); QCOMPARE(point23->y(), qreal(30));
+
+ sequence.release(0, p1).release(1, p2).release(2, p3).release(3, p4).release(4, p5).commit();
+
+ //points remain valid immediately after release
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+ QCOMPARE(point21->isValid(), true);
+ QCOMPARE(point22->isValid(), true);
+ QCOMPARE(point23->isValid(), true);
+
+ delete canvas;
+}
+
+void tst_QQuickMultiPointTouchArea::nested()
+{
+ QQuickView *canvas = createAndShowView("nested.qml");
+ QVERIFY(canvas->rootObject() != 0);
+
+ QQuickTouchPoint *point11 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point11");
+ QQuickTouchPoint *point12 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point12");
+ QQuickTouchPoint *point21 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point21");
+ QQuickTouchPoint *point22 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point22");
+ QQuickTouchPoint *point23 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point23");
+
+ QCOMPARE(point11->isValid(), false);
+ QCOMPARE(point12->isValid(), false);
+ QCOMPARE(point21->isValid(), false);
+ QCOMPARE(point22->isValid(), false);
+ QCOMPARE(point23->isValid(), false);
+
+ QPoint p1(20,100);
+ QPoint p2(40,100);
+ QPoint p3(60,180);
+
+ QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas);
+
+ sequence.press(0, p1).commit();
+
+ QCOMPARE(point11->isValid(), false);
+ QCOMPARE(point12->isValid(), false);
+ QCOMPARE(point21->isValid(), false);
+ QCOMPARE(point22->isValid(), false);
+ QCOMPARE(point23->isValid(), false);
+
+ sequence.stationary(0).press(1, p2).commit();
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+ QCOMPARE(point21->isValid(), false);
+ QCOMPARE(point22->isValid(), false);
+ QCOMPARE(point23->isValid(), false);
+
+ QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(100));
+ QCOMPARE(point12->x(), qreal(40)); QCOMPARE(point12->y(), qreal(100));
+
+ p1 += QPoint(0,10);
+ p2 += QPoint(5,0);
+ sequence.move(0, p1).move(1, p2).commit();
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+ QCOMPARE(point21->isValid(), false);
+ QCOMPARE(point22->isValid(), false);
+ QCOMPARE(point23->isValid(), false);
+
+ QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110));
+ QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
+
+ sequence.stationary(0).stationary(1).press(2, p3).commit();
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+ QCOMPARE(point21->isValid(), true);
+ QCOMPARE(point22->isValid(), true);
+ QCOMPARE(point23->isValid(), true);
+
+ //point11 should be same as point21, point12 same as point22
+ QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110));
+ QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
+ QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110));
+ QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100));
+ QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180));
+
+ sequence.stationary(0).stationary(1).stationary(2).press(3, QPoint(80,180)).press(4, QPoint(100,180)).commit();
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+ QCOMPARE(point21->isValid(), true);
+ QCOMPARE(point22->isValid(), true);
+ QCOMPARE(point23->isValid(), true);
+
+ //new touch points should be ignored (have no impact on our existing touch points)
+ QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110));
+ QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
+ QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110));
+ QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100));
+ QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180));
+
+ sequence.stationary(0).stationary(1).stationary(2).release(3, QPoint(80,180)).release(4, QPoint(100,180)).commit();
+
+ p1 += QPoint(4,10);
+ p2 += QPoint(17,17);
+ p3 += QPoint(3,0);
+ sequence.move(0, p1).move(1, p2).move(2, p3).commit();
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+ QCOMPARE(point21->isValid(), true);
+ QCOMPARE(point22->isValid(), true);
+ QCOMPARE(point23->isValid(), true);
+
+ QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120));
+ QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117));
+ QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120));
+ QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117));
+ QCOMPARE(point23->x(), qreal(63)); QCOMPARE(point23->y(), qreal(180));
+
+ p1 += QPoint(4,10);
+ p2 += QPoint(17,17);
+ p3 += QPoint(3,0);
+ sequence.move(0, p1).move(1, p2).move(2, p3).commit();
+
+ QCOMPARE(point11->isValid(), false);
+ QCOMPARE(point12->isValid(), false);
+ QCOMPARE(point21->isValid(), true);
+ QCOMPARE(point22->isValid(), true);
+ QCOMPARE(point23->isValid(), true);
+
+ //first two remain the same (touches now grabbed by inner touch area)
+ QCOMPARE(point11->x(), qreal(24)); QCOMPARE(point11->y(), qreal(120));
+ QCOMPARE(point12->x(), qreal(62)); QCOMPARE(point12->y(), qreal(117));
+ QCOMPARE(point21->x(), qreal(28)); QCOMPARE(point21->y(), qreal(130));
+ QCOMPARE(point22->x(), qreal(79)); QCOMPARE(point22->y(), qreal(134));
+ QCOMPARE(point23->x(), qreal(66)); QCOMPARE(point23->y(), qreal(180));
+
+ sequence.release(0, p1).release(1, p2).release(2, p3).commit();
+
+ sequence.press(0, p1).commit();
+
+ QCOMPARE(point11->isValid(), false);
+ QCOMPARE(point12->isValid(), false);
+ QCOMPARE(point21->isValid(), false);
+ QCOMPARE(point22->isValid(), false);
+ QCOMPARE(point23->isValid(), false);
+
+ sequence.release(0, p1).commit();
+
+ //test with grabbing turned off
+ canvas->rootObject()->setProperty("grabInnerArea", false);
+
+ sequence.press(0, p1).press(1, p2).press(2, p3).commit();
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+ QCOMPARE(point21->isValid(), true);
+ QCOMPARE(point22->isValid(), true);
+ QCOMPARE(point23->isValid(), true);
+
+ p1 -= QPoint(4,10);
+ p2 -= QPoint(17,17);
+ p3 -= QPoint(3,0);
+ sequence.move(0, p1).move(1, p2).move(2, p3).commit();
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+ QCOMPARE(point21->isValid(), true);
+ QCOMPARE(point22->isValid(), true);
+ QCOMPARE(point23->isValid(), true);
+
+ QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120));
+ QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117));
+ QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120));
+ QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117));
+ QCOMPARE(point23->x(), qreal(63)); QCOMPARE(point23->y(), qreal(180));
+
+ p1 -= QPoint(4,10);
+ p2 -= QPoint(17,17);
+ p3 -= QPoint(3,0);
+ sequence.move(0, p1).move(1, p2).move(2, p3).commit();
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+ QCOMPARE(point21->isValid(), true);
+ QCOMPARE(point22->isValid(), true);
+ QCOMPARE(point23->isValid(), true);
+
+ //all change (touches not grabbed by inner touch area)
+ QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110));
+ QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
+ QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110));
+ QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100));
+ QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180));
+
+ sequence.release(0, p1).release(1, p2).release(2, p3).commit();
+
+ delete canvas;
+}
+
+void tst_QQuickMultiPointTouchArea::inFlickable()
+{
+ QQuickView *canvas = createAndShowView("inFlickable.qml");
+ QVERIFY(canvas->rootObject() != 0);
+
+ QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(canvas->rootObject());
+ QVERIFY(flickable != 0);
+
+ QQuickTouchPoint *point11 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point1");
+ QQuickTouchPoint *point12 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point2");
+
+ QCOMPARE(point11->isValid(), false);
+ QCOMPARE(point12->isValid(), false);
+
+ QPoint p1(20,100);
+ QPoint p2(40,100);
+
+ //moving one point vertically
+ QTest::touchEvent(canvas).press(0, p1);
+ QTest::mousePress(canvas, Qt::LeftButton, 0, p1);
+
+ p1 += QPoint(0,15);
+ QTest::touchEvent(canvas).move(0, p1);
+ QTest::mouseMove(canvas, p1);
+
+ p1 += QPoint(0,15);
+ QTest::touchEvent(canvas).move(0, p1);
+ QTest::mouseMove(canvas, p1);
+
+ p1 += QPoint(0,15);
+ QTest::touchEvent(canvas).move(0, p1);
+ QTest::mouseMove(canvas, p1);
+
+ p1 += QPoint(0,15);
+ QTest::touchEvent(canvas).move(0, p1);
+ QTest::mouseMove(canvas, p1);
+
+ QVERIFY(flickable->contentY() < 0);
+ QCOMPARE(point11->isValid(), false);
+ QCOMPARE(point12->isValid(), false);
+
+ QTest::touchEvent(canvas).release(0, p1);
+ QTest::mouseRelease(canvas,Qt::LeftButton, 0, p1);
+ QTest::qWait(50);
+
+ QTRY_VERIFY(!flickable->isMoving());
+
+ //moving two points vertically
+ p1 = QPoint(20,100);
+ QTest::touchEvent(canvas).press(0, p1).press(1, p2);
+ QTest::mousePress(canvas, Qt::LeftButton, 0, p1);
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+
+ p1 += QPoint(0,15); p2 += QPoint(0,15);
+ QTest::touchEvent(canvas).move(0, p1).move(1, p2);
+ QTest::mouseMove(canvas, p1);
+
+ p1 += QPoint(0,15); p2 += QPoint(0,15);
+ QTest::touchEvent(canvas).move(0, p1).move(1, p2);
+ QTest::mouseMove(canvas, p1);
+
+ p1 += QPoint(0,15); p2 += QPoint(0,15);
+ QTest::touchEvent(canvas).move(0, p1).move(1, p2);
+ QTest::mouseMove(canvas, p1);
+
+ p1 += QPoint(0,15); p2 += QPoint(0,15);
+ QTest::touchEvent(canvas).move(0, p1).move(1, p2);
+ QTest::mouseMove(canvas, p1);
+
+ QVERIFY(flickable->contentY() < 0);
+ QCOMPARE(point11->isValid(), false);
+ QCOMPARE(point12->isValid(), false);
+
+ QTest::touchEvent(canvas).release(0, p1).release(1, p2);
+ QTest::mouseRelease(canvas,Qt::LeftButton, 0, p1);
+ QTest::qWait(50);
+
+ QTRY_VERIFY(!flickable->isMoving());
+
+ //moving two points horizontally, then one point vertically
+ p1 = QPoint(20,100);
+ p2 = QPoint(40,100);
+ QTest::touchEvent(canvas).press(0, p1).press(1, p2);
+ QTest::mousePress(canvas, Qt::LeftButton, 0, p1);
+
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+
+ p1 += QPoint(15,0); p2 += QPoint(15,0);
+ QTest::touchEvent(canvas).move(0, p1).move(1, p2);
+ QTest::mouseMove(canvas, p1);
+
+ p1 += QPoint(15,0); p2 += QPoint(15,0);
+ QTest::touchEvent(canvas).move(0, p1).move(1, p2);
+ QTest::mouseMove(canvas, p1);
+
+ p1 += QPoint(15,0); p2 += QPoint(15,0);
+ QTest::touchEvent(canvas).move(0, p1).move(1, p2);
+ QTest::mouseMove(canvas, p1);
+
+ p1 += QPoint(15,0); p2 += QPoint(15,0);
+ QTest::touchEvent(canvas).move(0, p1).move(1, p2);
+ QTest::mouseMove(canvas, p1);
+
+ p1 += QPoint(0,15); p2 += QPoint(0,15);
+ QTest::touchEvent(canvas).move(0, p1).move(1, p2);
+ QTest::mouseMove(canvas, p1);
+
+ p1 += QPoint(0,15); p2 += QPoint(0,15);
+ QTest::touchEvent(canvas).move(0, p1).move(1, p2);
+ QTest::mouseMove(canvas, p1);
+
+ p1 += QPoint(0,15); p2 += QPoint(0,15);
+ QTest::touchEvent(canvas).move(0, p1).move(1, p2);
+ QTest::mouseMove(canvas, p1);
+
+ p1 += QPoint(0,15); p2 += QPoint(0,15);
+ QTest::touchEvent(canvas).move(0, p1).move(1, p2);
+ QTest::mouseMove(canvas, p1);
+
+ QVERIFY(flickable->contentY() == 0);
+ QCOMPARE(point11->isValid(), true);
+ QCOMPARE(point12->isValid(), true);
+
+ QTest::touchEvent(canvas).release(0, p1).release(1, p2);
+ QTest::mouseRelease(canvas,Qt::LeftButton, 0, p1);
+ QTest::qWait(50);
+
+ delete canvas;
+}
+
+QQuickView *tst_QQuickMultiPointTouchArea::createAndShowView(const QString &file)
+{
+ QQuickView *canvas = new QQuickView(0);
+ canvas->setSource(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + QLatin1String("/data/") + file));
+ canvas->show();
+ canvas->requestActivateWindow();
+ QTest::qWaitForWindowShown(canvas);
+
+ return canvas;
+}
+
+QTEST_MAIN(tst_QQuickMultiPointTouchArea)
+
+#include "tst_qquickmultipointtoucharea.moc"
diff --git a/tests/auto/declarative/qquickpathview/data/pathline.qml b/tests/auto/declarative/qquickpathview/data/pathline.qml
new file mode 100644
index 0000000000..4c1c785bce
--- /dev/null
+++ b/tests/auto/declarative/qquickpathview/data/pathline.qml
@@ -0,0 +1,48 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: app
+ width: 360
+ height: 360
+
+ PathView {
+ id: pathView
+ objectName: "view"
+ x: (app.width-pathView.width)/2
+ y: 100
+ width: 240
+ height: 100
+
+ model: testModel
+
+ Rectangle {
+ anchors.fill: parent
+ color: "white"
+ border.color: "black"
+ }
+ preferredHighlightBegin: 0.5
+ preferredHighlightEnd: 0.5
+
+ delegate: Rectangle {
+ objectName: "wrapper"
+ width: 100
+ height: 100
+ color: PathView.isCurrentItem ? "red" : "yellow"
+ Text {
+ text: index
+ anchors.centerIn: parent
+ }
+ z: (PathView.isCurrentItem?1:0)
+ }
+ path: Path {
+ id: path
+ startX: -100+pathView.width/2
+ startY: pathView.height/2
+ PathLine {
+ id: line
+ x: 100+pathView.width/2
+ y: pathView.height/2
+ }
+ }
+ }
+}
diff --git a/tests/auto/declarative/qquickpathview/tst_qquickpathview.cpp b/tests/auto/declarative/qquickpathview/tst_qquickpathview.cpp
index dc85f590e9..5e434b0259 100644
--- a/tests/auto/declarative/qquickpathview/tst_qquickpathview.cpp
+++ b/tests/auto/declarative/qquickpathview/tst_qquickpathview.cpp
@@ -111,6 +111,7 @@ private slots:
void changePreferredHighlight();
void missingPercent();
void creationContext();
+ void currentOffsetOnInsertion();
private:
QQuickView *createView();
@@ -240,6 +241,8 @@ void tst_QQuickPathView::initValues()
QCOMPARE(obj->dragMargin(), 0.);
QCOMPARE(obj->count(), 0);
QCOMPARE(obj->pathItemCount(), -1);
+
+ delete obj;
}
void tst_QQuickPathView::items()
@@ -303,6 +306,8 @@ void tst_QQuickPathView::pathview2()
QCOMPARE(obj->dragMargin(), 0.);
QCOMPARE(obj->count(), 8);
QCOMPARE(obj->pathItemCount(), 10);
+
+ delete obj;
}
void tst_QQuickPathView::pathview3()
@@ -321,6 +326,8 @@ void tst_QQuickPathView::pathview3()
QCOMPARE(obj->dragMargin(), 24.);
QCOMPARE(obj->count(), 8);
QCOMPARE(obj->pathItemCount(), 4);
+
+ delete obj;
}
void tst_QQuickPathView::path()
@@ -366,6 +373,8 @@ void tst_QQuickPathView::path()
QCOMPARE(cubic->control1Y(), 90.);
QCOMPARE(cubic->control2X(), 210.);
QCOMPARE(cubic->control2Y(), 90.);
+
+ delete obj;
}
void tst_QQuickPathView::dataModel()
@@ -1081,6 +1090,86 @@ void tst_QQuickPathView::creationContext()
QCOMPARE(item->property("text").toString(), QString("Hello!"));
}
+// QTBUG-21320
+void tst_QQuickPathView::currentOffsetOnInsertion()
+{
+ QQuickView *canvas = createView();
+ canvas->show();
+
+ TestModel model;
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathline.qml")));
+ qApp->processEvents();
+
+ QQuickPathView *pathview = findItem<QQuickPathView>(canvas->rootObject(), "view");
+ QVERIFY(pathview != 0);
+
+ pathview->setPreferredHighlightBegin(0.5);
+ pathview->setPreferredHighlightEnd(0.5);
+
+ QCOMPARE(pathview->count(), model.count());
+
+ model.addItem("item0", "0");
+
+ QCOMPARE(pathview->count(), model.count());
+
+ QQuickRectangle *item = 0;
+ QTRY_VERIFY(item = findItem<QQuickRectangle>(pathview, "wrapper", 0));
+
+ QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
+ QVERIFY(path);
+
+ QPointF start = path->pointAt(0.5);
+ start = QPointF(qRound(start.x()), qRound(start.y()));
+ QPointF offset;//Center of item is at point, but pos is from corner
+ offset.setX(item->width()/2);
+ offset.setY(item->height()/2);
+ QCOMPARE(item->pos() + offset, start);
+
+ QSignalSpy currentIndexSpy(pathview, SIGNAL(currentIndexChanged()));
+
+ // insert an item at the beginning
+ model.insertItem(0, "item1", "1");
+ qApp->processEvents();
+
+ QCOMPARE(currentIndexSpy.count(), 1);
+
+ // currentIndex is now 1
+ QVERIFY(item = findItem<QQuickRectangle>(pathview, "wrapper", 1));
+
+ // verify that current item (item 1) is still at offset 0.5
+ QCOMPARE(item->pos() + offset, start);
+
+ // insert another item at the beginning
+ model.insertItem(0, "item2", "2");
+ qApp->processEvents();
+
+ QCOMPARE(currentIndexSpy.count(), 2);
+
+ // currentIndex is now 2
+ QVERIFY(item = findItem<QQuickRectangle>(pathview, "wrapper", 2));
+
+ // verify that current item (item 2) is still at offset 0.5
+ QCOMPARE(item->pos() + offset, start);
+
+ // verify that remove before current maintains current item
+ model.removeItem(0);
+ qApp->processEvents();
+
+ QCOMPARE(currentIndexSpy.count(), 3);
+
+ // currentIndex is now 1
+ QVERIFY(item = findItem<QQuickRectangle>(pathview, "wrapper", 1));
+
+ // verify that current item (item 1) is still at offset 0.5
+ QCOMPARE(item->pos() + offset, start);
+
+ delete canvas;
+}
+
QQuickView *tst_QQuickPathView::createView()
{
QQuickView *canvas = new QQuickView(0);
diff --git a/tests/auto/declarative/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/declarative/qquickpositioners/tst_qquickpositioners.cpp
index 1d3ccabbf5..f50b5a5b49 100644
--- a/tests/auto/declarative/qquickpositioners/tst_qquickpositioners.cpp
+++ b/tests/auto/declarative/qquickpositioners/tst_qquickpositioners.cpp
@@ -267,8 +267,8 @@ void tst_qquickpositioners::test_horizontal_animated()
QTRY_COMPARE(row->height(), 50.0);
QTest::qWait(0);//Let the animation start
- QCOMPARE(two->x(), -100.0);
- QCOMPARE(three->x(), 50.0);
+ QVERIFY(two->x() >= -100.0 && two->x() < 50.0);
+ QVERIFY(three->x() >= 50.0 && three->x() < 100.0);
QTRY_COMPARE(two->x(), 50.0);
QTRY_COMPARE(three->x(), 100.0);
@@ -323,8 +323,8 @@ void tst_qquickpositioners::test_horizontal_animated_rightToLeft()
QTRY_COMPARE(row->height(), 50.0);
QTest::qWait(0);//Let the animation start
- QCOMPARE(one->x(), 50.0);
- QCOMPARE(two->x(), -100.0);
+ QVERIFY(one->x() >= 50.0 && one->x() < 100);
+ QVERIFY(two->x() >= -100.0 && two->x() < 50.0);
QTRY_COMPARE(one->x(), 100.0);
QTRY_COMPARE(two->x(), 50.0);
@@ -361,13 +361,11 @@ void tst_qquickpositioners::test_horizontal_animated_disabled()
//Add 'two'
two->setVisible(true);
QCOMPARE(two->isVisible(), true);
- qApp->processEvents();
- QCOMPARE(row->width(), 150.0);
- QCOMPARE(row->height(), 50.0);
+ QTRY_COMPARE(row->width(), 150.0);
+ QTRY_COMPARE(row->height(), 50.0);
- qApp->processEvents();
- QCOMPARE(two->x(), 50.0);
- QCOMPARE(three->x(), 100.0);
+ QTRY_COMPARE(two->x(), 50.0);
+ QTRY_COMPARE(three->x(), 100.0);
delete canvas;
}
@@ -468,8 +466,8 @@ void tst_qquickpositioners::test_vertical_animated()
QTRY_COMPARE(column->height(), 150.0);
QTRY_COMPARE(column->width(), 50.0);
QTest::qWait(0);//Let the animation start
- QCOMPARE(two->y(), -100.0);
- QCOMPARE(three->y(), 50.0);
+ QVERIFY(two->y() >= -100.0 && two->y() < 50.0);
+ QVERIFY(three->y() >= 50.0 && three->y() < 100.0);
QTRY_COMPARE(two->y(), 50.0);
QTRY_COMPARE(three->y(), 100.0);
diff --git a/tests/auto/declarative/qquickspriteimage/data/basic.qml b/tests/auto/declarative/qquickspriteimage/data/basic.qml
new file mode 100644
index 0000000000..1fcdfd99c3
--- /dev/null
+++ b/tests/auto/declarative/qquickspriteimage/data/basic.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ SpriteImage {
+ objectName: "sprite"
+ sprites: Sprite {
+ name: "happy"
+ source: "squarefacesprite.png"
+ frames: 6
+ duration: 120
+ }
+ width: 160
+ height: 160
+ }
+}
diff --git a/tests/auto/declarative/qquickspriteimage/data/squarefacesprite.png b/tests/auto/declarative/qquickspriteimage/data/squarefacesprite.png
new file mode 100644
index 0000000000..f9a5d5fcce
--- /dev/null
+++ b/tests/auto/declarative/qquickspriteimage/data/squarefacesprite.png
Binary files differ
diff --git a/tests/auto/declarative/qquickspriteimage/qquickspriteimage.pro b/tests/auto/declarative/qquickspriteimage/qquickspriteimage.pro
new file mode 100644
index 0000000000..db5c45da8a
--- /dev/null
+++ b/tests/auto/declarative/qquickspriteimage/qquickspriteimage.pro
@@ -0,0 +1,12 @@
+CONFIG += testcase
+TARGET = tst_qquickspriteimage
+SOURCES += tst_qquickspriteimage.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qquickspriteimage/tst_qquickspriteimage.cpp b/tests/auto/declarative/qquickspriteimage/tst_qquickspriteimage.cpp
new file mode 100644
index 0000000000..1b8c58b873
--- /dev/null
+++ b/tests/auto/declarative/qquickspriteimage/tst_qquickspriteimage.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+#include "../shared/util.h"
+#include <qquickview.h>
+#include <private/qquickspriteimage_p.h>
+
+class tst_qquickspriteimage : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qquickspriteimage(){}
+
+private slots:
+ void test_properties();
+};
+
+void tst_qquickspriteimage::test_properties()
+{
+ QQuickView *canvas = new QQuickView(0);
+
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("basic.qml")));
+ canvas->show();
+ QTest::qWaitForWindowShown(canvas);
+
+ QVERIFY(canvas->rootObject());
+ QQuickSpriteImage* sprite = canvas->rootObject()->findChild<QQuickSpriteImage*>("sprite");
+ QVERIFY(sprite);
+
+ QVERIFY(sprite->running());
+ QVERIFY(sprite->interpolate());
+
+ sprite->setRunning(false);
+ QVERIFY(!sprite->running());
+ sprite->setInterpolate(false);
+ QVERIFY(!sprite->interpolate());
+
+ delete canvas;
+}
+
+QTEST_MAIN(tst_qquickspriteimage)
+
+#include "tst_qquickspriteimage.moc"
diff --git a/tests/auto/declarative/qquicktext/tst_qquicktext.cpp b/tests/auto/declarative/qquicktext/tst_qquicktext.cpp
index 3a08dd208d..8ac3a078bc 100644
--- a/tests/auto/declarative/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/declarative/qquicktext/tst_qquicktext.cpp
@@ -520,15 +520,7 @@ void tst_qquicktext::alignments()
QFETCH(int, vAlign);
QFETCH(QString, expectfile);
-#ifdef Q_WS_X11
- // Font-specific, but not likely platform-specific, so only test on one platform
- QFont fn;
- fn.setRawName("-misc-fixed-medium-r-*-*-8-*-*-*-*-*-*-*");
- QApplication::setFont(fn);
-#endif
-
QQuickView *canvas = createView(TESTDATA("alignments.qml"));
-
canvas->show();
canvas->requestActivateWindow();
QTest::qWait(50);
@@ -545,14 +537,9 @@ void tst_qquicktext::alignments()
canvas->render(&p);
QImage expect(expectfile);
-
-#ifdef Q_WS_X11
- // Font-specific, but not likely platform-specific, so only test on one platform
if (QApplicationPrivate::graphics_system_name == "raster" || QApplicationPrivate::graphics_system_name == "") {
QCOMPARE(actual,expect);
}
-#endif
-
delete canvas;
#endif
}
diff --git a/tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp
index 86c33a64d8..693619f638 100644
--- a/tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp
@@ -63,7 +63,7 @@
#include <private/qtextcontrol_p.h>
#include "../shared/util.h"
-#ifdef Q_WS_MAC
+#ifdef Q_OS_MAC
#include <Carbon/Carbon.h>
#endif
@@ -151,8 +151,7 @@ private slots:
void testQtQuick11Attributes();
void testQtQuick11Attributes_data();
- void preeditMicroFocus();
- void inputContextMouseHandler();
+ void preeditCursorRectangle();
void inputMethodComposing();
void cursorRectangleSize();
@@ -573,12 +572,15 @@ void tst_qquicktextedit::hAlign_RightToLeft()
QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
textEdit->setText(QString());
- { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(&canvas, &ev); }
- QEXPECT_FAIL("", "QTBUG-21691", Abort);
+ { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); }
QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight);
- { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(&canvas, &ev); }
+ { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); }
QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft);
+ // Clear pre-edit text. TextEdit should maybe do this itself on setText, but that may be
+ // redundant as an actual input method may take care of it.
+ { QInputMethodEvent ev; QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); }
+
#ifndef Q_OS_MAC // QTBUG-18040
// empty text with implicit alignment follows the system locale-based
// keyboard input direction from QGuiApplication::keyboardInputDirection
@@ -1402,8 +1404,6 @@ void tst_qquicktextedit::mouseSelection()
QTest::mouseClick(&canvas, Qt::LeftButton, Qt::NoModifier, p1);
QTest::mouseClick(&canvas, Qt::LeftButton, Qt::ShiftModifier, p2);
QTest::qWait(50);
- if (!selectedText.isEmpty())
- QEXPECT_FAIL("", "QTBUG-21743", Continue);
QTRY_COMPARE(textEditObject->selectedText(), selectedText);
}
@@ -1525,36 +1525,28 @@ void tst_qquicktextedit::positionAt()
const int y1 = fm.height() * 3 / 2;
int pos = texteditObject->positionAt(texteditObject->width()/2, y0);
- int width = 0;
+ int widthBegin = 0;
+ int widthEnd = 0;
if (!qmlDisableDistanceField()) {
- QTextLayout layout(texteditObject->text().left(pos));
+ QTextLayout layout(texteditObject->text());
- {
- QTextOption option;
- option.setUseDesignMetrics(true);
- layout.setTextOption(option);
- }
+ QTextOption option;
+ option.setUseDesignMetrics(true);
+ layout.setTextOption(option);
layout.beginLayout();
QTextLine line = layout.createLine();
layout.endLayout();
- width = ceil(line.horizontalAdvance());
-
+ widthBegin = floor(line.cursorToX(pos - 1));
+ widthEnd = ceil(line.cursorToX(pos + 1));
} else {
- width = fm.width(texteditObject->text().left(pos));
+ widthBegin = fm.width(texteditObject->text().left(pos - 1));
+ widthEnd = fm.width(texteditObject->text().left(pos + 1));
}
-
- int diff = abs(int(width-texteditObject->width()/2));
-
- QEXPECT_FAIL("", "QTBUG-21689", Abort);
- // some tollerance for different fonts.
-#ifdef Q_OS_LINUX
- QVERIFY(diff < 2);
-#else
- QVERIFY(diff < 5);
-#endif
+ QVERIFY(widthBegin <= texteditObject->width() / 2);
+ QVERIFY(widthEnd >= texteditObject->width() / 2);
const qreal x0 = texteditObject->positionToRectangle(pos).x();
const qreal x1 = texteditObject->positionToRectangle(pos + 1).x();
@@ -1564,7 +1556,7 @@ void tst_qquicktextedit::positionAt()
texteditObject->setCursorPosition(0);
QInputMethodEvent inputEvent(preeditText, QList<QInputMethodEvent::Attribute>());
- QGuiApplication::sendEvent(&canvas, &inputEvent);
+ QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &inputEvent);
// Check all points within the preedit text return the same position.
QCOMPARE(texteditObject->positionAt(0, y0), 0);
@@ -1780,7 +1772,7 @@ void tst_qquicktextedit::navigation()
void tst_qquicktextedit::copyAndPaste() {
#ifndef QT_NO_CLIPBOARD
-#ifdef Q_WS_MAC
+#ifdef Q_OS_MAC
{
PasteboardRef pasteboard;
OSStatus status = PasteboardCreate(0, &pasteboard);
@@ -1909,55 +1901,6 @@ void tst_qquicktextedit::simulateKey(QQuickView *view, int key, Qt::KeyboardModi
QGuiApplication::sendEvent(view, &release);
}
-
-#ifndef QTBUG_21691
-class MyInputContext : public QInputContext
-{
-public:
- MyInputContext() : updateReceived(false), eventType(QEvent::None) {}
- ~MyInputContext() {}
-
- QString identifierName() { return QString(); }
- QString language() { return QString(); }
-
- void reset() {}
-
- bool isComposing() const { return false; }
-
- void update() { updateReceived = true; }
-
- void sendPreeditText(const QString &text, int cursor)
- {
- QList<QInputMethodEvent::Attribute> attributes;
- attributes.append(QInputMethodEvent::Attribute(
- QInputMethodEvent::Cursor, cursor, text.length(), QVariant()));
-
- QInputMethodEvent event(text, attributes);
- sendEvent(event);
- }
-
- void mouseHandler(int x, QMouseEvent *event)
- {
- cursor = x;
- eventType = event->type();
- eventPosition = event->pos();
- eventGlobalPosition = event->globalPos();
- eventButton = event->button();
- eventButtons = event->buttons();
- eventModifiers = event->modifiers();
- }
-
- bool updateReceived;
- int cursor;
- QEvent::Type eventType;
- QPoint eventPosition;
- QPoint eventGlobalPosition;
- Qt::MouseButton eventButton;
- Qt::MouseButtons eventButtons;
- Qt::KeyboardModifiers eventModifiers;
-};
-#endif
-
void tst_qquicktextedit::textInput()
{
QQuickView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml")));
@@ -1972,8 +1915,7 @@ void tst_qquicktextedit::textInput()
// test that input method event is committed
QInputMethodEvent event;
event.setCommitString( "Hello world!", 0, 0);
- QGuiApplication::sendEvent(&view, &event);
- QEXPECT_FAIL("", "QTBUG-21689", Abort);
+ QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event);
QCOMPARE(edit->text(), QString("Hello world!"));
// QTBUG-12339
@@ -2179,12 +2121,8 @@ void tst_qquicktextedit::testQtQuick11Attributes_data()
<< ":1 \"TextEdit.onLinkActivated\" is not available in QtQuick 1.0.\n";
}
-void tst_qquicktextedit::preeditMicroFocus()
+void tst_qquicktextedit::preeditCursorRectangle()
{
-#ifdef QTBUG_21691
- QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
- QVERIFY(false);
-#else
QString preeditText = "super";
QQuickView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml")));
@@ -2196,173 +2134,52 @@ void tst_qquicktextedit::preeditMicroFocus()
QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(view.rootObject());
QVERIFY(edit);
- QSignalSpy cursorRectangleSpy(edit, SIGNAL(cursorRectangleChanged()));
+ QSignalSpy editSpy(edit, SIGNAL(cursorRectangleChanged()));
+ QSignalSpy panelSpy(qGuiApp->inputPanel(), SIGNAL(cursorRectangleChanged()));
QRect currentRect;
- QRect previousRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect();
+
+ QInputMethodQueryEvent query(Qt::ImCursorRectangle);
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query);
+ QRect previousRect = query.value(Qt::ImCursorRectangle).toRect();
// Verify that the micro focus rect is positioned the same for position 0 as
// it would be if there was no preedit text.
- ic.updateReceived = false;
- ic.sendPreeditText(preeditText, 0);
- currentRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect();
+ QInputMethodEvent imEvent(preeditText, QList<QInputMethodEvent::Attribute>()
+ << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, preeditText.length(), QVariant()));
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent);
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query);
+ currentRect = query.value(Qt::ImCursorRectangle).toRect();
QCOMPARE(currentRect, previousRect);
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
- QCOMPARE(ic.updateReceived, false); // The cursor position hasn't changed.
-#endif
- QCOMPARE(cursorRectangleSpy.count(), 0);
+ QCOMPARE(editSpy.count(), 0);
+ QCOMPARE(panelSpy.count(), 0);
// Verify that the micro focus rect moves to the left as the cursor position
// is incremented.
for (int i = 1; i <= 5; ++i) {
- ic.updateReceived = false;
- ic.sendPreeditText(preeditText, i);
- currentRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect();
+ QInputMethodEvent imEvent(preeditText, QList<QInputMethodEvent::Attribute>()
+ << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, i, preeditText.length(), QVariant()));
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent);
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query);
+ currentRect = query.value(Qt::ImCursorRectangle).toRect();
QVERIFY(previousRect.left() < currentRect.left());
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
- QCOMPARE(ic.updateReceived, true);
-#endif
- QVERIFY(cursorRectangleSpy.count() > 0);
- cursorRectangleSpy.clear();
+ QVERIFY(editSpy.count() > 0); editSpy.clear();
+ QVERIFY(panelSpy.count() > 0); panelSpy.clear();
previousRect = currentRect;
}
// Verify that if there is no preedit cursor then the micro focus rect is the
// same as it would be if it were positioned at the end of the preedit text.
- ic.sendPreeditText(preeditText, 0);
- ic.updateReceived = false;
- ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>()));
- currentRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect();
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent);
+ editSpy.clear();
+ panelSpy.clear();
+ { QInputMethodEvent imEvent(preeditText, QList<QInputMethodEvent::Attribute>());
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); }
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query);
+ currentRect = query.value(Qt::ImCursorRectangle).toRect();
QCOMPARE(currentRect, previousRect);
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
- QCOMPARE(ic.updateReceived, true);
-#endif
- QVERIFY(cursorRectangleSpy.count() > 0);
-#endif
-}
-
-void tst_qquicktextedit::inputContextMouseHandler()
-{
-
-#ifdef QTBUG_21691
- QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
- QVERIFY(false);
-#else
- QString text = "supercalifragisiticexpialidocious!";
-
- QQuickView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml")));
- MyInputContext ic;
- // QQuickCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has focus
- // and QWidget won't allow an input context to be set when the flag is not set.
- view.setAttribute(Qt::WA_InputMethodEnabled, true);
- view.setInputContext(&ic);
- view.setAttribute(Qt::WA_InputMethodEnabled, false);
- view.show();
- view.requestActivateWindow();
- QTest::qWaitForWindowShown(&view);
-
- QTRY_COMPARE(&view, qGuiApp->focusWindow());
- QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(view.rootObject());
- QVERIFY(edit);
- edit->setCursorPosition(12);
-
- QFontMetricsF fm(edit->font());
- const qreal y = fm.height() / 2;
-
- QPoint position2 = edit->mapToScene(QPointF(fm.width(text.mid(0, 2)), y)).toPoint();
- QPoint position8 = edit->mapToScene(QPointF(fm.width(text.mid(0, 8)), y)).toPoint();
- QPoint position20 = edit->mapToScene(QPointF(fm.width(text.mid(0, 20)), y)).toPoint();
- QPoint position27 = edit->mapToScene(QPointF(fm.width(text.mid(0, 27)), y)).toPoint();
- QPoint globalPosition2 = view.mapToGlobal(position2);
- QPoint globalposition8 = view.mapToGlobal(position8);
- QPoint globalposition20 = view.mapToGlobal(position20);
- QPoint globalposition27 = view.mapToGlobal(position27);
-
- ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>()));
-
- QTest::mouseDClick(&view, Qt::LeftButton, Qt::NoModifier, position2);
- QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
- QCOMPARE(ic.eventPosition, position2);
- QCOMPARE(ic.eventGlobalPosition, globalPosition2);
- QCOMPARE(ic.eventButton, Qt::LeftButton);
- QCOMPARE(ic.eventModifiers, Qt::NoModifier);
- QVERIFY(ic.cursor < 0);
- ic.eventType = QEvent::None;
-
- QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, position2);
- QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
- QCOMPARE(ic.eventPosition, position2);
- QCOMPARE(ic.eventGlobalPosition, globalPosition2);
- QCOMPARE(ic.eventButton, Qt::LeftButton);
- QCOMPARE(ic.eventModifiers, Qt::NoModifier);
- QVERIFY(ic.cursor < 0);
- ic.eventType = QEvent::None;
-
- { QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QGuiApplication::sendEvent(&view, &mv); }
- QCOMPARE(ic.eventType, QEvent::None);
-
- { QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QGuiApplication::sendEvent(&view, &mv); }
- QCOMPARE(ic.eventType, QEvent::MouseMove);
- QCOMPARE(ic.eventPosition, position27);
- QCOMPARE(ic.eventGlobalPosition, globalposition27);
- QCOMPARE(ic.eventButton, Qt::LeftButton);
- QCOMPARE(ic.eventModifiers, Qt::NoModifier);
- QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); // 15 is expected but some platforms may be off by one.
- ic.eventType = QEvent::None;
-
- QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, position27);
- QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
- QCOMPARE(ic.eventPosition, position27);
- QCOMPARE(ic.eventGlobalPosition, globalposition27);
- QCOMPARE(ic.eventButton, Qt::LeftButton);
- QCOMPARE(ic.eventModifiers, Qt::NoModifier);
- QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
- ic.eventType = QEvent::None;
-
- // And in the other direction.
- QTest::mouseDClick(&view, Qt::LeftButton, Qt::ControlModifier, position27);
- QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
- QCOMPARE(ic.eventPosition, position27);
- QCOMPARE(ic.eventGlobalPosition, globalposition27);
- QCOMPARE(ic.eventButton, Qt::LeftButton);
- QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
- QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
- ic.eventType = QEvent::None;
-
- QTest::mousePress(&view, Qt::RightButton, Qt::ControlModifier, position27);
- QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
- QCOMPARE(ic.eventPosition, position27);
- QCOMPARE(ic.eventGlobalPosition, globalposition27);
- QCOMPARE(ic.eventButton, Qt::RightButton);
- QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
- QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
- ic.eventType = QEvent::None;
-
- { QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
- QGuiApplication::sendEvent(&view, &mv); }
- QCOMPARE(ic.eventType, QEvent::MouseMove);
- QCOMPARE(ic.eventPosition, position20);
- QCOMPARE(ic.eventGlobalPosition, globalposition20);
- QCOMPARE(ic.eventButton, Qt::RightButton);
- QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
- QVERIFY(ic.cursor >= 7 && ic.cursor <= 9);
- ic.eventType = QEvent::None;
-
- { QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
- QGuiApplication::sendEvent(&view, &mv); }
- QCOMPARE(ic.eventType, QEvent::None);
-
- QTest::mouseRelease(&view, Qt::RightButton, Qt::ControlModifier, position2);
- QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
- QCOMPARE(ic.eventPosition, position2);
- QCOMPARE(ic.eventGlobalPosition, globalPosition2);
- QCOMPARE(ic.eventButton, Qt::RightButton);
- QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
- QVERIFY(ic.cursor < 0);
- ic.eventType = QEvent::None;
-#endif
+ QVERIFY(editSpy.count() > 0);
+ QVERIFY(panelSpy.count() > 0);
}
void tst_qquicktextedit::inputMethodComposing()
diff --git a/tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp
index 23224d0452..bf29f88ff1 100644
--- a/tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp
@@ -56,6 +56,10 @@
#include <QtOpenGL/QGLShaderProgram>
#include <math.h>
+#ifdef Q_OS_MAC
+#include <Carbon/Carbon.h>
+#endif
+
#include "qplatformdefs.h"
Q_DECLARE_METATYPE(QQuickTextInput::SelectionMode)
@@ -142,8 +146,7 @@ private slots:
void testQtQuick11Attributes_data();
void preeditAutoScroll();
- void preeditMicroFocus();
- void inputContextMouseHandler();
+ void preeditCursorRectangle();
void inputMethodComposing();
void cursorRectangleSize();
@@ -1158,15 +1161,20 @@ void tst_qquicktextinput::horizontalAlignment_RightToLeft()
// If there is no commited text, the preedit text should determine the alignment.
textInput->setText(QString());
- { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(&canvas, &ev); }
- QEXPECT_FAIL("", "QTBUG-21691", Continue);
+ { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); }
QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
- { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(&canvas, &ev); }
+ { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); }
QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft);
-#ifndef Q_OS_MAC // QTBUG-18040
+ // Clear pre-edit text. TextInput should maybe do this itself on setText, but that may be
+ // redundant as an actual input method may take care of it.
+ { QInputMethodEvent ev; QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); }
+
+#ifdef Q_OS_MAC
// empty text with implicit alignment follows the system locale-based
// keyboard input direction from QGuiApplication::keyboardInputDirection
+ QEXPECT_FAIL("", "QTBUG-18040", Abort);
+#endif
textInput->setText("");
QCOMPARE(textInput->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ?
QQuickTextInput::AlignLeft : QQuickTextInput::AlignRight);
@@ -1177,10 +1185,11 @@ void tst_qquicktextinput::horizontalAlignment_RightToLeft()
textInput->setHAlign(QQuickTextInput::AlignRight);
QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
-#endif
-#ifndef Q_OS_MAC // QTBUG-18040
- // alignment of TextInput with no text set to it
+
+#ifdef Q_OS_MAC
+ QEXPECT_FAIL("", "QTBUG-18040", Abort); // alignment of TextInput with no text set to it
+#endif
QString componentStr = "import QtQuick 2.0\nTextInput {}";
QDeclarativeComponent textComponent(&engine);
textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
@@ -1188,7 +1197,6 @@ void tst_qquicktextinput::horizontalAlignment_RightToLeft()
QCOMPARE(textObject->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ?
QQuickTextInput::AlignLeft : QQuickTextInput::AlignRight);
delete textObject;
-#endif
}
void tst_qquicktextinput::positionAt()
@@ -1207,52 +1215,30 @@ void tst_qquicktextinput::positionAt()
int pos = textinputObject->positionAt(textinputObject->width()/2);
int textWidth = 0;
- int textLeftWidth = 0;
+ int textLeftWidthBegin = 0;
+ int textLeftWidthEnd = 0;
if (!qmlDisableDistanceField()) {
- {
- QTextLayout layout(textinputObject->text().left(pos));
+ QTextLayout layout(textinputObject->text());
- {
- QTextOption option;
- option.setUseDesignMetrics(true);
- layout.setTextOption(option);
- }
-
- layout.beginLayout();
- QTextLine line = layout.createLine();
- layout.endLayout();
+ QTextOption option;
+ option.setUseDesignMetrics(true);
+ layout.setTextOption(option);
- textLeftWidth = ceil(line.horizontalAdvance());
- }
- {
- QTextLayout layout(textinputObject->text());
+ layout.beginLayout();
+ QTextLine line = layout.createLine();
+ layout.endLayout();
- {
- QTextOption option;
- option.setUseDesignMetrics(true);
- layout.setTextOption(option);
- }
-
- layout.beginLayout();
- QTextLine line = layout.createLine();
- layout.endLayout();
-
- textWidth = ceil(line.horizontalAdvance());
- }
+ textLeftWidthBegin = floor(line.cursorToX(pos - 1));
+ textLeftWidthEnd = ceil(line.cursorToX(pos + 1));
+ textWidth = floor(line.horizontalAdvance());
} else {
textWidth = fm.width(textinputObject->text());
- textLeftWidth = fm.width(textinputObject->text().left(pos));
+ textLeftWidthBegin = fm.width(textinputObject->text().left(pos - 1));
+ textLeftWidthEnd = fm.width(textinputObject->text().left(pos + 1));
}
- int diff = abs(textWidth - (textLeftWidth+textinputObject->width()/2));
-
- // some tollerance for different fonts.
- QEXPECT_FAIL("", "QTBUG-21689", Abort);
-#ifdef Q_OS_LINUX
- QVERIFY(diff < 2);
-#else
- QVERIFY(diff < 5);
-#endif
+ QVERIFY(textLeftWidthBegin <= textWidth - textinputObject->width() / 2);
+ QVERIFY(textLeftWidthEnd >= textWidth - textinputObject->width() / 2);
int x = textinputObject->positionToRectangle(pos + 1).x() - 1;
QCOMPARE(textinputObject->positionAt(x, QQuickTextInput::CursorBetweenCharacters), pos + 1);
@@ -1263,33 +1249,25 @@ void tst_qquicktextinput::positionAt()
pos = textinputObject->positionAt(textinputObject->width()/2);
if (!qmlDisableDistanceField()) {
- {
- QTextLayout layout(textinputObject->text().left(pos));
+ QTextLayout layout(textinputObject->text());
- {
- QTextOption option;
- option.setUseDesignMetrics(true);
- layout.setTextOption(option);
- }
+ QTextOption option;
+ option.setUseDesignMetrics(true);
+ layout.setTextOption(option);
- layout.beginLayout();
- QTextLine line = layout.createLine();
- layout.endLayout();
+ layout.beginLayout();
+ QTextLine line = layout.createLine();
+ layout.endLayout();
- textLeftWidth = ceil(line.horizontalAdvance());
- }
+ textLeftWidthBegin = floor(line.cursorToX(pos - 1));
+ textLeftWidthEnd = ceil(line.cursorToX(pos + 1));
} else {
- textLeftWidth = fm.width(textinputObject->text().left(pos));
+ textLeftWidthBegin = fm.width(textinputObject->text().left(pos - 1));
+ textLeftWidthEnd = fm.width(textinputObject->text().left(pos + 1));
}
- diff = abs(int(textLeftWidth-textinputObject->width()/2));
-
- // some tollerance for different fonts.
-#ifdef Q_OS_LINUX
- QVERIFY(diff < 2);
-#else
- QVERIFY(diff < 5);
-#endif
+ QVERIFY(textLeftWidthBegin <= textinputObject->width() / 2);
+ QVERIFY(textLeftWidthEnd >= textinputObject->width() / 2);
x = textinputObject->positionToRectangle(pos + 1).x() - 1;
QCOMPARE(textinputObject->positionAt(x, QQuickTextInput::CursorBetweenCharacters), pos + 1);
@@ -1303,7 +1281,7 @@ void tst_qquicktextinput::positionAt()
textinputObject->setCursorPosition(0);
QInputMethodEvent inputEvent(preeditText, QList<QInputMethodEvent::Attribute>());
- QGuiApplication::sendEvent(&canvas, &inputEvent);
+ QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &inputEvent);
// Check all points within the preedit text return the same position.
QCOMPARE(textinputObject->positionAt(0), 0);
@@ -1495,25 +1473,24 @@ void tst_qquicktextinput::inputMethods()
// test that input method event is committed
QInputMethodEvent event;
event.setCommitString( "My ", -12, 0);
- QGuiApplication::sendEvent(&canvas, &event);
- QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
+ QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event);
QCOMPARE(input->text(), QString("My Hello world!"));
input->setCursorPosition(2);
event.setCommitString("Your", -2, 2);
- QGuiApplication::sendEvent(&canvas, &event);
+ QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event);
QCOMPARE(input->text(), QString("Your Hello world!"));
QCOMPARE(input->cursorPosition(), 4);
input->setCursorPosition(7);
event.setCommitString("Goodbye", -2, 5);
- QGuiApplication::sendEvent(&canvas, &event);
+ QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event);
QCOMPARE(input->text(), QString("Your Goodbye world!"));
QCOMPARE(input->cursorPosition(), 12);
input->setCursorPosition(8);
event.setCommitString("Our", -8, 4);
- QGuiApplication::sendEvent(&canvas, &event);
+ QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event);
QCOMPARE(input->text(), QString("Our Goodbye world!"));
QCOMPARE(input->cursorPosition(), 7);
}
@@ -1602,7 +1579,7 @@ void tst_qquicktextinput::navigation_RTL()
void tst_qquicktextinput::copyAndPaste() {
#ifndef QT_NO_CLIPBOARD
-#ifdef Q_WS_MAC
+#ifdef Q_OS_MAC
{
PasteboardRef pasteboard;
OSStatus status = PasteboardCreate(0, &pasteboard);
@@ -2265,66 +2242,69 @@ void tst_qquicktextinput::testQtQuick11Attributes_data()
<< "";
}
+static void sendPreeditText(const QString &text, int cursor)
+{
+ QInputMethodEvent event(text, QList<QInputMethodEvent::Attribute>()
+ << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursor, text.length(), QVariant()));
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event);
+}
+
void tst_qquicktextinput::preeditAutoScroll()
{
-#ifdef QTBUG_21691
- QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
- QVERIFY(false);
-#else
QString preeditText = "califragisiticexpialidocious!";
QQuickView view(QUrl::fromLocalFile(TESTDATA("preeditAutoScroll.qml")));
- MyInputContext ic;
- // QQuickCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has active focus
- // and QWidget won't allow an input context to be set when the flag is not set.
- view.setAttribute(Qt::WA_InputMethodEnabled, true);
- view.setInputContext(&ic);
- view.setAttribute(Qt::WA_InputMethodEnabled, false);
view.show();
view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
QTRY_COMPARE(&view, qGuiApp->focusWindow());
QQuickTextInput *input = qobject_cast<QQuickTextInput *>(view.rootObject());
QVERIFY(input);
+ QVERIFY(input->hasActiveFocus());
+
+ input->setWidth(input->implicitWidth());
QSignalSpy cursorRectangleSpy(input, SIGNAL(cursorRectangleChanged()));
int cursorRectangleChanges = 0;
- QFontMetricsF fm(input->font());
- input->setWidth(fm.width(input->text()));
-
// test the text is scrolled so the preedit is visible.
- ic.sendPreeditText(preeditText.mid(0, 3), 1);
+ sendPreeditText(preeditText.mid(0, 3), 1);
QVERIFY(input->positionAt(0) != 0);
QVERIFY(input->cursorRectangle().left() < input->boundingRect().width());
QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
// test the text is scrolled back when the preedit is removed.
- ic.sendEvent(QInputMethodEvent());
+ QInputMethodEvent imEvent;
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent);
QCOMPARE(input->positionAt(0), 0);
QCOMPARE(input->positionAt(input->width()), 5);
QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
- // some tolerance for different fonts.
-#ifdef Q_OS_LINUX
- const int error = 2;
-#else
- const int error = 5;
-#endif
+ QTextLayout layout(preeditText);
+ if (!qmlDisableDistanceField()) {
+ QTextOption option;
+ option.setUseDesignMetrics(true);
+ layout.setTextOption(option);
+ }
+ layout.beginLayout();
+ QTextLine line = layout.createLine();
+ layout.endLayout();
// test if the preedit is larger than the text input that the
// character preceding the cursor is still visible.
qreal x = input->positionToRectangle(0).x();
for (int i = 0; i < 3; ++i) {
- ic.sendPreeditText(preeditText, i + 1);
- QVERIFY(input->cursorRectangle().right() >= fm.width(preeditText.at(i)) - error);
+ sendPreeditText(preeditText, i + 1);
+ int width = ceil(line.cursorToX(i, QTextLine::Trailing)) - floor(line.cursorToX(i));
+ QVERIFY(input->cursorRectangle().right() >= width - 3);
QVERIFY(input->positionToRectangle(0).x() < x);
QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
x = input->positionToRectangle(0).x();
}
for (int i = 1; i >= 0; --i) {
- ic.sendPreeditText(preeditText, i + 1);
- QVERIFY(input->cursorRectangle().right() >= fm.width(preeditText.at(i)) - error);
+ sendPreeditText(preeditText, i + 1);
+ int width = ceil(line.cursorToX(i, QTextLine::Trailing)) - floor(line.cursorToX(i));
+ QVERIFY(input->cursorRectangle().right() >= width - 3);
QVERIFY(input->positionToRectangle(0).x() > x);
QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
x = input->positionToRectangle(0).x();
@@ -2332,45 +2312,34 @@ void tst_qquicktextinput::preeditAutoScroll()
// Test incrementing the preedit cursor doesn't cause further
// scrolling when right most text is visible.
- ic.sendPreeditText(preeditText, preeditText.length() - 3);
+ sendPreeditText(preeditText, preeditText.length() - 3);
QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
x = input->positionToRectangle(0).x();
for (int i = 2; i >= 0; --i) {
- ic.sendPreeditText(preeditText, preeditText.length() - i);
+ sendPreeditText(preeditText, preeditText.length() - i);
QCOMPARE(input->positionToRectangle(0).x(), x);
QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
}
for (int i = 1; i < 3; ++i) {
- ic.sendPreeditText(preeditText, preeditText.length() - i);
+ sendPreeditText(preeditText, preeditText.length() - i);
QCOMPARE(input->positionToRectangle(0).x(), x);
QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
}
// Test disabling auto scroll.
- ic.sendEvent(QInputMethodEvent());
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent);
input->setAutoScroll(false);
- ic.sendPreeditText(preeditText.mid(0, 3), 1);
+ sendPreeditText(preeditText.mid(0, 3), 1);
QCOMPARE(input->positionAt(0), 0);
QCOMPARE(input->positionAt(input->width()), 5);
-#endif
}
-void tst_qquicktextinput::preeditMicroFocus()
+void tst_qquicktextinput::preeditCursorRectangle()
{
-#ifdef QTBUG_21691
- QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
- QVERIFY(false);
-#else
QString preeditText = "super";
QQuickView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml")));
- MyInputContext ic;
- // QQuickCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has active focus
- // and QWidget won't allow an input context to be set when the flag is not set.
- view.setAttribute(Qt::WA_InputMethodEnabled, true);
- view.setInputContext(&ic);
- view.setAttribute(Qt::WA_InputMethodEnabled, false);
view.show();
view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
@@ -2379,163 +2348,43 @@ void tst_qquicktextinput::preeditMicroFocus()
QVERIFY(input);
QRect currentRect;
- QRect previousRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect();
+
+ QInputMethodQueryEvent query(Qt::ImCursorRectangle);
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query);
+ QRect previousRect = query.value(Qt::ImCursorRectangle).toRect();
// Verify that the micro focus rect is positioned the same for position 0 as
// it would be if there was no preedit text.
- ic.updateReceived = false;
- ic.sendPreeditText(preeditText, 0);
- currentRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect();
+ sendPreeditText(preeditText, 0);
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query);
+ currentRect = query.value(Qt::ImCursorRectangle).toRect();
QCOMPARE(currentRect, previousRect);
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
- QCOMPARE(ic.updateReceived, true);
-#endif
+
+ QSignalSpy inputSpy(input, SIGNAL(cursorRectangleChanged()));
+ QSignalSpy panelSpy(qGuiApp->inputPanel(), SIGNAL(cursorRectangleChanged()));
// Verify that the micro focus rect moves to the left as the cursor position
// is incremented.
for (int i = 1; i <= 5; ++i) {
- ic.updateReceived = false;
- ic.sendPreeditText(preeditText, i);
- currentRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect();
+ sendPreeditText(preeditText, i);
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query);
+ currentRect = query.value(Qt::ImCursorRectangle).toRect();
QVERIFY(previousRect.left() < currentRect.left());
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
- QCOMPARE(ic.updateReceived, true);
-#endif
+ QVERIFY(inputSpy.count() > 0); inputSpy.clear();
+ QVERIFY(panelSpy.count() > 0); panelSpy.clear();
previousRect = currentRect;
}
// Verify that if there is no preedit cursor then the micro focus rect is the
// same as it would be if it were positioned at the end of the preedit text.
- ic.sendPreeditText(preeditText, 0);
- ic.updateReceived = false;
- ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>()));
- currentRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect();
+ sendPreeditText(preeditText, 0);
+ QInputMethodEvent imEvent(preeditText, QList<QInputMethodEvent::Attribute>());
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent);
+ QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query);
+ currentRect = query.value(Qt::ImCursorRectangle).toRect();
QCOMPARE(currentRect, previousRect);
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
- QCOMPARE(ic.updateReceived, true);
-#endif
-#endif
-}
-
-void tst_qquicktextinput::inputContextMouseHandler()
-{
-#ifdef QTBUG_21691
- QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
- QVERIFY(false);
-#else
- QString text = "supercalifragisiticexpialidocious!";
-
- QQuickView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml")));
- MyInputContext ic;
- // QQuickCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has active focus
- // and QWidget won't allow an input context to be set when the flag is not set.
- view.setAttribute(Qt::WA_InputMethodEnabled, true);
- view.setInputContext(&ic);
- view.setAttribute(Qt::WA_InputMethodEnabled, false);
- view.show();
- view.requestActivateWindow();
- QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(&view, qGuiApp->focusWindow());
- QQuickTextInput *input = qobject_cast<QQuickTextInput *>(view.rootObject());
- QVERIFY(input);
-
- QFontMetricsF fm(input->font());
- const qreal y = fm.height() / 2;
-
- QPoint position2 = input->mapToScene(QPointF(fm.width(text.mid(0, 2)), y)).toPoint();
- QPoint position8 = input->mapToScene(QPointF(fm.width(text.mid(0, 8)), y)).toPoint();
- QPoint position20 = input->mapToScene(QPointF(fm.width(text.mid(0, 20)), y)).toPoint();
- QPoint position27 = input->mapToScene(QPointF(fm.width(text.mid(0, 27)), y)).toPoint();
- QPoint globalPosition2 = view.mapToGlobal(position2);
- QPoint globalposition8 = view.mapToGlobal(position8);
- QPoint globalposition20 = view.mapToGlobal(position20);
- QPoint globalposition27 = view.mapToGlobal(position27);
-
- ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>()));
-
- QTest::mouseDClick(&view, Qt::LeftButton, Qt::NoModifier, position2);
- QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
- QCOMPARE(ic.eventPosition, position2);
- QCOMPARE(ic.eventGlobalPosition, globalPosition2);
- QCOMPARE(ic.eventButton, Qt::LeftButton);
- QCOMPARE(ic.eventModifiers, Qt::NoModifier);
- QVERIFY(ic.cursor < 0);
- ic.eventType = QEvent::None;
-
- QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, position2);
- QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
- QCOMPARE(ic.eventPosition, position2);
- QCOMPARE(ic.eventGlobalPosition, globalPosition2);
- QCOMPARE(ic.eventButton, Qt::LeftButton);
- QCOMPARE(ic.eventModifiers, Qt::NoModifier);
- QVERIFY(ic.cursor < 0);
- ic.eventType = QEvent::None;
-
- { QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QGuiApplication::sendEvent(&view, &mv); }
- QCOMPARE(ic.eventType, QEvent::None);
-
- { QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QGuiApplication::sendEvent(&view, &mv); }
- QCOMPARE(ic.eventType, QEvent::MouseMove);
- QCOMPARE(ic.eventPosition, position27);
- QCOMPARE(ic.eventGlobalPosition, globalposition27);
- QCOMPARE(ic.eventButton, Qt::LeftButton);
- QCOMPARE(ic.eventModifiers, Qt::NoModifier);
- QVERIFY(ic.cursor >= 14 && ic.cursor <= 16); // 15 is expected but some platforms may be off by one.
- ic.eventType = QEvent::None;
-
- QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, position27);
- QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
- QCOMPARE(ic.eventPosition, position27);
- QCOMPARE(ic.eventGlobalPosition, globalposition27);
- QCOMPARE(ic.eventButton, Qt::LeftButton);
- QCOMPARE(ic.eventModifiers, Qt::NoModifier);
- QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
- ic.eventType = QEvent::None;
-
- // And in the other direction.
- QTest::mouseDClick(&view, Qt::LeftButton, Qt::ControlModifier, position27);
- QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
- QCOMPARE(ic.eventPosition, position27);
- QCOMPARE(ic.eventGlobalPosition, globalposition27);
- QCOMPARE(ic.eventButton, Qt::LeftButton);
- QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
- QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
- ic.eventType = QEvent::None;
-
- QTest::mousePress(&view, Qt::RightButton, Qt::ControlModifier, position27);
- QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
- QCOMPARE(ic.eventPosition, position27);
- QCOMPARE(ic.eventGlobalPosition, globalposition27);
- QCOMPARE(ic.eventButton, Qt::RightButton);
- QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
- QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
- ic.eventType = QEvent::None;
-
- { QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
- QGuiApplication::sendEvent(&view, &mv); }
- QCOMPARE(ic.eventType, QEvent::MouseMove);
- QCOMPARE(ic.eventPosition, position20);
- QCOMPARE(ic.eventGlobalPosition, globalposition20);
- QCOMPARE(ic.eventButton, Qt::RightButton);
- QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
- QVERIFY(ic.cursor >= 7 && ic.cursor <= 9);
- ic.eventType = QEvent::None;
-
- { QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
- QGuiApplication::sendEvent(&view, &mv); }
- QCOMPARE(ic.eventType, QEvent::None);
-
- QTest::mouseRelease(&view, Qt::RightButton, Qt::ControlModifier, position2);
- QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
- QCOMPARE(ic.eventPosition, position2);
- QCOMPARE(ic.eventGlobalPosition, globalPosition2);
- QCOMPARE(ic.eventButton, Qt::RightButton);
- QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
- QVERIFY(ic.cursor < 0);
- ic.eventType = QEvent::None;
-#endif
+ QVERIFY(inputSpy.count() > 0);
+ QVERIFY(panelSpy.count() > 0);
}
void tst_qquicktextinput::inputMethodComposing()
diff --git a/tests/auto/declarative/qquickview/tst_qquickview.cpp b/tests/auto/declarative/qquickview/tst_qquickview.cpp
index a2334d2e58..fc480b5fca 100644
--- a/tests/auto/declarative/qquickview/tst_qquickview.cpp
+++ b/tests/auto/declarative/qquickview/tst_qquickview.cpp
@@ -89,9 +89,8 @@ void tst_QQuickView::resizemodeitem()
// size update from view
canvas->resize(QSize(80,100));
- QTest::qWait(50);
- QCOMPARE(item->width(), 80.0);
+ QTRY_COMPARE(item->width(), 80.0);
QCOMPARE(item->height(), 100.0);
QCOMPARE(canvas->size(), QSize(80, 100));
QCOMPARE(canvas->size(), canvas->sizeHint());
@@ -177,7 +176,6 @@ void tst_QQuickView::resizemodeitem()
QTest::qWait(50);
// initial size from root object
- QEXPECT_FAIL("", "QTBUG-22019", Abort);
QCOMPARE(item->width(), 300.0);
QCOMPARE(item->height(), 300.0);
QCOMPARE(canvas->size(), QSize(300, 300));
diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/create.qml b/tests/auto/declarative/qquickvisualdatamodel/data/create.qml
index 36ea3baf76..3475a0dace 100644
--- a/tests/auto/declarative/qquickvisualdatamodel/data/create.qml
+++ b/tests/auto/declarative/qquickvisualdatamodel/data/create.qml
@@ -7,6 +7,8 @@ ListView {
model: VisualDataModel {
id: visualModel
+ persistedItems.includeByDefault: true
+
model: myModel
delegate: Item {
id: delegate
@@ -16,6 +18,7 @@ ListView {
property bool destroyed: false
+
Component.onDestruction: destroyed = true
}
}
diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/datalist-package.qml b/tests/auto/declarative/qquickvisualdatamodel/data/datalist-package.qml
new file mode 100644
index 0000000000..ae3bd81d91
--- /dev/null
+++ b/tests/auto/declarative/qquickvisualdatamodel/data/datalist-package.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.0
+
+ListView {
+ width: 100
+ height: 100
+ model: visualModel.parts.package
+ VisualDataModel {
+ id: visualModel
+ objectName: "visualModel"
+ model: myModel
+ delegate: Package {
+ Rectangle {
+ height: 25
+ width: 100
+ Package.name: "package"
+ Text { objectName: "display"; text: display }
+ }
+ }
+ }
+}
diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/groups-invalid.qml b/tests/auto/declarative/qquickvisualdatamodel/data/groups-invalid.qml
new file mode 100644
index 0000000000..70c6f9f995
--- /dev/null
+++ b/tests/auto/declarative/qquickvisualdatamodel/data/groups-invalid.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+
+VisualDataModel {
+ id: visualModel
+
+ objectName: "visualModel"
+
+ groups: [
+ VisualDataGroup { id: visibleItems; objectName: "visibleItems"; name: "visible"; includeByDefault: true },
+ VisualDataGroup { id: selectedItems; objectName: "selectedItems"; name: "selected" },
+ VisualDataGroup { id: unnamed; objectName: "unnamed" },
+ VisualDataGroup { id: capitalised; objectName: "capitalised"; name: "Capitalised" }
+ ]
+}
diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/groups-package.qml b/tests/auto/declarative/qquickvisualdatamodel/data/groups-package.qml
new file mode 100644
index 0000000000..ea5ad5d3bd
--- /dev/null
+++ b/tests/auto/declarative/qquickvisualdatamodel/data/groups-package.qml
@@ -0,0 +1,52 @@
+import QtQuick 2.0
+
+ListView {
+ width: 100
+ height: 100
+
+ function contains(array, value) {
+ for (var i = 0; i < array.length; ++i)
+ if (array[i] == value)
+ return true
+ return false
+ }
+ model: visualModel.parts.package
+
+ VisualDataModel {
+ id: visualModel
+
+ objectName: "visualModel"
+
+ groups: [
+ VisualDataGroup { id: visibleItems; objectName: "visibleItems"; name: "visible"; includeByDefault: true },
+ VisualDataGroup { id: selectedItems; objectName: "selectedItems"; name: "selected" }
+ ]
+
+ model: myModel
+ delegate: Package {
+ id: delegate
+
+ property variant test1: name
+ property variant test2: index
+ property variant test3: VisualDataModel.itemsIndex
+ property variant test4: VisualDataModel.inItems
+ property variant test5: VisualDataModel.visibleIndex
+ property variant test6: VisualDataModel.inVisible
+ property variant test7: VisualDataModel.selectedIndex
+ property variant test8: VisualDataModel.inSelected
+ property variant test9: VisualDataModel.groups
+
+ function hide() { VisualDataModel.inVisible = false }
+ function select() { VisualDataModel.inSelected = true }
+
+ Item {
+ Package.name: "package"
+
+ objectName: "delegate"
+ width: 100
+ height: 2
+ }
+ }
+ }
+
+}
diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/groups.qml b/tests/auto/declarative/qquickvisualdatamodel/data/groups.qml
index a24e223bc5..7502dd2502 100644
--- a/tests/auto/declarative/qquickvisualdatamodel/data/groups.qml
+++ b/tests/auto/declarative/qquickvisualdatamodel/data/groups.qml
@@ -11,7 +11,12 @@ ListView {
return false
}
- model: VisualDataModel {
+ model: visualModel
+ VisualDataModel {
+ id: visualModel
+
+ objectName: "visualModel"
+
groups: [
VisualDataGroup { id: visibleItems; objectName: "visibleItems"; name: "visible"; includeByDefault: true },
VisualDataGroup { id: selectedItems; objectName: "selectedItems"; name: "selected" }
@@ -20,6 +25,7 @@ ListView {
model: myModel
delegate: Item {
id: delegate
+
objectName: "delegate"
width: 100
height: 2
diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/onChanged.qml b/tests/auto/declarative/qquickvisualdatamodel/data/onChanged.qml
new file mode 100644
index 0000000000..71dc7d72d7
--- /dev/null
+++ b/tests/auto/declarative/qquickvisualdatamodel/data/onChanged.qml
@@ -0,0 +1,87 @@
+import QtQuick 2.0
+
+VisualDataModel {
+ id: vm
+
+ property var inserted
+ property var removed
+
+ Component.onCompleted: {
+ vm.inserted = []
+ vm.removed = []
+ vi.inserted = []
+ vi.removed = []
+ si.inserted = []
+ si.removed = []
+ }
+
+ function verify(changes, indexes, counts, moveIds) {
+ if (changes.length != indexes.length
+ || changes.length != counts.length
+ || changes.length != moveIds.length) {
+ console.log("invalid length", changes.length, indexes.length, counts.length, moveIds.length)
+ return false
+ }
+
+ var valid = true;
+ for (var i = 0; i < changes.length; ++i) {
+ if (changes[i].index != indexes[i]) {
+ console.log(i, "incorrect index. actual:", changes[i].index, "expected:", indexes[i])
+ valid = false;
+ }
+ if (changes[i].count != counts[i]) {
+ console.log(i, "incorrect count. actual:", changes[i].count, "expected:", counts[i])
+ valid = false;
+ }
+ if (changes[i].moveId != moveIds[i]) {
+ console.log(i, "incorrect moveId. actual:", changes[i].moveId, "expected:", moveIds[i])
+ valid = false;
+ }
+ }
+ return valid
+ }
+
+ groups: [
+ VisualDataGroup {
+ id: vi;
+
+ property var inserted
+ property var removed
+
+ name: "visible"
+ includeByDefault: true
+
+ onChanged: {
+ vi.inserted = inserted
+ vi.removed = removed
+ }
+ },
+ VisualDataGroup {
+ id: si;
+
+ property var inserted
+ property var removed
+
+ name: "selected"
+ onChanged: {
+ si.inserted = inserted
+ si.removed = removed
+ }
+ }
+ ]
+
+ model: ListModel {
+ id: listModel
+ ListElement { number: "one" }
+ ListElement { number: "two" }
+ ListElement { number: "three" }
+ ListElement { number: "four" }
+ }
+
+ delegate: Item {}
+
+ items.onChanged: {
+ vm.inserted = inserted
+ vm.removed = removed
+ }
+}
diff --git a/tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
index aba760db91..706c20fa15 100644
--- a/tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
+++ b/tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
@@ -122,18 +122,27 @@ private slots:
void initTestCase();
void cleanupTestCase();
void rootIndex();
+ void updateLayout_data();
void updateLayout();
+ void childChanged_data();
void childChanged();
void objectListModel();
void singleRole();
void modelProperties();
+ void noDelegate_data();
void noDelegate();
void qaimRowsMoved();
void qaimRowsMoved_data();
+ void remove_data();
void remove();
+ void move_data();
void move();
+ void groups_data();
void groups();
+ void invalidGroups();
void get();
+ void onChanged_data();
+ void onChanged();
void create();
private:
@@ -262,8 +271,18 @@ void tst_qquickvisualdatamodel::rootIndex()
delete obj;
}
+void tst_qquickvisualdatamodel::updateLayout_data()
+{
+ QTest::addColumn<QUrl>("source");
+
+ QTest::newRow("item delegate") << QUrl::fromLocalFile(TESTDATA("datalist.qml"));
+ QTest::newRow("package delegate") << QUrl::fromLocalFile(TESTDATA("datalist-package.qml"));
+}
+
void tst_qquickvisualdatamodel::updateLayout()
{
+ QFETCH(QUrl, source);
+
QQuickView view;
QStandardItemModel model;
@@ -271,7 +290,7 @@ void tst_qquickvisualdatamodel::updateLayout()
view.rootContext()->setContextProperty("myModel", &model);
- view.setSource(QUrl::fromLocalFile(TESTDATA("datalist.qml")));
+ view.setSource(source);
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
QVERIFY(listview != 0);
@@ -302,8 +321,18 @@ void tst_qquickvisualdatamodel::updateLayout()
QCOMPARE(name->text(), QString("Row 1 Item"));
}
+void tst_qquickvisualdatamodel::childChanged_data()
+{
+ QTest::addColumn<QUrl>("source");
+
+ QTest::newRow("item delegate") << QUrl::fromLocalFile(TESTDATA("datalist.qml"));
+ QTest::newRow("package delegate") << QUrl::fromLocalFile(TESTDATA("datalist-package.qml"));
+}
+
void tst_qquickvisualdatamodel::childChanged()
{
+ QFETCH(QUrl, source);
+
QQuickView view;
QStandardItemModel model;
@@ -311,7 +340,7 @@ void tst_qquickvisualdatamodel::childChanged()
view.rootContext()->setContextProperty("myModel", &model);
- view.setSource(QUrl::fromLocalFile(TESTDATA("datalist.qml")));
+ view.setSource(source);
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
QVERIFY(listview != 0);
@@ -567,8 +596,18 @@ void tst_qquickvisualdatamodel::modelProperties()
//### should also test QStringList and QVariantList
}
+void tst_qquickvisualdatamodel::noDelegate_data()
+{
+ QTest::addColumn<QUrl>("source");
+
+ QTest::newRow("item delegate") << QUrl::fromLocalFile(TESTDATA("datalist.qml"));
+ QTest::newRow("package delegate") << QUrl::fromLocalFile(TESTDATA("datalist-package.qml"));
+}
+
void tst_qquickvisualdatamodel::noDelegate()
{
+ QFETCH(QUrl, source);
+
QQuickView view;
QStandardItemModel model;
@@ -576,7 +615,7 @@ void tst_qquickvisualdatamodel::noDelegate()
view.rootContext()->setContextProperty("myModel", &model);
- view.setSource(QUrl::fromLocalFile(TESTDATA("datalist.qml")));
+ view.setSource(source);
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
QVERIFY(listview != 0);
@@ -669,6 +708,19 @@ void tst_qquickvisualdatamodel::qaimRowsMoved_data()
<< 10 << 1 << 5;
}
+void tst_qquickvisualdatamodel::remove_data()
+{
+ QTest::addColumn<QUrl>("source");
+ QTest::addColumn<QString>("package delegate");
+
+ QTest::newRow("item delegate")
+ << QUrl::fromLocalFile(TESTDATA("groups.qml"))
+ << QString();
+ QTest::newRow("package")
+ << QUrl::fromLocalFile(TESTDATA("groups-package.qml"))
+ << QString("package.");
+}
+
void tst_qquickvisualdatamodel::remove()
{
QQuickView view;
@@ -766,6 +818,19 @@ void tst_qquickvisualdatamodel::remove()
}
}
+void tst_qquickvisualdatamodel::move_data()
+{
+ QTest::addColumn<QUrl>("source");
+ QTest::addColumn<QString>("package delegate");
+
+ QTest::newRow("item delegate")
+ << QUrl::fromLocalFile(TESTDATA("groups.qml"))
+ << QString();
+ QTest::newRow("package")
+ << QUrl::fromLocalFile(TESTDATA("groups-package.qml"))
+ << QString("package.");
+}
+
void tst_qquickvisualdatamodel::move()
{
QQuickView view;
@@ -906,6 +971,18 @@ void tst_qquickvisualdatamodel::move()
}
}
+void tst_qquickvisualdatamodel::groups_data()
+{
+ QTest::addColumn<QUrl>("source");
+ QTest::addColumn<QString>("part");
+
+ QTest::newRow("item delegate")
+ << QUrl::fromLocalFile(TESTDATA("groups.qml"))
+ << QString();
+ QTest::newRow("package")
+ << QUrl::fromLocalFile(TESTDATA("groups-package.qml"))
+ << QString("visualModel.parts.package.");
+}
template <int N> void tst_qquickvisualdatamodel::groups_verify(
const SingleRoleModel &model,
@@ -921,17 +998,17 @@ template <int N> void tst_qquickvisualdatamodel::groups_verify(
for (int i = 0; i < N; ++i) {
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", mIndex[i]);
QVERIFY(delegate);
- QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
- QCOMPARE(delegate->property("test2").toInt() , mIndex[i]);
- QCOMPARE(delegate->property("test3").toInt() , iIndex[i]);
- QCOMPARE(delegate->property("test4").toBool(), true);
- QCOMPARE(delegate->property("test5").toInt() , vIndex[i]);
- QCOMPARE(delegate->property("test6").toBool(), vMember[i]);
- QCOMPARE(delegate->property("test7").toInt() , sIndex[i]);
- QCOMPARE(delegate->property("test8").toBool(), sMember[i]);
- QCOMPARE(delegate->property("test9").toStringList().contains("items") , QBool(true));
- QCOMPARE(delegate->property("test9").toStringList().contains("visible") , QBool(vMember[i]));
- QCOMPARE(delegate->property("test9").toStringList().contains("selected"), QBool(sMember[i]));
+ QCOMPARE(evaluate<QString>(delegate, "test1"), model.list.at(mIndex[i]));
+ QCOMPARE(evaluate<int>(delegate, "test2") , mIndex[i]);
+ QCOMPARE(evaluate<int>(delegate, "test3") , iIndex[i]);
+ QCOMPARE(evaluate<bool>(delegate, "test4"), true);
+ QCOMPARE(evaluate<int>(delegate, "test5") , vIndex[i]);
+ QCOMPARE(evaluate<bool>(delegate, "test6"), vMember[i]);
+ QCOMPARE(evaluate<int>(delegate, "test7") , sIndex[i]);
+ QCOMPARE(evaluate<bool>(delegate, "test8"), sMember[i]);
+ QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("items") , QBool(true));
+ QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("visible") , QBool(vMember[i]));
+ QCOMPARE(evaluate<QStringList>(delegate, "test9").contains("selected"), QBool(sMember[i]));
}
failed = false;
}
@@ -943,6 +1020,9 @@ template <int N> void tst_qquickvisualdatamodel::groups_verify(
void tst_qquickvisualdatamodel::groups()
{
+ QFETCH(QUrl, source);
+ QFETCH(QString, part);
+
QQuickView view;
SingleRoleModel model;
@@ -963,7 +1043,7 @@ void tst_qquickvisualdatamodel::groups()
QDeclarativeContext *ctxt = view.rootContext();
ctxt->setContextProperty("myModel", &model);
- view.setSource(QUrl::fromLocalFile(TESTDATA("groups.qml")));
+ view.setSource(source);
QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
QVERIFY(listview != 0);
@@ -971,13 +1051,13 @@ void tst_qquickvisualdatamodel::groups()
QQuickItem *contentItem = listview->contentItem();
QVERIFY(contentItem != 0);
- QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
+ QQuickVisualDataModel *visualModel = listview->findChild<QQuickVisualDataModel *>("visualModel");
QVERIFY(visualModel);
- QQuickVisualDataGroup *visibleItems = visualModel->findChild<QQuickVisualDataGroup *>("visibleItems");
+ QQuickVisualDataGroup *visibleItems = listview->findChild<QQuickVisualDataGroup *>("visibleItems");
QVERIFY(visibleItems);
- QQuickVisualDataGroup *selectedItems = visualModel->findChild<QQuickVisualDataGroup *>("selectedItems");
+ QQuickVisualDataGroup *selectedItems = listview->findChild<QQuickVisualDataGroup *>("selectedItems");
QVERIFY(selectedItems);
const bool f = false;
@@ -1130,23 +1210,26 @@ void tst_qquickvisualdatamodel::groups()
QCOMPARE(visibleItems->count(), 9);
QCOMPARE(selectedItems->count(), 2);
} {
- evaluate<void>(visualModel, "filterOnGroup = \"visible\"");
+ evaluate<void>(visualModel, part + "filterOnGroup = \"visible\"");
QCOMPARE(listview->count(), 9);
QCOMPARE(visualModel->items()->count(), 12);
QCOMPARE(visibleItems->count(), 9);
QCOMPARE(selectedItems->count(), 2);
+ QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("visible"));
} {
- evaluate<void>(visualModel, "filterOnGroup = \"selected\"");
+ evaluate<void>(visualModel, part + "filterOnGroup = \"selected\"");
QCOMPARE(listview->count(), 2);
QCOMPARE(visualModel->items()->count(), 12);
QCOMPARE(visibleItems->count(), 9);
QCOMPARE(selectedItems->count(), 2);
+ QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("selected"));
} {
- evaluate<void>(visualModel, "filterOnGroup = \"items\"");
+ evaluate<void>(visualModel, part + "filterOnGroup = undefined");
QCOMPARE(listview->count(), 12);
QCOMPARE(visualModel->items()->count(), 12);
QCOMPARE(visibleItems->count(), 9);
QCOMPARE(selectedItems->count(), 2);
+ QCOMPARE(evaluate<QString>(visualModel, part + "filterOnGroup"), QString("items"));
} {
QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 5);
QVERIFY(delegate);
@@ -1410,6 +1493,144 @@ void tst_qquickvisualdatamodel::get()
}
}
+void tst_qquickvisualdatamodel::invalidGroups()
+{
+ QUrl source = QUrl::fromLocalFile(TESTDATA("groups-invalid.qml"));
+ QTest::ignoreMessage(QtWarningMsg, (source.toString() + ":12:9: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("Group names must start with a lower case letter")).toUtf8());
+
+ QDeclarativeComponent component(&engine, source);
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(object);
+
+ QCOMPARE(evaluate<int>(object.data(), "groups.length"), 4);
+ QCOMPARE(evaluate<QString>(object.data(), "groups[0].name"), QString("items"));
+ QCOMPARE(evaluate<QString>(object.data(), "groups[1].name"), QString("persistedItems"));
+ QCOMPARE(evaluate<QString>(object.data(), "groups[2].name"), QString("visible"));
+ QCOMPARE(evaluate<QString>(object.data(), "groups[3].name"), QString("selected"));
+}
+
+void tst_qquickvisualdatamodel::onChanged_data()
+{
+ QTest::addColumn<QString>("expression");
+ QTest::addColumn<QStringList>("tests");
+
+ QTest::newRow("item appended")
+ << QString("listModel.append({\"number\": \"five\"})")
+ << (QStringList()
+ << "verify(vm.removed, [], [], [])"
+ << "verify(vm.inserted, [4], [1], [undefined])"
+ << "verify(vi.removed, [], [], [])"
+ << "verify(vi.inserted, [4], [1], [undefined])"
+ << "verify(si.removed, [], [], [])"
+ << "verify(si.inserted, [], [], [])");
+ QTest::newRow("item prepended")
+ << QString("listModel.insert(0, {\"number\": \"five\"})")
+ << (QStringList()
+ << "verify(vm.removed, [], [], [])"
+ << "verify(vm.inserted, [0], [1], [undefined])"
+ << "verify(vi.removed, [], [], [])"
+ << "verify(vi.inserted, [0], [1], [undefined])"
+ << "verify(si.removed, [], [], [])"
+ << "verify(si.inserted, [], [], [])");
+ QTest::newRow("item inserted")
+ << QString("listModel.insert(2, {\"number\": \"five\"})")
+ << (QStringList()
+ << "verify(vm.removed, [], [], [])"
+ << "verify(vm.inserted, [2], [1], [undefined])"
+ << "verify(vi.removed, [], [], [])"
+ << "verify(vi.inserted, [2], [1], [undefined])"
+ << "verify(si.removed, [], [], [])"
+ << "verify(si.inserted, [], [], [])");
+
+ QTest::newRow("item removed tail")
+ << QString("listModel.remove(3)")
+ << (QStringList()
+ << "verify(vm.removed, [3], [1], [undefined])"
+ << "verify(vm.inserted, [], [], [])"
+ << "verify(vi.removed, [3], [1], [undefined])"
+ << "verify(vi.inserted, [], [], [])"
+ << "verify(si.removed, [], [], [])"
+ << "verify(si.inserted, [], [], [])");
+ QTest::newRow("item removed head")
+ << QString("listModel.remove(0)")
+ << (QStringList()
+ << "verify(vm.removed, [0], [1], [undefined])"
+ << "verify(vm.inserted, [], [], [])"
+ << "verify(vi.removed, [0], [1], [undefined])"
+ << "verify(vi.inserted, [], [], [])"
+ << "verify(si.removed, [], [], [])"
+ << "verify(si.inserted, [], [], [])");
+ QTest::newRow("item removed middle")
+ << QString("listModel.remove(1)")
+ << (QStringList()
+ << "verify(vm.removed, [1], [1], [undefined])"
+ << "verify(vm.inserted, [], [], [])"
+ << "verify(vi.removed, [1], [1], [undefined])"
+ << "verify(vi.inserted, [], [], [])"
+ << "verify(si.removed, [], [], [])"
+ << "verify(si.inserted, [], [], [])");
+
+
+ QTest::newRow("item moved from tail")
+ << QString("listModel.move(3, 0, 1)")
+ << (QStringList()
+ << "verify(vm.removed, [3], [1], [vm.inserted[0].moveId])"
+ << "verify(vm.inserted, [0], [1], [vm.removed[0].moveId])"
+ << "verify(vi.removed, [3], [1], [vi.inserted[0].moveId])"
+ << "verify(vi.inserted, [0], [1], [vi.removed[0].moveId])"
+ << "verify(si.removed, [], [], [])"
+ << "verify(si.inserted, [], [], [])");
+ QTest::newRow("item moved from head")
+ << QString("listModel.move(0, 2, 2)")
+ << (QStringList()
+ << "verify(vm.removed, [0], [2], [vm.inserted[0].moveId])"
+ << "verify(vm.inserted, [2], [2], [vm.removed[0].moveId])"
+ << "verify(vi.removed, [0], [2], [vi.inserted[0].moveId])"
+ << "verify(vi.inserted, [2], [2], [vi.removed[0].moveId])"
+ << "verify(si.removed, [], [], [])"
+ << "verify(si.inserted, [], [], [])");
+
+ QTest::newRow("groups changed")
+ << QString("items.setGroups(1, 2, [\"items\", \"selected\"])")
+ << (QStringList()
+ << "verify(vm.inserted, [], [], [])"
+ << "verify(vm.removed, [], [], [])"
+ << "verify(vi.removed, [1], [2], [undefined])"
+ << "verify(vi.inserted, [], [], [])"
+ << "verify(si.removed, [], [], [])"
+ << "verify(si.inserted, [0], [2], [undefined])");
+
+ QTest::newRow("multiple removes")
+ << QString("{ vi.remove(1, 1); "
+ "vi.removeGroups(0, 2, \"items\") }")
+ << (QStringList()
+ << "verify(vm.removed, [0, 1], [1, 1], [undefined, undefined])"
+ << "verify(vm.inserted, [], [], [])"
+ << "verify(vi.removed, [1], [1], [undefined])"
+ << "verify(vi.inserted, [], [], [])"
+ << "verify(si.removed, [], [], [])"
+ << "verify(si.inserted, [], [], [])");
+}
+
+void tst_qquickvisualdatamodel::onChanged()
+{
+ QFETCH(QString, expression);
+ QFETCH(QStringList, tests);
+
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("onChanged.qml")));
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(object);
+
+ evaluate<void>(object.data(), expression);
+
+ foreach (const QString &test, tests) {
+ bool passed = evaluate<bool>(object.data(), test);
+ if (!passed)
+ qWarning() << test;
+ QVERIFY(passed);
+ }
+}
+
void tst_qquickvisualdatamodel::create()
{
QQuickView view;
@@ -1455,8 +1676,20 @@ void tst_qquickvisualdatamodel::create()
QQuickItem *delegate;
+ // persistedItems.includeByDefault is true, so all items belong to persistedItems initially.
+ QVERIFY(delegate = findItem<QQuickItem>(contentItem, "delegate", 1));
+ QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
+
+ // changing include by default doesn't remove persistance.
+ evaluate<void>(visualModel, "persistedItems.includeByDefault = false");
+ QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
+
+ // removing from persistedItems does.
+ evaluate<void>(visualModel, "persistedItems.remove(0, 20)");
+ QCOMPARE(listview->count(), 20);
+ QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
+
// Request an item instantiated by the view.
- QVERIFY(findItem<QQuickItem>(contentItem, "delegate", 1));
QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(1)")));
QCOMPARE(delegate, findItem<QQuickItem>(contentItem, "delegate", 1));
QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
diff --git a/tests/auto/declarative/v4/data/qtbug_21883.qml b/tests/auto/declarative/v4/data/qtbug_21883.qml
new file mode 100644
index 0000000000..a51f97c944
--- /dev/null
+++ b/tests/auto/declarative/v4/data/qtbug_21883.qml
@@ -0,0 +1,5 @@
+import Qt.v4 1.0
+
+Result {
+ property Result dummy: Result
+}
diff --git a/tests/auto/declarative/v4/tst_v4.cpp b/tests/auto/declarative/v4/tst_v4.cpp
index 0b6b2c24f7..20d739f4b5 100644
--- a/tests/auto/declarative/v4/tst_v4.cpp
+++ b/tests/auto/declarative/v4/tst_v4.cpp
@@ -77,6 +77,7 @@ private slots:
void qtscript_data();
void nestedObjectAccess();
void subscriptionsInConditionalExpressions();
+ void qtbug_21883();
private:
QDeclarativeEngine engine;
@@ -239,6 +240,19 @@ void tst_v4::subscriptionsInConditionalExpressions()
delete o;
}
+// Crash test
+void tst_v4::qtbug_21883()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("qtbug_21883.qml"));
+
+ QString warning = component.url().toString() + ":4: Unable to assign null to ResultObject*";
+ QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData());
+
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+ delete o;
+}
+
QTEST_MAIN(tst_v4)
#include "tst_v4.moc"
diff --git a/tests/auto/headersclean/tst_headersclean.cpp b/tests/auto/headersclean/tst_headersclean.cpp
index 60bb799076..9aa7f1d693 100644
--- a/tests/auto/headersclean/tst_headersclean.cpp
+++ b/tests/auto/headersclean/tst_headersclean.cpp
@@ -49,6 +49,7 @@
#include <QtCore/QtCore>
#include <QtTest/QtTest>
+#include <QtDeclarative/QtDeclarative>
class tst_HeadersClean: public QObject
{
diff --git a/tests/auto/particles/qquickage/tst_qquickage.cpp b/tests/auto/particles/qquickage/tst_qquickage.cpp
index 73db409de3..b787a73ef7 100644
--- a/tests/auto/particles/qquickage/tst_qquickage.cpp
+++ b/tests/auto/particles/qquickage/tst_qquickage.cpp
@@ -68,7 +68,7 @@ void tst_qquickage::test_kill()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -84,6 +84,7 @@ void tst_qquickage::test_kill()
QCOMPARE(d->endSize, 32.f);
QVERIFY(d->t <= ((qreal)system->timeInt/1000.0) - 0.5f + EPSILON);
}
+ delete view;
}
void tst_qquickage::test_jump()
@@ -92,14 +93,14 @@ void tst_qquickage::test_jump()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
- //Allow for a small variance because jump is trying to simulate off wall time
- extremelyFuzzyCompare(d->x, -100.f, 5.0f);
- extremelyFuzzyCompare(d->y, -100.f, 5.0f);
+ //Allow for variance because jump is trying to simulate off wall time and things have emitted 'continuously' before first affect
+ QVERIFY(d->x <= -50.f);
+ QVERIFY(d->y <= -50.f);
QCOMPARE(d->vx, 500.f);
QCOMPARE(d->vy, 500.f);
QCOMPARE(d->ax, 0.f);
@@ -109,6 +110,7 @@ void tst_qquickage::test_jump()
QCOMPARE(d->endSize, 32.f);
QVERIFY(d->t <= ((qreal)system->timeInt/1000.0) - 0.4f + EPSILON);
}
+ delete view;
}
void tst_qquickage::test_onceOff()
@@ -117,7 +119,7 @@ void tst_qquickage::test_onceOff()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -133,6 +135,7 @@ void tst_qquickage::test_onceOff()
QCOMPARE(d->endSize, 32.f);
QVERIFY(d->t <= ((qreal)system->timeInt/1000.0) - 0.4f + EPSILON);
}
+ delete view;
}
void tst_qquickage::test_sustained()
@@ -142,7 +145,7 @@ void tst_qquickage::test_sustained()
ensureAnimTime(600, system->m_animation);
//TODO: Ensure some particles have lived to 0.4s point despite unified timer
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -158,6 +161,7 @@ void tst_qquickage::test_sustained()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyCompare(d->t, ((qreal)system->timeInt/1000.0) - 0.4f));
}
+ delete view;
}
QTEST_MAIN(tst_qquickage);
diff --git a/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp b/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp
index d21753e8a0..4e3fda3d03 100644
--- a/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp
+++ b/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp
@@ -66,7 +66,7 @@ void tst_qquickangleddirection::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -85,6 +85,7 @@ void tst_qquickangleddirection::test_basic()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquickangleddirection);
diff --git a/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp b/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp
index 052578f3a8..22c2d5efa0 100644
--- a/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp
+++ b/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp
@@ -65,7 +65,7 @@ void tst_qquickcumulativedirection::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -81,6 +81,7 @@ void tst_qquickcumulativedirection::test_basic()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquickcumulativedirection);
diff --git a/tests/auto/particles/qquickcustomaffector/data/basic.qml b/tests/auto/particles/qquickcustomaffector/data/basic.qml
index 7371698026..253c566c66 100644
--- a/tests/auto/particles/qquickcustomaffector/data/basic.qml
+++ b/tests/auto/particles/qquickcustomaffector/data/basic.qml
@@ -54,6 +54,7 @@ Rectangle {
ImageParticle {
source: "../../shared/star.png"
+ rotation: 90
}
Emitter{
@@ -75,6 +76,12 @@ Rectangle {
particles[i].initialAY = 100;
particles[i].startSize = 100;
particles[i].endSize = 100;
+ particles[i].autoRotate = true;
+ particles[i].update = true;
+ particles[i].red = 0;
+ particles[i].green = 1.0;
+ particles[i].blue = 0;
+ particles[i].alpha = 0;
}
}
}
diff --git a/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp b/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp
index 77b1d09763..c33895e9ad 100644
--- a/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp
+++ b/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp
@@ -66,10 +66,13 @@ void tst_qquickcustomaffector::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
+ //in CI the whole simulation often happens at once, so dead particles end up missing out
+ if (!d->stillAlive())
+ continue; //parameters no longer get set once you die
QCOMPARE(d->x, 100.f);
QCOMPARE(d->y, 100.f);
@@ -80,8 +83,14 @@ void tst_qquickcustomaffector::test_basic()
QCOMPARE(d->lifeSpan, 0.5f);
QCOMPARE(d->size, 100.f);
QCOMPARE(d->endSize, 100.f);
+ QCOMPARE(d->autoRotate, 1.f);
+ QCOMPARE(d->color.r, (uchar)0);
+ QCOMPARE(d->color.g, (uchar)255);
+ QCOMPARE(d->color.b, (uchar)0);
+ QCOMPARE(d->color.a, (uchar)0);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
void tst_qquickcustomaffector::test_move()
@@ -90,7 +99,7 @@ void tst_qquickcustomaffector::test_move()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -108,6 +117,7 @@ void tst_qquickcustomaffector::test_move()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquickcustomaffector);
diff --git a/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp b/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp
index 3c73fad3f3..60977b2f49 100644
--- a/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp
+++ b/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp
@@ -67,7 +67,7 @@ void tst_qquickcustomparticle::test_basic()
ensureAnimTime(600, system->m_animation);
bool oneNonZero = false;
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -86,6 +86,7 @@ void tst_qquickcustomparticle::test_basic()
if (d->r != 0.0 )
oneNonZero = true;
}
+ delete view;
QVERIFY(oneNonZero);//Zero is a valid value, but it also needs to be set to a random number
}
diff --git a/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp b/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp
index 7f412c8521..683eb49ed7 100644
--- a/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp
+++ b/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp
@@ -82,7 +82,7 @@ void tst_qquickellipseextruder::test_basic()
ensureAnimTime(600, system->m_animation);
//Filled
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -97,6 +97,7 @@ void tst_qquickellipseextruder::test_basic()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+
//Just border
QCOMPARE(system->groupData[1]->size(), 500);
foreach (QQuickParticleData *d, system->groupData[1]->data) {
@@ -113,6 +114,7 @@ void tst_qquickellipseextruder::test_basic()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquickellipseextruder);
diff --git a/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp b/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp
index aca4ea2330..bea3e18d27 100644
--- a/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp
+++ b/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp
@@ -67,7 +67,7 @@ void tst_qquickfriction::test_basic()
ensureAnimTime(600, system->m_animation);
//Default is just slowed a little
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -101,6 +101,7 @@ void tst_qquickfriction::test_basic()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
void tst_qquickfriction::test_threshold()
@@ -110,7 +111,7 @@ void tst_qquickfriction::test_threshold()
ensureAnimTime(600, system->m_animation);
//Speed capped at 50, but it might take a frame or two to get there
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1.0f)
continue; //Particle data unused
@@ -127,6 +128,7 @@ void tst_qquickfriction::test_threshold()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquickfriction);
diff --git a/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp b/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp
index 5613591171..bc8cca8522 100644
--- a/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp
+++ b/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp
@@ -65,18 +65,21 @@ void tst_qquickgravity::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
+ float mag = 707.10678f;
foreach (QQuickParticleData *d, system->groupData[0]->data) {
- if (d->t == -1)
- continue; //Particle data unused
+ if (d->t == -1 || !d->stillAlive())
+ continue; //Particle data unused or dead
- QCOMPARE(d->ax, 707.10678f);
- QCOMPARE(d->ay, 707.10678f);
+ float t = ((qreal)system->timeInt/1000.0) - d->t;
+ QVERIFY(extremelyFuzzyCompare(d->vx, t*mag, 20.0f));
+ QVERIFY(extremelyFuzzyCompare(d->vy, t*mag, 20.0f));
QCOMPARE(d->lifeSpan, 0.5f);
QCOMPARE(d->size, 32.f);
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquickgravity);
diff --git a/tests/auto/particles/qquickgroupgoal/data/basic.qml b/tests/auto/particles/qquickgroupgoal/data/basic.qml
new file mode 100644
index 0000000000..4b27cd4ac9
--- /dev/null
+++ b/tests/auto/particles/qquickgroupgoal/data/basic.qml
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ GroupGoal {
+ groups: ["notdefault"]
+ goalState: ""
+ jump: true
+ }
+
+ Emitter {
+ //0,0 position
+ group: "notdefault"
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro b/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro
new file mode 100644
index 0000000000..8e7d5ae021
--- /dev/null
+++ b/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qquickgroupgoal
+SOURCES += tst_qquickgroupgoal.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp b/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp
new file mode 100644
index 0000000000..92f30d903f
--- /dev/null
+++ b/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qquickparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qquickgroupgoal : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qquickgroupgoal();
+
+private slots:
+ void test_instantTransition();
+};
+
+tst_qquickgroupgoal::tst_qquickgroupgoal()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qquickgroupgoal::test_instantTransition()
+{
+ //Note: Does not go through sprite engine
+ QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QVERIFY(system->groupData[0]->size() <= 500 && system->groupData[0]->size() >= 450);
+ foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+ delete view;
+}
+
+QTEST_MAIN(tst_qquickgroupgoal);
+
+#include "tst_qquickgroupgoal.moc"
diff --git a/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro b/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro
index c05ecdfb09..14d28fd43d 100644
--- a/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro
+++ b/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro
@@ -8,4 +8,3 @@ testDataFiles.path = .
DEPLOYMENT += testDataFiles
QT += core-private gui-private v8-private declarative-private opengl-private testlib
-
diff --git a/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp b/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp
index e56de35137..27b386dcd5 100644
--- a/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp
+++ b/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp
@@ -71,7 +71,7 @@ void tst_qquickimageparticle::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -105,6 +105,7 @@ void tst_qquickimageparticle::test_basic()
QCOMPARE(d->frameCount, 1.0f);
QCOMPARE(d->animT, -1.0f);
}
+ delete view;
}
@@ -114,7 +115,7 @@ void tst_qquickimageparticle::test_colored()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -148,6 +149,7 @@ void tst_qquickimageparticle::test_colored()
QCOMPARE(d->frameCount, 1.0f);
QCOMPARE(d->animT, -1.0f);
}
+ delete view;
}
@@ -157,7 +159,7 @@ void tst_qquickimageparticle::test_deformed()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -191,6 +193,7 @@ void tst_qquickimageparticle::test_deformed()
QCOMPARE(d->frameCount, 1.0f);
QCOMPARE(d->animT, -1.0f);
}
+ delete view;
}
@@ -200,7 +203,7 @@ void tst_qquickimageparticle::test_tabled()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -235,6 +238,7 @@ void tst_qquickimageparticle::test_tabled()
QCOMPARE(d->animT, -1.0f);
//TODO: This performance level doesn't alter particleData, but goes straight to shaders. Find something to test
}
+ delete view;
}
@@ -244,7 +248,7 @@ void tst_qquickimageparticle::test_sprite()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -278,6 +282,7 @@ void tst_qquickimageparticle::test_sprite()
QCOMPARE(d->animWidth, 31.0f);
QCOMPARE(d->animHeight, 30.0f);
}
+ delete view;
}
QTEST_MAIN(tst_qquickimageparticle);
diff --git a/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro b/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro
index dc006d2ba1..8e8eadd463 100644
--- a/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro
+++ b/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro
@@ -7,5 +7,7 @@ testDataFiles.files = data
testDataFiles.path = .
DEPLOYMENT += testDataFiles
+CONFIG += insignificant_test #temporary
+
QT += core-private gui-private v8-private declarative-private opengl-private testlib
diff --git a/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp b/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp
index 40197ec619..6cfb6c5562 100644
--- a/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp
+++ b/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp
@@ -66,7 +66,7 @@ void tst_qquickitemparticle::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -88,6 +88,7 @@ void tst_qquickitemparticle::test_basic()
QVERIFY(d->delegate);
QVERIFY(qobject_cast<QQuickImage*>(d->delegate));
}
+ delete view;
}
QTEST_MAIN(tst_qquickitemparticle);
diff --git a/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp b/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp
index ff45a9e92c..69d87acf44 100644
--- a/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp
+++ b/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp
@@ -65,7 +65,7 @@ void tst_qquicklineextruder::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -96,6 +96,7 @@ void tst_qquicklineextruder::test_basic()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquicklineextruder);
diff --git a/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp b/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp
index b2a178fa1c..c13a776586 100644
--- a/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp
+++ b/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp
@@ -65,7 +65,7 @@ void tst_qquickmaskextruder::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -81,6 +81,7 @@ void tst_qquickmaskextruder::test_basic()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquickmaskextruder);
diff --git a/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp b/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp
index c3b155aa68..2548d879d0 100644
--- a/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp
+++ b/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp
@@ -82,6 +82,7 @@ void tst_qquickparticlegroup::test_instantTransition()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquickparticlegroup);
diff --git a/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp b/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp
index b85c57da0b..f9bb971a82 100644
--- a/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp
+++ b/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp
@@ -65,7 +65,7 @@ void tst_qquickparticlesystem::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
int stillAlive = 0;
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
@@ -84,6 +84,7 @@ void tst_qquickparticlesystem::test_basic()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
QVERIFY(extremelyFuzzyCompare(stillAlive, 500, 5));//Small simulation variance is permissible.
}
diff --git a/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp b/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp
index 6a64f919c0..e6b1b6e1c8 100644
--- a/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp
+++ b/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp
@@ -65,7 +65,7 @@ void tst_qquickpointattractor::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -82,6 +82,7 @@ void tst_qquickpointattractor::test_basic()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquickpointattractor);
diff --git a/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp b/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp
index 19cc471126..b554ba7226 100644
--- a/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp
+++ b/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp
@@ -65,7 +65,7 @@ void tst_qquickpointdirection::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -83,6 +83,7 @@ void tst_qquickpointdirection::test_basic()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquickpointdirection);
diff --git a/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp b/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp
index 6fb2e9cae8..d8c17efdaf 100644
--- a/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp
+++ b/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp
@@ -65,7 +65,7 @@ void tst_qquickrectangleextruder::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -106,6 +106,7 @@ void tst_qquickrectangleextruder::test_basic()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquickrectangleextruder);
diff --git a/tests/auto/particles/qquickspritegoal/data/basic.qml b/tests/auto/particles/qquickspritegoal/data/basic.qml
new file mode 100644
index 0000000000..4c172ef28d
--- /dev/null
+++ b/tests/auto/particles/qquickspritegoal/data/basic.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ sprites: [Sprite {
+ name: "happy"
+ source: "../../shared/squarefacesprite.png"
+ frames: 6
+ duration: 120
+ }, Sprite {
+ name: "twoHappy"
+ source: "../../shared/squarefacesprite.png"
+ frames: 3
+ duration: 240
+ }]
+ }
+
+ SpriteGoal {
+ goalState: "twoHappy"
+ jump: true
+ }
+
+ Emitter {
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro b/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro
new file mode 100644
index 0000000000..d335a91537
--- /dev/null
+++ b/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qquickspritegoal
+SOURCES += tst_qquickspritegoal.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp b/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp
new file mode 100644
index 0000000000..9bb19d207a
--- /dev/null
+++ b/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qquickparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qquickspritegoal : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qquickspritegoal();
+
+private slots:
+ void test_instantTransition();
+};
+
+tst_qquickspritegoal::tst_qquickspritegoal()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qquickspritegoal::test_instantTransition()
+{
+ QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QVERIFY(system->groupData[0]->size() <= 500 && system->groupData[0]->size() >= 450);
+ foreach (QQuickParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->animIdx, 1.f);//Spawns at 0, affector moves it.
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+ delete view;
+}
+
+QTEST_MAIN(tst_qquickspritegoal);
+
+#include "tst_qquickspritegoal.moc"
diff --git a/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp b/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp
index 7d83ae8830..789334e175 100644
--- a/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp
+++ b/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp
@@ -65,7 +65,7 @@ void tst_qquicktargetdirection::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -81,6 +81,7 @@ void tst_qquicktargetdirection::test_basic()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquicktargetdirection);
diff --git a/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp b/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp
index 6325ca6efe..89463b6362 100644
--- a/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp
+++ b/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp
@@ -65,7 +65,7 @@ void tst_qquicktrailemitter::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -98,6 +98,7 @@ void tst_qquicktrailemitter::test_basic()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquicktrailemitter);
diff --git a/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp b/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp
index 29faec2381..9f4d50c45e 100644
--- a/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp
+++ b/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp
@@ -67,7 +67,7 @@ void tst_qquickturbulence::test_basic()
//Note that the noise image built-in provides the 'randomness', so this test should be stable so long as it and the size
//of the Turbulence item remain the same
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[0]->data) {
if (d->t == -1)
continue; //Particle data unused
@@ -79,6 +79,7 @@ void tst_qquickturbulence::test_basic()
QCOMPARE(d->endSize, 32.f);
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
+ delete view;
}
QTEST_MAIN(tst_qquickturbulence);
diff --git a/tests/auto/particles/qquickwander/tst_qquickwander.cpp b/tests/auto/particles/qquickwander/tst_qquickwander.cpp
index 41f09d4993..ac88b582c4 100644
--- a/tests/auto/particles/qquickwander/tst_qquickwander.cpp
+++ b/tests/auto/particles/qquickwander/tst_qquickwander.cpp
@@ -65,7 +65,7 @@ void tst_qquickwander::test_basic()
QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
ensureAnimTime(600, system->m_animation);
- QCOMPARE(system->groupData[0]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10));
//Since Wander is random perturbations, the compromise between stability and actual testing is to hope that one of
//the 500 was randomly changed from 0.0 in velocity
bool vxChanged = false;
@@ -85,6 +85,7 @@ void tst_qquickwander::test_basic()
if (d->vy != 0.0f)
vyChanged = true;
}
+ delete view;
QVERIFY(vxChanged);
QVERIFY(vyChanged);
}
diff --git a/tests/auto/qtquick1/examples/examples.pro b/tests/auto/qtquick1/examples/examples.pro
index ca4ad04e47..3086ea1413 100644
--- a/tests/auto/qtquick1/examples/examples.pro
+++ b/tests/auto/qtquick1/examples/examples.pro
@@ -11,4 +11,4 @@ CONFIG += parallel_test
QT += core-private gui-private widgets-private declarative-private qtquick1-private testlib
-qpa:CONFIG+=insignificant_test # QTBUG-20990, aborts
+CONFIG+=insignificant_test # QTBUG-20990, aborts
diff --git a/tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro b/tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro
index 3b0fd671e1..eefb4d5902 100644
--- a/tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro
+++ b/tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro
@@ -9,4 +9,4 @@ DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
-qpa:contains(QT_CONFIG,xcb):CONFIG+=insignificant_test # QTBUG-21012 fails on exit (X11-specific)
+contains(QT_CONFIG,xcb):CONFIG+=insignificant_test # QTBUG-21012 fails on exit (X11-specific)
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/qdeclarativefocusscope.pro b/tests/auto/qtquick1/qdeclarativefocusscope/qdeclarativefocusscope.pro
index a42997dc08..67bd8ae6d4 100644
--- a/tests/auto/qtquick1/qdeclarativefocusscope/qdeclarativefocusscope.pro
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/qdeclarativefocusscope.pro
@@ -6,4 +6,4 @@ macx:CONFIG -= app_bundle
DEFINES += SRCDIR=\\\"$$PWD\\\"
QT += core-private gui-private widgets-private declarative-private qtquick1-private testlib
-qpa:CONFIG+=insignificant_test # QTBUG-21013 unstable
+CONFIG+=insignificant_test # QTBUG-21013 unstable
diff --git a/tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro b/tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro
index 31a71a5ab8..8663c69ea4 100644
--- a/tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro
+++ b/tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro
@@ -9,4 +9,4 @@ DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
-qpa:contains(QT_CONFIG,xcb):CONFIG+=insignificant_test # QTBUG-21012 fails on exit (X11-specific)
+contains(QT_CONFIG,xcb):CONFIG+=insignificant_test # QTBUG-21012 fails on exit (X11-specific)
diff --git a/tests/auto/qtquick1/qdeclarativestates/data/signalOverrideCrash3.qml b/tests/auto/qtquick1/qdeclarativestates/data/signalOverrideCrash3.qml
new file mode 100644
index 0000000000..ed1f22f39a
--- /dev/null
+++ b/tests/auto/qtquick1/qdeclarativestates/data/signalOverrideCrash3.qml
@@ -0,0 +1,27 @@
+import QtQuick 1.0
+
+Rectangle {
+ id: myRect
+ width: 400
+ height: 400
+
+ onHeightChanged: console.log("base state")
+
+ states: [
+ State {
+ name: "state1"
+ PropertyChanges {
+ target: myRect
+ onHeightChanged: console.log("state1")
+ color: "green"
+ }
+ },
+ State {
+ name: "state2";
+ PropertyChanges {
+ target: myRect
+ onHeightChanged: console.log("state2")
+ color: "red"
+ }
+ }]
+}
diff --git a/tests/auto/qtquick1/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/qtquick1/qdeclarativestates/tst_qdeclarativestates.cpp
index 809d9ca65c..ba4177e7ff 100644
--- a/tests/auto/qtquick1/qdeclarativestates/tst_qdeclarativestates.cpp
+++ b/tests/auto/qtquick1/qdeclarativestates/tst_qdeclarativestates.cpp
@@ -108,6 +108,7 @@ private slots:
void signalOverride();
void signalOverrideCrash();
void signalOverrideCrash2();
+ void signalOverrideCrash3();
void parentChange();
void parentChangeErrors();
void anchorChanges();
@@ -515,6 +516,22 @@ void tst_qdeclarativestates::signalOverrideCrash2()
delete rect;
}
+void tst_qdeclarativestates::signalOverrideCrash3()
+{
+ QDeclarativeEngine engine;
+
+ QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverrideCrash3.qml");
+ QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(rectComponent.create());
+ QVERIFY(rect != 0);
+
+ QDeclarativeItemPrivate::get(rect)->setState("state1");
+ QDeclarativeItemPrivate::get(rect)->setState("");
+ QDeclarativeItemPrivate::get(rect)->setState("state2");
+ QDeclarativeItemPrivate::get(rect)->setState("");
+
+ delete rect;
+}
+
void tst_qdeclarativestates::parentChange()
{
QDeclarativeEngine engine;
diff --git a/tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
index 58027bf760..f6af1297bb 100644
--- a/tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
+++ b/tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
@@ -1630,10 +1630,8 @@ void tst_qdeclarativetextedit::positionAt()
int pos = texteditObject->positionAt(texteditObject->width()/2, y0);
int diff = abs(int(fm.width(texteditObject->text().left(pos))-texteditObject->width()/2));
-#ifdef Q_WS_QPA
QEXPECT_FAIL("", "QTBUG-21016 fails", Continue);
-#endif
- // some tollerance for different fonts.
+ // some tolerance for different fonts.
#ifdef Q_OS_LINUX
QVERIFY(diff < 2);
#else